]> git.donarmstrong.com Git - roundcube.git/blob - program/js/tiny_mce/tiny_mce_src.js
Merge commit 'upstream/0.2_stable' into unstable-import
[roundcube.git] / program / js / tiny_mce / tiny_mce_src.js
1 \r
2 /* file:jscripts/tiny_mce/classes/tinymce.js */\r
3 \r
4 var tinymce = {\r
5         majorVersion : '3',\r
6         minorVersion : '1.0.1',\r
7         releaseDate : '2008-06-18',\r
8 \r
9         _init : function() {\r
10                 var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;\r
11 \r
12                 // Browser checks\r
13                 t.isOpera = w.opera && opera.buildNumber;\r
14                 t.isWebKit = /WebKit/.test(ua);\r
15                 t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt;\r
16                 t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);\r
17                 t.isIE6 = t.isIE && /MSIE [56]/.test(ua);\r
18                 t.isGecko = !t.isWebKit && /Gecko/.test(ua);\r
19                 t.isMac = ua.indexOf('Mac') != -1;\r
20 \r
21                 // TinyMCE .NET webcontrol might be setting the values for TinyMCE\r
22                 if (w.tinyMCEPreInit) {\r
23                         t.suffix = tinyMCEPreInit.suffix;\r
24                         t.baseURL = tinyMCEPreInit.base;\r
25                         t.query = tinyMCEPreInit.query;\r
26                         return;\r
27                 }\r
28 \r
29                 // Get suffix and base\r
30                 t.suffix = '';\r
31 \r
32                 // If base element found, add that infront of baseURL\r
33                 nl = d.getElementsByTagName('base');\r
34                 for (i=0; i<nl.length; i++) {\r
35                         if (v = nl[i].href) {\r
36                                 // Host only value like http://site.com or http://site.com:8008\r
37                                 if (/^https?:\/\/[^\/]+$/.test(v))\r
38                                         v += '/';\r
39 \r
40                                 base = v ? v.match(/.*\//)[0] : ''; // Get only directory\r
41                         }\r
42                 }\r
43 \r
44                 function getBase(n) {\r
45                         if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) {\r
46                                 if (/_(src|dev)\.js/g.test(n.src))\r
47                                         t.suffix = '_src';\r
48 \r
49                                 if ((p = n.src.indexOf('?')) != -1)\r
50                                         t.query = n.src.substring(p + 1);\r
51 \r
52                                 t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));\r
53 \r
54                                 // If path to script is relative and a base href was found add that one infront\r
55                                 if (base && t.baseURL.indexOf('://') == -1)\r
56                                         t.baseURL = base + t.baseURL;\r
57 \r
58                                 return t.baseURL;\r
59                         }\r
60 \r
61                         return null;\r
62                 };\r
63 \r
64                 // Check document\r
65                 nl = d.getElementsByTagName('script');\r
66                 for (i=0; i<nl.length; i++) {\r
67                         if (getBase(nl[i]))\r
68                                 return;\r
69                 }\r
70 \r
71                 // Check head\r
72                 n = d.getElementsByTagName('head')[0];\r
73                 if (n) {\r
74                         nl = n.getElementsByTagName('script');\r
75                         for (i=0; i<nl.length; i++) {\r
76                                 if (getBase(nl[i]))\r
77                                         return;\r
78                         }\r
79                 }\r
80 \r
81                 return;\r
82         },\r
83 \r
84         is : function(o, t) {\r
85                 var n = typeof(o);\r
86 \r
87                 if (!t)\r
88                         return n != 'undefined';\r
89 \r
90                 if (t == 'array' && (o instanceof Array))\r
91                         return true;\r
92 \r
93                 return n == t;\r
94         },\r
95 \r
96         // #if !jquery\r
97 \r
98         each : function(o, cb, s) {\r
99                 var n, l;\r
100 \r
101                 if (!o)\r
102                         return 0;\r
103 \r
104                 s = s || o;\r
105 \r
106                 if (typeof(o.length) != 'undefined') {\r
107                         // Indexed arrays, needed for Safari\r
108                         for (n=0, l = o.length; n<l; n++) {\r
109                                 if (cb.call(s, o[n], n, o) === false)\r
110                                         return 0;\r
111                         }\r
112                 } else {\r
113                         // Hashtables\r
114                         for (n in o) {\r
115                                 if (o.hasOwnProperty(n)) {\r
116                                         if (cb.call(s, o[n], n, o) === false)\r
117                                                 return 0;\r
118                                 }\r
119                         }\r
120                 }\r
121 \r
122                 return 1;\r
123         },\r
124 \r
125         map : function(a, f) {\r
126                 var o = [];\r
127 \r
128                 tinymce.each(a, function(v) {\r
129                         o.push(f(v));\r
130                 });\r
131 \r
132                 return o;\r
133         },\r
134 \r
135         grep : function(a, f) {\r
136                 var o = [];\r
137 \r
138                 tinymce.each(a, function(v) {\r
139                         if (!f || f(v))\r
140                                 o.push(v);\r
141                 });\r
142 \r
143                 return o;\r
144         },\r
145 \r
146         inArray : function(a, v) {\r
147                 var i, l;\r
148 \r
149                 if (a) {\r
150                         for (i = 0, l = a.length; i < l; i++) {\r
151                                 if (a[i] === v)\r
152                                         return i;\r
153                         }\r
154                 }\r
155 \r
156                 return -1;\r
157         },\r
158 \r
159         extend : function(o, e) {\r
160                 var i, a = arguments;\r
161 \r
162                 for (i=1; i<a.length; i++) {\r
163                         e = a[i];\r
164 \r
165                         tinymce.each(e, function(v, n) {\r
166                                 if (typeof(v) !== 'undefined')\r
167                                         o[n] = v;\r
168                         });\r
169                 }\r
170 \r
171                 return o;\r
172         },\r
173 \r
174         trim : function(s) {\r
175                 return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');\r
176         },\r
177 \r
178         // #endif\r
179 \r
180         create : function(s, p) {\r
181                 var t = this, sp, ns, cn, scn, c, de = 0;\r
182 \r
183                 // Parse : <prefix> <class>:<super class>\r
184                 s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);\r
185                 cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name\r
186 \r
187                 // Create namespace for new class\r
188                 ns = t.createNS(s[3].replace(/\.\w+$/, ''));\r
189 \r
190                 // Class already exists\r
191                 if (ns[cn])\r
192                         return;\r
193 \r
194                 // Make pure static class\r
195                 if (s[2] == 'static') {\r
196                         ns[cn] = p;\r
197 \r
198                         if (this.onCreate)\r
199                                 this.onCreate(s[2], s[3], ns[cn]);\r
200 \r
201                         return;\r
202                 }\r
203 \r
204                 // Create default constructor\r
205                 if (!p[cn]) {\r
206                         p[cn] = function() {};\r
207                         de = 1;\r
208                 }\r
209 \r
210                 // Add constructor and methods\r
211                 ns[cn] = p[cn];\r
212                 t.extend(ns[cn].prototype, p);\r
213 \r
214                 // Extend\r
215                 if (s[5]) {\r
216                         sp = t.resolve(s[5]).prototype;\r
217                         scn = s[5].match(/\.(\w+)$/i)[1]; // Class name\r
218 \r
219                         // Extend constructor\r
220                         c = ns[cn];\r
221                         if (de) {\r
222                                 // Add passthrough constructor\r
223                                 ns[cn] = function() {\r
224                                         return sp[scn].apply(this, arguments);\r
225                                 };\r
226                         } else {\r
227                                 // Add inherit constructor\r
228                                 ns[cn] = function() {\r
229                                         this.parent = sp[scn];\r
230                                         return c.apply(this, arguments);\r
231                                 };\r
232                         }\r
233                         ns[cn].prototype[cn] = ns[cn];\r
234 \r
235                         // Add super methods\r
236                         t.each(sp, function(f, n) {\r
237                                 ns[cn].prototype[n] = sp[n];\r
238                         });\r
239 \r
240                         // Add overridden methods\r
241                         t.each(p, function(f, n) {\r
242                                 // Extend methods if needed\r
243                                 if (sp[n]) {\r
244                                         ns[cn].prototype[n] = function() {\r
245                                                 this.parent = sp[n];\r
246                                                 return f.apply(this, arguments);\r
247                                         };\r
248                                 } else {\r
249                                         if (n != cn)\r
250                                                 ns[cn].prototype[n] = f;\r
251                                 }\r
252                         });\r
253                 }\r
254 \r
255                 // Add static methods\r
256                 t.each(p['static'], function(f, n) {\r
257                         ns[cn][n] = f;\r
258                 });\r
259 \r
260                 if (this.onCreate)\r
261                         this.onCreate(s[2], s[3], ns[cn].prototype);\r
262         },\r
263 \r
264         walk : function(o, f, n, s) {\r
265                 s = s || this;\r
266 \r
267                 if (o) {\r
268                         if (n)\r
269                                 o = o[n];\r
270 \r
271                         tinymce.each(o, function(o, i) {\r
272                                 if (f.call(s, o, i, n) === false)\r
273                                         return false;\r
274 \r
275                                 tinymce.walk(o, f, n, s);\r
276                         });\r
277                 }\r
278         },\r
279 \r
280         createNS : function(n, o) {\r
281                 var i, v;\r
282 \r
283                 o = o || window;\r
284 \r
285                 n = n.split('.');\r
286                 for (i=0; i<n.length; i++) {\r
287                         v = n[i];\r
288 \r
289                         if (!o[v])\r
290                                 o[v] = {};\r
291 \r
292                         o = o[v];\r
293                 }\r
294 \r
295                 return o;\r
296         },\r
297 \r
298         resolve : function(n, o) {\r
299                 var i, l;\r
300 \r
301                 o = o || window;\r
302 \r
303                 n = n.split('.');\r
304                 for (i=0, l = n.length; i<l; i++) {\r
305                         o = o[n[i]];\r
306 \r
307                         if (!o)\r
308                                 break;\r
309                 }\r
310 \r
311                 return o;\r
312         },\r
313 \r
314         addUnload : function(f, s) {\r
315                 var t = this, w = window;\r
316 \r
317                 f = {func : f, scope : s || this};\r
318 \r
319                 if (!t.unloads) {\r
320                         function unload() {\r
321                                 var li = t.unloads, o, n;\r
322 \r
323                                 if (li) {\r
324                                         // Call unload handlers\r
325                                         for (n in li) {\r
326                                                 o = li[n];\r
327 \r
328                                                 if (o && o.func)\r
329                                                         o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy\r
330                                         }\r
331 \r
332                                         // Detach unload function\r
333                                         if (w.detachEvent) {\r
334                                                 w.detachEvent('onbeforeunload', fakeUnload);\r
335                                                 w.detachEvent('onunload', unload);\r
336                                         } else if (w.removeEventListener)\r
337                                                 w.removeEventListener('unload', unload, false);\r
338 \r
339                                         // Destroy references\r
340                                         t.unloads = o = li = w = unload = null;\r
341 \r
342                                         // Run garbarge collector on IE\r
343                                         if (window.CollectGarbage)\r
344                                                 window.CollectGarbage();\r
345                                 }\r
346                         };\r
347 \r
348                         function fakeUnload() {\r
349                                 var d = document;\r
350 \r
351                                 // Is there things still loading, then do some magic\r
352                                 if (d.readyState == 'interactive') {\r
353                                         function stop() {\r
354                                                 // Prevent memory leak\r
355                                                 d.detachEvent('onstop', stop);\r
356 \r
357                                                 // Call unload handler\r
358                                                 unload();\r
359 \r
360                                                 d = null;\r
361                                         };\r
362 \r
363                                         // Fire unload when the currently loading page is stopped\r
364                                         d.attachEvent('onstop', stop);\r
365 \r
366                                         // Remove onstop listener after a while to prevent the unload function\r
367                                         // to execute if the user presses cancel in an onbeforeunload\r
368                                         // confirm dialog and then presses the browser stop button\r
369                                         window.setTimeout(function() {\r
370                                                 d.detachEvent('onstop', stop);\r
371                                         }, 0);\r
372                                 }\r
373                         };\r
374 \r
375                         // Attach unload handler\r
376                         if (w.attachEvent) {\r
377                                 w.attachEvent('onunload', unload);\r
378                                 w.attachEvent('onbeforeunload', fakeUnload);\r
379                         } else if (w.addEventListener)\r
380                                 w.addEventListener('unload', unload, false);\r
381 \r
382                         // Setup initial unload handler array\r
383                         t.unloads = [f];\r
384                 } else\r
385                         t.unloads.push(f);\r
386 \r
387                 return f;\r
388         },\r
389 \r
390         removeUnload : function(f) {\r
391                 var u = this.unloads, r = null;\r
392 \r
393                 tinymce.each(u, function(o, i) {\r
394                         if (o && o.func == f) {\r
395                                 u.splice(i, 1);\r
396                                 r = f;\r
397                                 return false;\r
398                         }\r
399                 });\r
400 \r
401                 return r;\r
402         },\r
403 \r
404         explode : function(s, d) {\r
405                 return s ? tinymce.map(s.split(d || ','), tinymce.trim) : s;\r
406         },\r
407 \r
408         _addVer : function(u) {\r
409                 var v;\r
410 \r
411                 if (!this.query)\r
412                         return u;\r
413 \r
414                 v = (u.indexOf('?') == -1 ? '?' : '&') + this.query;\r
415 \r
416                 if (u.indexOf('#') == -1)\r
417                         return u + v;\r
418 \r
419                 return u.replace('#', v + '#');\r
420         }\r
421 \r
422         };\r
423 \r
424 // Required for GZip AJAX loading\r
425 window.tinymce = tinymce;\r
426 \r
427 // Initialize the API\r
428 tinymce._init();\r
429 \r
430 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */\r
431 \r
432 \r
433 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */\r
434 \r
435 \r
436 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */\r
437 \r
438 tinymce.create('tinymce.util.Dispatcher', {\r
439         scope : null,\r
440         listeners : null,\r
441 \r
442         Dispatcher : function(s) {\r
443                 this.scope = s || this;\r
444                 this.listeners = [];\r
445         },\r
446 \r
447         add : function(cb, s) {\r
448                 this.listeners.push({cb : cb, scope : s || this.scope});\r
449 \r
450                 return cb;\r
451         },\r
452 \r
453         addToTop : function(cb, s) {\r
454                 this.listeners.unshift({cb : cb, scope : s || this.scope});\r
455 \r
456                 return cb;\r
457         },\r
458 \r
459         remove : function(cb) {\r
460                 var l = this.listeners, o = null;\r
461 \r
462                 tinymce.each(l, function(c, i) {\r
463                         if (cb == c.cb) {\r
464                                 o = cb;\r
465                                 l.splice(i, 1);\r
466                                 return false;\r
467                         }\r
468                 });\r
469 \r
470                 return o;\r
471         },\r
472 \r
473         dispatch : function() {\r
474                 var s, a = arguments, i, li = this.listeners, c;\r
475 \r
476                 // Needs to be a real loop since the listener count might change while looping\r
477                 // And this is also more efficient\r
478                 for (i = 0; i<li.length; i++) {\r
479                         c = li[i];\r
480                         s = c.cb.apply(c.scope, a);\r
481 \r
482                         if (s === false)\r
483                                 break;\r
484                 }\r
485 \r
486                 return s;\r
487         }\r
488 \r
489         });\r
490 \r
491 /* file:jscripts/tiny_mce/classes/util/URI.js */\r
492 \r
493 (function() {\r
494         var each = tinymce.each;\r
495 \r
496         tinymce.create('tinymce.util.URI', {\r
497                 URI : function(u, s) {\r
498                         var t = this, o, a, b;\r
499 \r
500                         // Default settings\r
501                         s = t.settings = s || {};\r
502 \r
503                         // Strange app protocol or local anchor\r
504                         if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {\r
505                                 t.source = u;\r
506                                 return;\r
507                         }\r
508 \r
509                         // Absolute path with no host, fake host and protocol\r
510                         if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)\r
511                                 u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;\r
512 \r
513                         // Relative path\r
514                         if (u.indexOf('://') === -1 && u.indexOf('//') !== 0)\r
515                                 u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);\r
516 \r
517                         // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)\r
518                         u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something\r
519                         u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);\r
520                         each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {\r
521                                 var s = u[i];\r
522 \r
523                                 // Zope 3 workaround, they use @@something\r
524                                 if (s)\r
525                                         s = s.replace(/\(mce_at\)/g, '@@');\r
526 \r
527                                 t[v] = s;\r
528                         });\r
529 \r
530                         if (b = s.base_uri) {\r
531                                 if (!t.protocol)\r
532                                         t.protocol = b.protocol;\r
533 \r
534                                 if (!t.userInfo)\r
535                                         t.userInfo = b.userInfo;\r
536 \r
537                                 if (!t.port && t.host == 'mce_host')\r
538                                         t.port = b.port;\r
539 \r
540                                 if (!t.host || t.host == 'mce_host')\r
541                                         t.host = b.host;\r
542 \r
543                                 t.source = '';\r
544                         }\r
545 \r
546                         //t.path = t.path || '/';\r
547                 },\r
548 \r
549                 setPath : function(p) {\r
550                         var t = this;\r
551 \r
552                         p = /^(.*?)\/?(\w+)?$/.exec(p);\r
553 \r
554                         // Update path parts\r
555                         t.path = p[0];\r
556                         t.directory = p[1];\r
557                         t.file = p[2];\r
558 \r
559                         // Rebuild source\r
560                         t.source = '';\r
561                         t.getURI();\r
562                 },\r
563 \r
564                 toRelative : function(u) {\r
565                         var t = this, o;\r
566 \r
567                         u = new tinymce.util.URI(u, {base_uri : t});\r
568 \r
569                         // Not on same domain/port or protocol\r
570                         if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)\r
571                                 return u.getURI();\r
572 \r
573                         o = t.toRelPath(t.path, u.path);\r
574 \r
575                         // Add query\r
576                         if (u.query)\r
577                                 o += '?' + u.query;\r
578 \r
579                         // Add anchor\r
580                         if (u.anchor)\r
581                                 o += '#' + u.anchor;\r
582 \r
583                         return o;\r
584                 },\r
585         \r
586                 toAbsolute : function(u, nh) {\r
587                         var u = new tinymce.util.URI(u, {base_uri : this});\r
588 \r
589                         return u.getURI(this.host == u.host ? nh : 0);\r
590                 },\r
591 \r
592                 toRelPath : function(base, path) {\r
593                         var items, bp = 0, out = '', i;\r
594 \r
595                         // Split the paths\r
596                         base = base.substring(0, base.lastIndexOf('/'));\r
597                         base = base.split('/');\r
598                         items = path.split('/');\r
599 \r
600                         if (base.length >= items.length) {\r
601                                 for (i = 0; i < base.length; i++) {\r
602                                         if (i >= items.length || base[i] != items[i]) {\r
603                                                 bp = i + 1;\r
604                                                 break;\r
605                                         }\r
606                                 }\r
607                         }\r
608 \r
609                         if (base.length < items.length) {\r
610                                 for (i = 0; i < items.length; i++) {\r
611                                         if (i >= base.length || base[i] != items[i]) {\r
612                                                 bp = i + 1;\r
613                                                 break;\r
614                                         }\r
615                                 }\r
616                         }\r
617 \r
618                         if (bp == 1)\r
619                                 return path;\r
620 \r
621                         for (i = 0; i < base.length - (bp - 1); i++)\r
622                                 out += "../";\r
623 \r
624                         for (i = bp - 1; i < items.length; i++) {\r
625                                 if (i != bp - 1)\r
626                                         out += "/" + items[i];\r
627                                 else\r
628                                         out += items[i];\r
629                         }\r
630 \r
631                         return out;\r
632                 },\r
633 \r
634                 toAbsPath : function(base, path) {\r
635                         var i, nb = 0, o = [];\r
636 \r
637                         // Split paths\r
638                         base = base.split('/');\r
639                         path = path.split('/');\r
640 \r
641                         // Remove empty chunks\r
642                         each(base, function(k) {\r
643                                 if (k)\r
644                                         o.push(k);\r
645                         });\r
646 \r
647                         base = o;\r
648 \r
649                         // Merge relURLParts chunks\r
650                         for (i = path.length - 1, o = []; i >= 0; i--) {\r
651                                 // Ignore empty or .\r
652                                 if (path[i].length == 0 || path[i] == ".")\r
653                                         continue;\r
654 \r
655                                 // Is parent\r
656                                 if (path[i] == '..') {\r
657                                         nb++;\r
658                                         continue;\r
659                                 }\r
660 \r
661                                 // Move up\r
662                                 if (nb > 0) {\r
663                                         nb--;\r
664                                         continue;\r
665                                 }\r
666 \r
667                                 o.push(path[i]);\r
668                         }\r
669 \r
670                         i = base.length - nb;\r
671 \r
672                         // If /a/b/c or /\r
673                         if (i <= 0)\r
674                                 return '/' + o.reverse().join('/');\r
675 \r
676                         return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');\r
677                 },\r
678 \r
679                 getURI : function(nh) {\r
680                         var s, t = this;\r
681 \r
682                         // Rebuild source\r
683                         if (!t.source || nh) {\r
684                                 s = '';\r
685 \r
686                                 if (!nh) {\r
687                                         if (t.protocol)\r
688                                                 s += t.protocol + '://';\r
689 \r
690                                         if (t.userInfo)\r
691                                                 s += t.userInfo + '@';\r
692 \r
693                                         if (t.host)\r
694                                                 s += t.host;\r
695 \r
696                                         if (t.port)\r
697                                                 s += ':' + t.port;\r
698                                 }\r
699 \r
700                                 if (t.path)\r
701                                         s += t.path;\r
702 \r
703                                 if (t.query)\r
704                                         s += '?' + t.query;\r
705 \r
706                                 if (t.anchor)\r
707                                         s += '#' + t.anchor;\r
708 \r
709                                 t.source = s;\r
710                         }\r
711 \r
712                         return t.source;\r
713                 }\r
714 \r
715                 });\r
716 })();\r
717 \r
718 /* file:jscripts/tiny_mce/classes/util/Cookie.js */\r
719 \r
720 (function() {\r
721         var each = tinymce.each;\r
722 \r
723         tinymce.create('static tinymce.util.Cookie', {\r
724                 getHash : function(n) {\r
725                         var v = this.get(n), h;\r
726 \r
727                         if (v) {\r
728                                 each(v.split('&'), function(v) {\r
729                                         v = v.split('=');\r
730                                         h = h || {};\r
731                                         h[unescape(v[0])] = unescape(v[1]);\r
732                                 });\r
733                         }\r
734 \r
735                         return h;\r
736                 },\r
737 \r
738                 setHash : function(n, v, e, p, d, s) {\r
739                         var o = '';\r
740 \r
741                         each(v, function(v, k) {\r
742                                 o += (!o ? '' : '&') + escape(k) + '=' + escape(v);\r
743                         });\r
744 \r
745                         this.set(n, o, e, p, d, s);\r
746                 },\r
747 \r
748                 get : function(n) {\r
749                         var c = document.cookie, e, p = n + "=", b;\r
750 \r
751                         // Strict mode\r
752                         if (!c)\r
753                                 return;\r
754 \r
755                         b = c.indexOf("; " + p);\r
756 \r
757                         if (b == -1) {\r
758                                 b = c.indexOf(p);\r
759 \r
760                                 if (b != 0)\r
761                                         return null;\r
762                         } else\r
763                                 b += 2;\r
764 \r
765                         e = c.indexOf(";", b);\r
766 \r
767                         if (e == -1)\r
768                                 e = c.length;\r
769 \r
770                         return unescape(c.substring(b + p.length, e));\r
771                 },\r
772 \r
773                 set : function(n, v, e, p, d, s) {\r
774                         document.cookie = n + "=" + escape(v) +\r
775                                 ((e) ? "; expires=" + e.toGMTString() : "") +\r
776                                 ((p) ? "; path=" + escape(p) : "") +\r
777                                 ((d) ? "; domain=" + d : "") +\r
778                                 ((s) ? "; secure" : "");\r
779                 },\r
780 \r
781                 remove : function(n, p) {\r
782                         var d = new Date();\r
783 \r
784                         d.setTime(d.getTime() - 1000);\r
785 \r
786                         this.set(n, '', d, p, d);\r
787                 }\r
788 \r
789                 });\r
790 })();\r
791 \r
792 /* file:jscripts/tiny_mce/classes/util/JSON.js */\r
793 \r
794 tinymce.create('static tinymce.util.JSON', {\r
795         serialize : function(o) {\r
796                 var i, v, s = tinymce.util.JSON.serialize, t;\r
797 \r
798                 if (o == null)\r
799                         return 'null';\r
800 \r
801                 t = typeof o;\r
802 \r
803                 if (t == 'string') {\r
804                         v = '\bb\tt\nn\ff\rr\""\'\'\\\\';\r
805 \r
806                         return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g, function(a, b) {\r
807                                 i = v.indexOf(b);\r
808 \r
809                                 if (i + 1)\r
810                                         return '\\' + v.charAt(i + 1);\r
811 \r
812                                 a = b.charCodeAt().toString(16);\r
813 \r
814                                 return '\\u' + '0000'.substring(a.length) + a;\r
815                         }) + '"';\r
816                 }\r
817 \r
818                 if (t == 'object') {\r
819                         if (o instanceof Array) {\r
820                                         for (i=0, v = '['; i<o.length; i++)\r
821                                                 v += (i > 0 ? ',' : '') + s(o[i]);\r
822 \r
823                                         return v + ']';\r
824                                 }\r
825 \r
826                                 v = '{';\r
827 \r
828                                 for (i in o)\r
829                                         v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';\r
830 \r
831                                 return v + '}';\r
832                 }\r
833 \r
834                 return '' + o;\r
835         },\r
836 \r
837         parse : function(s) {\r
838                 try {\r
839                         return eval('(' + s + ')');\r
840                 } catch (ex) {\r
841                         // Ignore\r
842                 }\r
843         }\r
844 \r
845         });\r
846 \r
847 /* file:jscripts/tiny_mce/classes/util/XHR.js */\r
848 \r
849 tinymce.create('static tinymce.util.XHR', {\r
850         send : function(o) {\r
851                 var x, t, w = window, c = 0;\r
852 \r
853                 // Default settings\r
854                 o.scope = o.scope || this;\r
855                 o.success_scope = o.success_scope || o.scope;\r
856                 o.error_scope = o.error_scope || o.scope;\r
857                 o.async = o.async === false ? false : true;\r
858                 o.data = o.data || '';\r
859 \r
860                 function get(s) {\r
861                         x = 0;\r
862 \r
863                         try {\r
864                                 x = new ActiveXObject(s);\r
865                         } catch (ex) {\r
866                         }\r
867 \r
868                         return x;\r
869                 };\r
870 \r
871                 x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');\r
872 \r
873                 if (x) {\r
874                         if (x.overrideMimeType)\r
875                                 x.overrideMimeType(o.content_type);\r
876 \r
877                         x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);\r
878 \r
879                         if (o.content_type)\r
880                                 x.setRequestHeader('Content-Type', o.content_type);\r
881 \r
882                         x.send(o.data);\r
883 \r
884                         function ready() {\r
885                                 if (!o.async || x.readyState == 4 || c++ > 10000) {\r
886                                         if (o.success && c < 10000 && x.status == 200)\r
887                                                 o.success.call(o.success_scope, '' + x.responseText, x, o);\r
888                                         else if (o.error)\r
889                                                 o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);\r
890 \r
891                                         x = null;\r
892                                 } else\r
893                                         w.setTimeout(ready, 10);\r
894                         };\r
895 \r
896                         // Syncronous request\r
897                         if (!o.async)\r
898                                 return ready();\r
899 \r
900                         // Wait for response, onReadyStateChange can not be used since it leaks memory in IE\r
901                         t = w.setTimeout(ready, 10);\r
902                 }\r
903 \r
904                 }\r
905 });\r
906 \r
907 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */\r
908 \r
909 (function() {\r
910         var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;\r
911 \r
912         tinymce.create('tinymce.util.JSONRequest', {\r
913                 JSONRequest : function(s) {\r
914                         this.settings = extend({\r
915                         }, s);\r
916                         this.count = 0;\r
917                 },\r
918 \r
919                 send : function(o) {\r
920                         var ecb = o.error, scb = o.success;\r
921 \r
922                         o = extend(this.settings, o);\r
923 \r
924                         o.success = function(c, x) {\r
925                                 c = JSON.parse(c);\r
926 \r
927                                 if (typeof(c) == 'undefined') {\r
928                                         c = {\r
929                                                 error : 'JSON Parse error.'\r
930                                         };\r
931                                 }\r
932 \r
933                                 if (c.error)\r
934                                         ecb.call(o.error_scope || o.scope, c.error, x);\r
935                                 else\r
936                                         scb.call(o.success_scope || o.scope, c.result);\r
937                         };\r
938 \r
939                         o.error = function(ty, x) {\r
940                                 ecb.call(o.error_scope || o.scope, ty, x);\r
941                         };\r
942 \r
943                         o.data = JSON.serialize({\r
944                                 id : o.id || 'c' + (this.count++),\r
945                                 method : o.method,\r
946                                 params : o.params\r
947                         });\r
948 \r
949                         // JSON content type for Ruby on rails. Bug: #1883287\r
950                         o.content_type = 'application/json';\r
951 \r
952                         XHR.send(o);\r
953                 },\r
954 \r
955                 'static' : {\r
956                         sendRPC : function(o) {\r
957                                 return new tinymce.util.JSONRequest().send(o);\r
958                         }\r
959                 }\r
960 \r
961                 });\r
962 }());\r
963 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */\r
964 \r
965 (function() {\r
966         // Shorten names\r
967         var each = tinymce.each, is = tinymce.is;\r
968         var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE;\r
969 \r
970         tinymce.create('tinymce.dom.DOMUtils', {\r
971                 doc : null,\r
972                 root : null,\r
973                 files : null,\r
974                 listeners : {},\r
975                 pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,\r
976                 cache : {},\r
977                 idPattern : /^#[\w]+$/,\r
978                 elmPattern : /^[\w_*]+$/,\r
979                 elmClassPattern : /^([\w_]*)\.([\w_]+)$/,\r
980 \r
981                 DOMUtils : function(d, s) {\r
982                         var t = this;\r
983 \r
984                         t.doc = d;\r
985                         t.win = window;\r
986                         t.files = {};\r
987                         t.cssFlicker = false;\r
988                         t.counter = 0;\r
989                         t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; \r
990                         t.stdMode = d.documentMode === 8;\r
991 \r
992                         this.settings = s = tinymce.extend({\r
993                                 keep_values : false,\r
994                                 hex_colors : 1,\r
995                                 process_html : 1\r
996                         }, s);\r
997 \r
998                         // Fix IE6SP2 flicker and check it failed for pre SP2\r
999                         if (tinymce.isIE6) {\r
1000                                 try {\r
1001                                         d.execCommand('BackgroundImageCache', false, true);\r
1002                                 } catch (e) {\r
1003                                         t.cssFlicker = true;\r
1004                                 }\r
1005                         }\r
1006 \r
1007                         tinymce.addUnload(t.destroy, t);\r
1008                 },\r
1009 \r
1010                 getRoot : function() {\r
1011                         var t = this, s = t.settings;\r
1012 \r
1013                         return (s && t.get(s.root_element)) || t.doc.body;\r
1014                 },\r
1015 \r
1016                 getViewPort : function(w) {\r
1017                         var d, b;\r
1018 \r
1019                         w = !w ? this.win : w;\r
1020                         d = w.document;\r
1021                         b = this.boxModel ? d.documentElement : d.body;\r
1022 \r
1023                         // Returns viewport size excluding scrollbars\r
1024                         return {\r
1025                                 x : w.pageXOffset || b.scrollLeft,\r
1026                                 y : w.pageYOffset || b.scrollTop,\r
1027                                 w : w.innerWidth || b.clientWidth,\r
1028                                 h : w.innerHeight || b.clientHeight\r
1029                         };\r
1030                 },\r
1031 \r
1032                 getRect : function(e) {\r
1033                         var p, t = this, w, h;\r
1034 \r
1035                         e = t.get(e);\r
1036                         p = t.getPos(e);\r
1037                         w = t.getStyle(e, 'width');\r
1038                         h = t.getStyle(e, 'height');\r
1039 \r
1040                         // Non pixel value, then force offset/clientWidth\r
1041                         if (w.indexOf('px') === -1)\r
1042                                 w = 0;\r
1043 \r
1044                         // Non pixel value, then force offset/clientWidth\r
1045                         if (h.indexOf('px') === -1)\r
1046                                 h = 0;\r
1047 \r
1048                         return {\r
1049                                 x : p.x,\r
1050                                 y : p.y,\r
1051                                 w : parseInt(w) || e.offsetWidth || e.clientWidth,\r
1052                                 h : parseInt(h) || e.offsetHeight || e.clientHeight\r
1053                         };\r
1054                 },\r
1055 \r
1056                 getParent : function(n, f, r) {\r
1057                         var na, se = this.settings;\r
1058 \r
1059                         n = this.get(n);\r
1060 \r
1061                         if (se.strict_root)\r
1062                                 r = r || this.getRoot();\r
1063 \r
1064                         // Wrap node name as func\r
1065                         if (is(f, 'string')) {\r
1066                                 na = f.toUpperCase();\r
1067 \r
1068                                 f = function(n) {\r
1069                                         var s = false;\r
1070 \r
1071                                         // Any element\r
1072                                         if (n.nodeType == 1 && na === '*') {\r
1073                                                 s = true;\r
1074                                                 return false;\r
1075                                         }\r
1076 \r
1077                                         each(na.split(','), function(v) {\r
1078                                                 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName.toUpperCase() == v)) {\r
1079                                                         s = true;\r
1080                                                         return false; // Break loop\r
1081                                                 }\r
1082                                         });\r
1083 \r
1084                                         return s;\r
1085                                 };\r
1086                         }\r
1087 \r
1088                         while (n) {\r
1089                                 if (n == r)\r
1090                                         return null;\r
1091 \r
1092                                 if (f(n))\r
1093                                         return n;\r
1094 \r
1095                                 n = n.parentNode;\r
1096                         }\r
1097 \r
1098                         return null;\r
1099                 },\r
1100 \r
1101                 get : function(e) {\r
1102                         var n;\r
1103 \r
1104                         if (e && this.doc && typeof(e) == 'string') {\r
1105                                 n = e;\r
1106                                 e = this.doc.getElementById(e);\r
1107 \r
1108                                 // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick\r
1109                                 if (e && e.id !== n)\r
1110                                         return this.doc.getElementsByName(n)[1];\r
1111                         }\r
1112 \r
1113                         return e;\r
1114                 },\r
1115 \r
1116                 // #if !jquery\r
1117 \r
1118                 select : function(pa, s) {\r
1119                         var t = this, cs, c, pl, o = [], x, i, l, n;\r
1120 \r
1121                         s = t.get(s) || t.doc;\r
1122 \r
1123                         // Look for native support and use that if it's found\r
1124                         if (s.querySelectorAll) {\r
1125                                 // Element scope then use temp id\r
1126                                 // We need to do this to be compatible with other implementations\r
1127                                 // See bug report: http://bugs.webkit.org/show_bug.cgi?id=17461\r
1128                                 if (s != t.doc) {\r
1129                                         i = s.id;\r
1130                                         s.id = '_mc_tmp';\r
1131                                         pa = '#_mc_tmp ' + pa;\r
1132                                 }\r
1133 \r
1134                                 // Select elements\r
1135                                 l = tinymce.grep(s.querySelectorAll(pa));\r
1136 \r
1137                                 // Restore old id\r
1138                                 s.id = i;\r
1139 \r
1140                                 return l;\r
1141                         }\r
1142 \r
1143                         if (t.settings.strict) {\r
1144                                 function get(s, n) {\r
1145                                         return s.getElementsByTagName(n.toLowerCase());\r
1146                                 };\r
1147                         } else {\r
1148                                 function get(s, n) {\r
1149                                         return s.getElementsByTagName(n);\r
1150                                 };\r
1151                         }\r
1152 \r
1153                         // Simple element pattern. For example: "p" or "*"\r
1154                         if (t.elmPattern.test(pa)) {\r
1155                                 x = get(s, pa);\r
1156 \r
1157                                 for (i = 0, l = x.length; i<l; i++)\r
1158                                         o.push(x[i]);\r
1159 \r
1160                                 return o;\r
1161                         }\r
1162 \r
1163                         // Simple class pattern. For example: "p.class" or ".class"\r
1164                         if (t.elmClassPattern.test(pa)) {\r
1165                                 pl = t.elmClassPattern.exec(pa);\r
1166                                 x = get(s, pl[1] || '*');\r
1167                                 c = ' ' + pl[2] + ' ';\r
1168 \r
1169                                 for (i = 0, l = x.length; i<l; i++) {\r
1170                                         n = x[i];\r
1171 \r
1172                                         if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1)\r
1173                                                 o.push(n);\r
1174                                 }\r
1175 \r
1176                                 return o;\r
1177                         }\r
1178 \r
1179                         function collect(n) {\r
1180                                 if (!n.mce_save) {\r
1181                                         n.mce_save = 1;\r
1182                                         o.push(n);\r
1183                                 }\r
1184                         };\r
1185 \r
1186                         function collectIE(n) {\r
1187                                 if (!n.getAttribute('mce_save')) {\r
1188                                         n.setAttribute('mce_save', '1');\r
1189                                         o.push(n);\r
1190                                 }\r
1191                         };\r
1192 \r
1193                         function find(n, f, r) {\r
1194                                 var i, l, nl = get(r, n);\r
1195 \r
1196                                 for (i = 0, l = nl.length; i < l; i++)\r
1197                                         f(nl[i]);\r
1198                         };\r
1199 \r
1200                         each(pa.split(','), function(v, i) {\r
1201                                 v = tinymce.trim(v);\r
1202 \r
1203                                 // Simple element pattern, most common in TinyMCE\r
1204                                 if (t.elmPattern.test(v)) {\r
1205                                         each(get(s, v), function(n) {\r
1206                                                 collect(n);\r
1207                                         });\r
1208 \r
1209                                         return;\r
1210                                 }\r
1211 \r
1212                                 // Simple element pattern with class, fairly common in TinyMCE\r
1213                                 if (t.elmClassPattern.test(v)) {\r
1214                                         x = t.elmClassPattern.exec(v);\r
1215 \r
1216                                         each(get(s, x[1]), function(n) {\r
1217                                                 if (t.hasClass(n, x[2]))\r
1218                                                         collect(n);\r
1219                                         });\r
1220 \r
1221                                         return;\r
1222                                 }\r
1223 \r
1224                                 if (!(cs = t.cache[pa])) {\r
1225                                         cs = 'x=(function(cf, s) {';\r
1226                                         pl = v.split(' ');\r
1227 \r
1228                                         each(pl, function(v) {\r
1229                                                 var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v);\r
1230 \r
1231                                                 // Find elements\r
1232                                                 p[1] = p[1] || '*';\r
1233                                                 cs += 'find("' + p[1] + '", function(n) {';\r
1234 \r
1235                                                 // Check id\r
1236                                                 if (p[2])\r
1237                                                         cs += 'if (n.id !== "' + p[2] + '") return;';\r
1238 \r
1239                                                 // Check classes\r
1240                                                 if (p[3]) {\r
1241                                                         cs += 'var c = " " + n.className + " ";';\r
1242                                                         cs += 'if (';\r
1243                                                         c = '';\r
1244                                                         each(p[3].split('.'), function(v) {\r
1245                                                                 if (v)\r
1246                                                                         c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1';\r
1247                                                         });\r
1248                                                         cs += c + ') return;';\r
1249                                                 }\r
1250                                         });\r
1251 \r
1252                                         cs += 'cf(n);';\r
1253 \r
1254                                         for (i = pl.length - 1; i >= 0; i--)\r
1255                                                 cs += '}, ' + (i ? 'n' : 's') + ');';\r
1256 \r
1257                                         cs += '})';\r
1258 \r
1259                                         // Compile CSS pattern function\r
1260                                         t.cache[pa] = cs = eval(cs);\r
1261                                 }\r
1262 \r
1263                                 // Run selector function\r
1264                                 cs(isIE ? collectIE : collect, s);\r
1265                         });\r
1266 \r
1267                         // Cleanup\r
1268                         each(o, function(n) {\r
1269                                 if (isIE)\r
1270                                         n.removeAttribute('mce_save');\r
1271                                 else\r
1272                                         delete n.mce_save;\r
1273                         });\r
1274 \r
1275                         return o;\r
1276                 },\r
1277 \r
1278                 // #endif\r
1279 \r
1280                 add : function(p, n, a, h, c) {\r
1281                         var t = this;\r
1282 \r
1283                         return this.run(p, function(p) {\r
1284                                 var e, k;\r
1285 \r
1286                                 e = is(n, 'string') ? t.doc.createElement(n) : n;\r
1287 \r
1288                                 if (a) {\r
1289                                         for (k in a) {\r
1290                                                 if (a.hasOwnProperty(k) && !is(a[k], 'object'))\r
1291                                                         t.setAttrib(e, k, '' + a[k]);\r
1292                                         }\r
1293 \r
1294                                         if (a.style && !is(a.style, 'string')) {\r
1295                                                 each(a.style, function(v, n) {\r
1296                                                         t.setStyle(e, n, v);\r
1297                                                 });\r
1298                                         }\r
1299                                 }\r
1300 \r
1301                                 if (h) {\r
1302                                         if (h.nodeType)\r
1303                                                 e.appendChild(h);\r
1304                                         else\r
1305                                                 t.setHTML(e, h);\r
1306                                 }\r
1307 \r
1308                                 return !c ? p.appendChild(e) : e;\r
1309                         });\r
1310                 },\r
1311 \r
1312                 create : function(n, a, h) {\r
1313                         return this.add(this.doc.createElement(n), n, a, h, 1);\r
1314                 },\r
1315 \r
1316                 createHTML : function(n, a, h) {\r
1317                         var o = '', t = this, k;\r
1318 \r
1319                         o += '<' + n;\r
1320 \r
1321                         for (k in a) {\r
1322                                 if (a.hasOwnProperty(k))\r
1323                                         o += ' ' + k + '="' + t.encode(a[k]) + '"';\r
1324                         }\r
1325 \r
1326                         if (tinymce.is(h))\r
1327                                 return o + '>' + h + '</' + n + '>';\r
1328 \r
1329                         return o + ' />';\r
1330                 },\r
1331 \r
1332                 remove : function(n, k) {\r
1333                         return this.run(n, function(n) {\r
1334                                 var p, g;\r
1335 \r
1336                                 p = n.parentNode;\r
1337 \r
1338                                 if (!p)\r
1339                                         return null;\r
1340 \r
1341                                 if (k) {\r
1342                                         each (n.childNodes, function(c) {\r
1343                                                 p.insertBefore(c.cloneNode(true), n);\r
1344                                         });\r
1345                                 }\r
1346 \r
1347                                 // Fix IE psuedo leak\r
1348                 /*              if (isIE) {\r
1349                                         p = n.cloneNode(true);\r
1350                                         n.outerHTML = '';\r
1351 \r
1352                                         return p;\r
1353                                 }*/\r
1354 \r
1355                                 return p.removeChild(n);\r
1356                         });\r
1357                 },\r
1358 \r
1359                 // #if !jquery\r
1360 \r
1361                 setStyle : function(n, na, v) {\r
1362                         var t = this;\r
1363 \r
1364                         return t.run(n, function(e) {\r
1365                                 var s, i;\r
1366 \r
1367                                 s = e.style;\r
1368 \r
1369                                 // Camelcase it, if needed\r
1370                                 na = na.replace(/-(\D)/g, function(a, b){\r
1371                                         return b.toUpperCase();\r
1372                                 });\r
1373 \r
1374                                 // Default px suffix on these\r
1375                                 if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))\r
1376                                         v += 'px';\r
1377 \r
1378                                 switch (na) {\r
1379                                         case 'opacity':\r
1380                                                 // IE specific opacity\r
1381                                                 if (isIE) {\r
1382                                                         s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";\r
1383 \r
1384                                                         if (!n.currentStyle || !n.currentStyle.hasLayout)\r
1385                                                                 s.display = 'inline-block';\r
1386                                                 }\r
1387 \r
1388                                                 // Fix for older browsers\r
1389                                                 s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || '';\r
1390                                                 break;\r
1391 \r
1392                                         case 'float':\r
1393                                                 isIE ? s.styleFloat = v : s.cssFloat = v;\r
1394                                                 break;\r
1395                                         \r
1396                                         default:\r
1397                                                 s[na] = v || '';\r
1398                                 }\r
1399 \r
1400                                 // Force update of the style data\r
1401                                 if (t.settings.update_styles)\r
1402                                         t.setAttrib(e, 'mce_style');\r
1403                         });\r
1404                 },\r
1405 \r
1406                 getStyle : function(n, na, c) {\r
1407                         n = this.get(n);\r
1408 \r
1409                         if (!n)\r
1410                                 return false;\r
1411 \r
1412                         // Gecko\r
1413                         if (this.doc.defaultView && c) {\r
1414                                 // Remove camelcase\r
1415                                 na = na.replace(/[A-Z]/g, function(a){\r
1416                                         return '-' + a;\r
1417                                 });\r
1418 \r
1419                                 try {\r
1420                                         return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);\r
1421                                 } catch (ex) {\r
1422                                         // Old safari might fail\r
1423                                         return null;\r
1424                                 }\r
1425                         }\r
1426 \r
1427                         // Camelcase it, if needed\r
1428                         na = na.replace(/-(\D)/g, function(a, b){\r
1429                                 return b.toUpperCase();\r
1430                         });\r
1431 \r
1432                         if (na == 'float')\r
1433                                 na = isIE ? 'styleFloat' : 'cssFloat';\r
1434 \r
1435                         // IE & Opera\r
1436                         if (n.currentStyle && c)\r
1437                                 return n.currentStyle[na];\r
1438 \r
1439                         return n.style[na];\r
1440                 },\r
1441 \r
1442                 setStyles : function(e, o) {\r
1443                         var t = this, s = t.settings, ol;\r
1444 \r
1445                         ol = s.update_styles;\r
1446                         s.update_styles = 0;\r
1447 \r
1448                         each(o, function(v, n) {\r
1449                                 t.setStyle(e, n, v);\r
1450                         });\r
1451 \r
1452                         // Update style info\r
1453                         s.update_styles = ol;\r
1454                         if (s.update_styles)\r
1455                                 t.setAttrib(e, s.cssText);\r
1456                 },\r
1457 \r
1458                 setAttrib : function(e, n, v) {\r
1459                         var t = this;\r
1460 \r
1461                         // Strict XML mode\r
1462                         if (t.settings.strict)\r
1463                                 n = n.toLowerCase();\r
1464 \r
1465                         return this.run(e, function(e) {\r
1466                                 var s = t.settings;\r
1467 \r
1468                                 switch (n) {\r
1469                                         case "style":\r
1470                                                 // No mce_style for elements with these since they might get resized by the user\r
1471                                                 if (s.keep_values) {\r
1472                                                         if (v && !t._isRes(v))\r
1473                                                                 e.setAttribute('mce_style', v, 2);\r
1474                                                         else\r
1475                                                                 e.removeAttribute('mce_style', 2);\r
1476                                                 }\r
1477 \r
1478                                                 e.style.cssText = v;\r
1479                                                 break;\r
1480 \r
1481                                         case "class":\r
1482                                                 e.className = v || ''; // Fix IE null bug\r
1483                                                 break;\r
1484 \r
1485                                         case "src":\r
1486                                         case "href":\r
1487                                                 if (s.keep_values) {\r
1488                                                         if (s.url_converter)\r
1489                                                                 v = s.url_converter.call(s.url_converter_scope || t, v, n, e);\r
1490 \r
1491                                                         t.setAttrib(e, 'mce_' + n, v, 2);\r
1492                                                 }\r
1493 \r
1494                                                 break;\r
1495                                         \r
1496                                         case "shape":\r
1497                                                 e.setAttribute('mce_style', v);\r
1498                                                 break;\r
1499                                 }\r
1500 \r
1501                                 if (is(v) && v !== null && v.length !== 0)\r
1502                                         e.setAttribute(n, '' + v, 2);\r
1503                                 else\r
1504                                         e.removeAttribute(n, 2);\r
1505                         });\r
1506                 },\r
1507 \r
1508                 setAttribs : function(e, o) {\r
1509                         var t = this;\r
1510 \r
1511                         return this.run(e, function(e) {\r
1512                                 each(o, function(v, n) {\r
1513                                         t.setAttrib(e, n, v);\r
1514                                 });\r
1515                         });\r
1516                 },\r
1517 \r
1518                 // #endif\r
1519 \r
1520                 getAttrib : function(e, n, dv) {\r
1521                         var v, t = this;\r
1522 \r
1523                         e = t.get(e);\r
1524 \r
1525                         if (!e || e.nodeType !== 1)\r
1526                                 return false;\r
1527 \r
1528                         if (!is(dv))\r
1529                                 dv = "";\r
1530 \r
1531                         // Try the mce variant for these\r
1532                         if (/^(src|href|style|coords|shape)$/.test(n)) {\r
1533                                 v = e.getAttribute("mce_" + n);\r
1534 \r
1535                                 if (v)\r
1536                                         return v;\r
1537                         }\r
1538 \r
1539                         v = e.getAttribute(n, 2);\r
1540 \r
1541                         if (!v) {\r
1542                                 switch (n) {\r
1543                                         case 'class':\r
1544                                                 v = e.className;\r
1545                                                 break;\r
1546 \r
1547                                         default:\r
1548                                                 // Fix for IE crash Bug: #1884376 probably due to invalid DOM structure\r
1549                                                 if (isIE && n === 'name' && e.nodeName === 'A') {\r
1550                                                         v = e.name;\r
1551                                                         break;\r
1552                                                 }\r
1553 \r
1554                                                 v = e.attributes[n];\r
1555                                                 v = v && is(v.nodeValue) ? v.nodeValue : v;\r
1556                                 }\r
1557                         }\r
1558 \r
1559                         switch (n) {\r
1560                                 case 'style':\r
1561                                         v = v || e.style.cssText;\r
1562 \r
1563                                         if (v) {\r
1564                                                 v = t.serializeStyle(t.parseStyle(v));\r
1565 \r
1566                                                 if (t.settings.keep_values && !t._isRes(v))\r
1567                                                         e.setAttribute('mce_style', v);\r
1568                                         }\r
1569 \r
1570                                         break;\r
1571                         }\r
1572 \r
1573                         // Remove Apple and WebKit stuff\r
1574                         if (isWebKit && n === "class" && v)\r
1575                                 v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');\r
1576 \r
1577                         // Handle IE issues\r
1578                         if (isIE) {\r
1579                                 switch (n) {\r
1580                                         case 'rowspan':\r
1581                                         case 'colspan':\r
1582                                                 // IE returns 1 as default value\r
1583                                                 if (v === 1)\r
1584                                                         v = '';\r
1585 \r
1586                                                 break;\r
1587 \r
1588                                         case 'size':\r
1589                                                 // IE returns +0 as default value for size\r
1590                                                 if (v === '+0')\r
1591                                                         v = '';\r
1592 \r
1593                                                 break;\r
1594 \r
1595                                         case 'hspace':\r
1596                                                 // IE returns -1 as default value\r
1597                                                 if (v === -1)\r
1598                                                         v = '';\r
1599 \r
1600                                                 break;\r
1601 \r
1602                                         case 'tabindex':\r
1603                                                 // IE returns default value\r
1604                                                 if (v === 32768)\r
1605                                                         v = '';\r
1606 \r
1607                                                 break;\r
1608 \r
1609                                         case 'maxlength':\r
1610                                                 // IE returns  default value\r
1611                                                 if (v === 2147483647)\r
1612                                                         v = '';\r
1613 \r
1614                                                 break;\r
1615 \r
1616                                         case 'shape':\r
1617                                                 v = v.toLowerCase();\r
1618                                                 break;\r
1619 \r
1620                                         default:\r
1621                                                 // IE has odd anonymous function for event attributes\r
1622                                                 if (n.indexOf('on') === 0 && v)\r
1623                                                         v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');\r
1624                                 }\r
1625                         }\r
1626 \r
1627                         return (v && v != '') ? '' + v : dv;\r
1628                 },\r
1629 \r
1630                 getPos : function(n) {\r
1631                         var t = this, x = 0, y = 0, e, d = t.doc, r;\r
1632 \r
1633                         n = t.get(n);\r
1634 \r
1635                         // Use getBoundingClientRect on IE, Opera has it but it's not perfect\r
1636                         if (n && isIE) {\r
1637                                 n = n.getBoundingClientRect();\r
1638                                 e = t.boxModel ? d.documentElement : d.body;\r
1639                                 x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border\r
1640                                 x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;\r
1641                                 n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset\r
1642 \r
1643                                 return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
1644                         }\r
1645 \r
1646                         r = n;\r
1647                         while (r) {\r
1648                                 x += r.offsetLeft || 0;\r
1649                                 y += r.offsetTop || 0;\r
1650                                 r = r.offsetParent;\r
1651                         }\r
1652 \r
1653                         r = n;\r
1654                         while (r) {\r
1655                                 // Opera 9.25 bug fix, fixed in 9.50\r
1656                                 if (!/^table-row|inline.*/i.test(t.getStyle(r, "display", 1))) {\r
1657                                         x -= r.scrollLeft || 0;\r
1658                                         y -= r.scrollTop || 0;\r
1659                                 }\r
1660 \r
1661                                 r = r.parentNode;\r
1662 \r
1663                                 if (r == d.body)\r
1664                                         break;\r
1665                         }\r
1666 \r
1667                         return {x : x, y : y};\r
1668                 },\r
1669 \r
1670                 parseStyle : function(st) {\r
1671                         var t = this, s = t.settings, o = {};\r
1672 \r
1673                         if (!st)\r
1674                                 return o;\r
1675 \r
1676                         function compress(p, s, ot) {\r
1677                                 var t, r, b, l;\r
1678 \r
1679                                 // Get values and check it it needs compressing\r
1680                                 t = o[p + '-top' + s];\r
1681                                 if (!t)\r
1682                                         return;\r
1683 \r
1684                                 r = o[p + '-right' + s];\r
1685                                 if (t != r)\r
1686                                         return;\r
1687 \r
1688                                 b = o[p + '-bottom' + s];\r
1689                                 if (r != b)\r
1690                                         return;\r
1691 \r
1692                                 l = o[p + '-left' + s];\r
1693                                 if (b != l)\r
1694                                         return;\r
1695 \r
1696                                 // Compress\r
1697                                 o[ot] = l;\r
1698                                 delete o[p + '-top' + s];\r
1699                                 delete o[p + '-right' + s];\r
1700                                 delete o[p + '-bottom' + s];\r
1701                                 delete o[p + '-left' + s];\r
1702                         };\r
1703 \r
1704                         function compress2(ta, a, b, c) {\r
1705                                 var t;\r
1706 \r
1707                                 t = o[a];\r
1708                                 if (!t)\r
1709                                         return;\r
1710 \r
1711                                 t = o[b];\r
1712                                 if (!t)\r
1713                                         return;\r
1714 \r
1715                                 t = o[c];\r
1716                                 if (!t)\r
1717                                         return;\r
1718 \r
1719                                 // Compress\r
1720                                 o[ta] = o[a] + ' ' + o[b] + ' ' + o[c];\r
1721                                 delete o[a];\r
1722                                 delete o[b];\r
1723                                 delete o[c];\r
1724                         };\r
1725 \r
1726                         st = st.replace(/&(#?[a-z0-9]+);/g, '&$1_MCE_SEMI_'); // Protect entities\r
1727 \r
1728                         each(st.split(';'), function(v) {\r
1729                                 var sv, ur = [];\r
1730 \r
1731                                 if (v) {\r
1732                                         v = v.replace(/_MCE_SEMI_/g, ';'); // Restore entities\r
1733                                         v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';});\r
1734                                         v = v.split(':');\r
1735                                         sv = tinymce.trim(v[1]);\r
1736                                         sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];});\r
1737 \r
1738                                         sv = sv.replace(/rgb\([^\)]+\)/g, function(v) {\r
1739                                                 return t.toHex(v);\r
1740                                         });\r
1741 \r
1742                                         if (s.url_converter) {\r
1743                                                 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) {\r
1744                                                         return 'url(' + s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null) + ')';\r
1745                                                 });\r
1746                                         }\r
1747 \r
1748                                         o[tinymce.trim(v[0]).toLowerCase()] = sv;\r
1749                                 }\r
1750                         });\r
1751 \r
1752                         compress("border", "", "border");\r
1753                         compress("border", "-width", "border-width");\r
1754                         compress("border", "-color", "border-color");\r
1755                         compress("border", "-style", "border-style");\r
1756                         compress("padding", "", "padding");\r
1757                         compress("margin", "", "margin");\r
1758                         compress2('border', 'border-width', 'border-style', 'border-color');\r
1759 \r
1760                         if (isIE) {\r
1761                                 // Remove pointless border\r
1762                                 if (o.border == 'medium none')\r
1763                                         o.border = '';\r
1764                         }\r
1765 \r
1766                         return o;\r
1767                 },\r
1768 \r
1769                 serializeStyle : function(o) {\r
1770                         var s = '';\r
1771 \r
1772                         each(o, function(v, k) {\r
1773                                 if (k && v) {\r
1774                                         if (tinymce.isGecko && k.indexOf('-moz-') === 0)\r
1775                                                 return;\r
1776 \r
1777                                         switch (k) {\r
1778                                                 case 'color':\r
1779                                                 case 'background-color':\r
1780                                                         v = v.toLowerCase();\r
1781                                                         break;\r
1782                                         }\r
1783 \r
1784                                         s += (s ? ' ' : '') + k + ': ' + v + ';';\r
1785                                 }\r
1786                         });\r
1787 \r
1788                         return s;\r
1789                 },\r
1790 \r
1791                 loadCSS : function(u) {\r
1792                         var t = this, d = t.doc;\r
1793 \r
1794                         if (!u)\r
1795                                 u = '';\r
1796 \r
1797                         each(u.split(','), function(u) {\r
1798                                 if (t.files[u])\r
1799                                         return;\r
1800 \r
1801                                 t.files[u] = true;\r
1802                                 t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : tinymce._addVer(u)});\r
1803                         });\r
1804                 },\r
1805 \r
1806                 // #if !jquery\r
1807 \r
1808                 addClass : function(e, c) {\r
1809                         return this.run(e, function(e) {\r
1810                                 var o;\r
1811 \r
1812                                 if (!c)\r
1813                                         return 0;\r
1814 \r
1815                                 if (this.hasClass(e, c))\r
1816                                         return e.className;\r
1817 \r
1818                                 o = this.removeClass(e, c);\r
1819 \r
1820                                 return e.className = (o != '' ? (o + ' ') : '') + c;\r
1821                         });\r
1822                 },\r
1823 \r
1824                 removeClass : function(e, c) {\r
1825                         var t = this, re;\r
1826 \r
1827                         return t.run(e, function(e) {\r
1828                                 var v;\r
1829 \r
1830                                 if (t.hasClass(e, c)) {\r
1831                                         if (!re)\r
1832                                                 re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");\r
1833 \r
1834                                         v = e.className.replace(re, ' ');\r
1835 \r
1836                                         return e.className = tinymce.trim(v != ' ' ? v : '');\r
1837                                 }\r
1838 \r
1839                                 return e.className;\r
1840                         });\r
1841                 },\r
1842 \r
1843                 hasClass : function(n, c) {\r
1844                         n = this.get(n);\r
1845 \r
1846                         if (!n || !c)\r
1847                                 return false;\r
1848 \r
1849                         return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;\r
1850                 },\r
1851 \r
1852                 show : function(e) {\r
1853                         return this.setStyle(e, 'display', 'block');\r
1854                 },\r
1855 \r
1856                 hide : function(e) {\r
1857                         return this.setStyle(e, 'display', 'none');\r
1858                 },\r
1859 \r
1860                 isHidden : function(e) {\r
1861                         e = this.get(e);\r
1862 \r
1863                         return e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
1864                 },\r
1865 \r
1866                 // #endif\r
1867 \r
1868                 uniqueId : function(p) {\r
1869                         return (!p ? 'mce_' : p) + (this.counter++);\r
1870                 },\r
1871 \r
1872                 setHTML : function(e, h) {\r
1873                         var t = this;\r
1874 \r
1875                         return this.run(e, function(e) {\r
1876                                 var x, i, nl, n, p, x;\r
1877 \r
1878                                 h = t.processHTML(h);\r
1879 \r
1880                                 if (isIE) {\r
1881                                         function set() {\r
1882                                                 try {\r
1883                                                         // IE will remove comments from the beginning\r
1884                                                         // unless you padd the contents with something\r
1885                                                         e.innerHTML = '<br />' + h;\r
1886                                                         e.removeChild(e.firstChild);\r
1887                                                 } catch (ex) {\r
1888                                                         // IE sometimes produces an unknown runtime error on innerHTML if it's an block element within a block element for example a div inside a p\r
1889                                                         // This seems to fix this problem\r
1890 \r
1891                                                         // Remove all child nodes\r
1892                                                         while (e.firstChild)\r
1893                                                                 e.firstChild.removeNode();\r
1894 \r
1895                                                         // Create new div with HTML contents and a BR infront to keep comments\r
1896                                                         x = t.create('div');\r
1897                                                         x.innerHTML = '<br />' + h;\r
1898 \r
1899                                                         // Add all children from div to target\r
1900                                                         each (x.childNodes, function(n, i) {\r
1901                                                                 // Skip br element\r
1902                                                                 if (i)\r
1903                                                                         e.appendChild(n);\r
1904                                                         });\r
1905                                                 }\r
1906                                         };\r
1907 \r
1908                                         // IE has a serious bug when it comes to paragraphs it can produce an invalid\r
1909                                         // DOM tree if contents like this <p><ul><li>Item 1</li></ul></p> is inserted\r
1910                                         // It seems to be that IE doesn't like a root block element placed inside another root block element\r
1911                                         if (t.settings.fix_ie_paragraphs)\r
1912                                                 h = h.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi, '<p$1 mce_keep="true">&nbsp;</p>');\r
1913 \r
1914                                         set();\r
1915 \r
1916                                         if (t.settings.fix_ie_paragraphs) {\r
1917                                                 // Check for odd paragraphs this is a sign of a broken DOM\r
1918                                                 nl = e.getElementsByTagName("p");\r
1919                                                 for (i = nl.length - 1, x = 0; i >= 0; i--) {\r
1920                                                         n = nl[i];\r
1921 \r
1922                                                         if (!n.hasChildNodes()) {\r
1923                                                                 if (!n.mce_keep) {\r
1924                                                                         x = 1; // Is broken\r
1925                                                                         break;\r
1926                                                                 }\r
1927 \r
1928                                                                 n.removeAttribute('mce_keep');\r
1929                                                         }\r
1930                                                 }\r
1931                                         }\r
1932 \r
1933                                         // Time to fix the madness IE left us\r
1934                                         if (x) {\r
1935                                                 // So if we replace the p elements with divs and mark them and then replace them back to paragraphs\r
1936                                                 // after we use innerHTML we can fix the DOM tree\r
1937                                                 h = h.replace(/<p([^>]+)>|<p>/g, '<div$1 mce_tmp="1">');\r
1938                                                 h = h.replace(/<\/p>/g, '</div>');\r
1939 \r
1940                                                 // Set the new HTML with DIVs\r
1941                                                 set();\r
1942 \r
1943                                                 // Replace all DIV elements with he mce_tmp attibute back to paragraphs\r
1944                                                 // This is needed since IE has a annoying bug see above for details\r
1945                                                 // This is a slow process but it has to be done. :(\r
1946                                                 if (t.settings.fix_ie_paragraphs) {\r
1947                                                         nl = e.getElementsByTagName("DIV");\r
1948                                                         for (i = nl.length - 1; i >= 0; i--) {\r
1949                                                                 n = nl[i];\r
1950 \r
1951                                                                 // Is it a temp div\r
1952                                                                 if (n.mce_tmp) {\r
1953                                                                         // Create new paragraph\r
1954                                                                         p = t.doc.createElement('p');\r
1955 \r
1956                                                                         // Copy all attributes\r
1957                                                                         n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) {\r
1958                                                                                 var v;\r
1959 \r
1960                                                                                 if (b !== 'mce_tmp') {\r
1961                                                                                         v = n.getAttribute(b);\r
1962 \r
1963                                                                                         if (!v && b === 'class')\r
1964                                                                                                 v = n.className;\r
1965 \r
1966                                                                                         p.setAttribute(b, v);\r
1967                                                                                 }\r
1968                                                                         });\r
1969 \r
1970                                                                         // Append all children to new paragraph\r
1971                                                                         for (x = 0; x<n.childNodes.length; x++)\r
1972                                                                                 p.appendChild(n.childNodes[x].cloneNode(true));\r
1973 \r
1974                                                                         // Replace div with new paragraph\r
1975                                                                         n.swapNode(p);\r
1976                                                                 }\r
1977                                                         }\r
1978                                                 }\r
1979                                         }\r
1980                                 } else\r
1981                                         e.innerHTML = h;\r
1982 \r
1983                                 return h;\r
1984                         });\r
1985                 },\r
1986 \r
1987                 processHTML : function(h) {\r
1988                         var t = this, s = t.settings;\r
1989 \r
1990                         if (!s.process_html)\r
1991                                 return h;\r
1992 \r
1993                         // Convert strong and em to b and i in FF since it can't handle them\r
1994                         if (tinymce.isGecko) {\r
1995                                 h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');\r
1996                                 h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');\r
1997                         } else if (isIE)\r
1998                                 h = h.replace(/&apos;/g, '&#39;'); // IE can't handle apos\r
1999 \r
2000                         // Fix some issues\r
2001                         h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open\r
2002 \r
2003                         // Store away src and href in mce_src and mce_href since browsers mess them up\r
2004                         if (s.keep_values) {\r
2005                                 // Wrap scripts and styles in comments for serialization purposes\r
2006                                 if (/<script|style/.test(h)) {\r
2007                                         function trim(s) {\r
2008                                                 // Remove prefix and suffix code for element\r
2009                                                 s = s.replace(/^[\r\n]*|[\r\n]*$/g, '');\r
2010                                                 s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<\[CDATA\[|<!--|<\[CDATA\[)[\r\n]*/g, '');\r
2011                                                 s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->)\s*$/g, '');\r
2012 \r
2013                                                 return s;\r
2014                                         };\r
2015 \r
2016                                         // Preserve script elements\r
2017                                         h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g, function(v, a, b) {\r
2018                                                 // Remove prefix and suffix code for script element\r
2019                                                 b = trim(b);\r
2020 \r
2021                                                 // Force type attribute\r
2022                                                 if (!a)\r
2023                                                         a = ' type="text/javascript"';\r
2024 \r
2025                                                 // Wrap contents in a comment\r
2026                                                 if (b)\r
2027                                                         b = '<!--\n' + b + '\n// -->';\r
2028 \r
2029                                                 // Output fake element\r
2030                                                 return '<mce:script' + a + '>' + b + '</mce:script>';\r
2031                                         });\r
2032 \r
2033                                         // Preserve style elements\r
2034                                         h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g, function(v, a, b) {\r
2035                                                 b = trim(b);\r
2036                                                 return '<mce:style' + a + '><!--\n' + b + '\n--></mce:style><style' + a + ' mce_bogus="1">' + b + '</style>';\r
2037                                         });\r
2038                                 }\r
2039 \r
2040                                 // Process all tags with src, href or style\r
2041                                 h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) {\r
2042                                         function handle(m, b, c) {\r
2043                                                 var u = c;\r
2044 \r
2045                                                 // Tag already got a mce_ version\r
2046                                                 if (a.indexOf('mce_' + b) != -1)\r
2047                                                         return m;\r
2048 \r
2049                                                 if (b == 'style') {\r
2050                                                         // Why did I need this one?\r
2051                                                         //if (isIE)\r
2052                                                         //      u = t.serializeStyle(t.parseStyle(u));\r
2053 \r
2054                                                         // No mce_style for elements with these since they might get resized by the user\r
2055                                                         if (t._isRes(c))\r
2056                                                                 return m;\r
2057 \r
2058                                                         if (s.hex_colors) {\r
2059                                                                 u = u.replace(/rgb\([^\)]+\)/g, function(v) {\r
2060                                                                         return t.toHex(v);\r
2061                                                                 });\r
2062                                                         }\r
2063 \r
2064                                                         if (s.url_converter) {\r
2065                                                                 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {\r
2066                                                                         return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';\r
2067                                                                 });\r
2068                                                         }\r
2069                                                 } else if (b != 'coords' && b != 'shape') {\r
2070                                                         if (s.url_converter)\r
2071                                                                 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));\r
2072                                                 }\r
2073 \r
2074                                                 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"';\r
2075                                         };\r
2076 \r
2077                                         a = a.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi, handle); // W3C\r
2078                                         a = a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi, handle); // W3C\r
2079 \r
2080                                         return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi, handle); // IE\r
2081                                 });\r
2082                         }\r
2083 \r
2084                         return h;\r
2085                 },\r
2086 \r
2087                 getOuterHTML : function(e) {\r
2088                         var d;\r
2089 \r
2090                         e = this.get(e);\r
2091 \r
2092                         if (!e)\r
2093                                 return null;\r
2094 \r
2095                         if (isIE)\r
2096                                 return e.outerHTML;\r
2097 \r
2098                         d = (e.ownerDocument || this.doc).createElement("body");\r
2099                         d.appendChild(e.cloneNode(true));\r
2100 \r
2101                         return d.innerHTML;\r
2102                 },\r
2103 \r
2104                 setOuterHTML : function(e, h, d) {\r
2105                         var t = this;\r
2106 \r
2107                         return this.run(e, function(e) {\r
2108                                 var n, tp;\r
2109 \r
2110                                 e = t.get(e);\r
2111                                 d = d || e.ownerDocument || t.doc;\r
2112 \r
2113                                 if (isIE && e.nodeType == 1)\r
2114                                         e.outerHTML = h;\r
2115                                 else {\r
2116                                         tp = d.createElement("body");\r
2117                                         tp.innerHTML = h;\r
2118 \r
2119                                         n = tp.lastChild;\r
2120                                         while (n) {\r
2121                                                 t.insertAfter(n.cloneNode(true), e);\r
2122                                                 n = n.previousSibling;\r
2123                                         }\r
2124 \r
2125                                         t.remove(e);\r
2126                                 }\r
2127                         });\r
2128                 },\r
2129 \r
2130                 decode : function(s) {\r
2131                         var e;\r
2132 \r
2133                         // Look for entities to decode\r
2134                         if (/&[^;]+;/.test(s)) {\r
2135                                 // Decode the entities using a div element not super efficient but less code\r
2136                                 e = this.doc.createElement("div");\r
2137                                 e.innerHTML = s;\r
2138 \r
2139                                 return !e.firstChild ? s : e.firstChild.nodeValue;\r
2140                         }\r
2141 \r
2142                         return s;\r
2143                 },\r
2144 \r
2145                 encode : function(s) {\r
2146                         return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) {\r
2147                                 switch (c) {\r
2148                                         case '&':\r
2149                                                 return '&amp;';\r
2150 \r
2151                                         case '"':\r
2152                                                 return '&quot;';\r
2153 \r
2154                                         case '<':\r
2155                                                 return '&lt;';\r
2156 \r
2157                                         case '>':\r
2158                                                 return '&gt;';\r
2159                                 }\r
2160 \r
2161                                 return c;\r
2162                         }) : s;\r
2163                 },\r
2164 \r
2165                 // #if !jquery\r
2166 \r
2167                 insertAfter : function(n, r) {\r
2168                         var t = this;\r
2169 \r
2170                         r = t.get(r);\r
2171 \r
2172                         return this.run(n, function(n) {\r
2173                                 var p, ns;\r
2174 \r
2175                                 p = r.parentNode;\r
2176                                 ns = r.nextSibling;\r
2177 \r
2178                                 if (ns)\r
2179                                         p.insertBefore(n, ns);\r
2180                                 else\r
2181                                         p.appendChild(n);\r
2182 \r
2183                                 return n;\r
2184                         });\r
2185                 },\r
2186 \r
2187                 // #endif\r
2188 \r
2189                 isBlock : function(n) {\r
2190                         if (n.nodeType && n.nodeType !== 1)\r
2191                                 return false;\r
2192 \r
2193                         n = n.nodeName || n;\r
2194 \r
2195                         return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);\r
2196                 },\r
2197 \r
2198                 // #if !jquery\r
2199 \r
2200                 replace : function(n, o, k) {\r
2201                         if (is(o, 'array'))\r
2202                                 n = n.cloneNode(true);\r
2203 \r
2204                         return this.run(o, function(o) {\r
2205                                 if (k) {\r
2206                                         each(o.childNodes, function(c) {\r
2207                                                 n.appendChild(c.cloneNode(true));\r
2208                                         });\r
2209                                 }\r
2210 \r
2211                                 // Fix IE psuedo leak for elements since replacing elements if fairly common\r
2212                                 // Will break parentNode for some unknown reason\r
2213         /*                      if (isIE && o.nodeType === 1) {\r
2214                                         o.parentNode.insertBefore(n, o);\r
2215                                         o.outerHTML = '';\r
2216                                         return n;\r
2217                                 }*/\r
2218 \r
2219                                 return o.parentNode.replaceChild(n, o);\r
2220                         });\r
2221                 },\r
2222 \r
2223                 // #endif\r
2224 \r
2225                 toHex : function(s) {\r
2226                         var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);\r
2227 \r
2228                         function hex(s) {\r
2229                                 s = parseInt(s).toString(16);\r
2230 \r
2231                                 return s.length > 1 ? s : '0' + s; // 0 -> 00\r
2232                         };\r
2233 \r
2234                         if (c) {\r
2235                                 s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]);\r
2236 \r
2237                                 return s;\r
2238                         }\r
2239 \r
2240                         return s;\r
2241                 },\r
2242 \r
2243                 getClasses : function() {\r
2244                         var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov;\r
2245 \r
2246                         if (t.classes)\r
2247                                 return t.classes;\r
2248 \r
2249                         function addClasses(s) {\r
2250                                 // IE style imports\r
2251                                 each(s.imports, function(r) {\r
2252                                         addClasses(r);\r
2253                                 });\r
2254 \r
2255                                 each(s.cssRules || s.rules, function(r) {\r
2256                                         // Real type or fake it on IE\r
2257                                         switch (r.type || 1) {\r
2258                                                 // Rule\r
2259                                                 case 1:\r
2260                                                         if (r.selectorText) {\r
2261                                                                 each(r.selectorText.split(','), function(v) {\r
2262                                                                         v = v.replace(/^\s*|\s*$|^\s\./g, "");\r
2263 \r
2264                                                                         // Is internal or it doesn't contain a class\r
2265                                                                         if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v))\r
2266                                                                                 return;\r
2267 \r
2268                                                                         // Remove everything but class name\r
2269                                                                         ov = v;\r
2270                                                                         v = v.replace(/.*\.([a-z0-9_\-]+).*/i, '$1');\r
2271 \r
2272                                                                         // Filter classes\r
2273                                                                         if (f && !(v = f(v, ov)))\r
2274                                                                                 return;\r
2275 \r
2276                                                                         if (!lo[v]) {\r
2277                                                                                 cl.push({'class' : v});\r
2278                                                                                 lo[v] = 1;\r
2279                                                                         }\r
2280                                                                 });\r
2281                                                         }\r
2282                                                         break;\r
2283 \r
2284                                                 // Import\r
2285                                                 case 3:\r
2286                                                         addClasses(r.styleSheet);\r
2287                                                         break;\r
2288                                         }\r
2289                                 });\r
2290                         };\r
2291 \r
2292                         try {\r
2293                                 each(t.doc.styleSheets, addClasses);\r
2294                         } catch (ex) {\r
2295                                 // Ignore\r
2296                         }\r
2297 \r
2298                         if (cl.length > 0)\r
2299                                 t.classes = cl;\r
2300 \r
2301                         return cl;\r
2302                 },\r
2303 \r
2304                 run : function(e, f, s) {\r
2305                         var t = this, o;\r
2306 \r
2307                         if (t.doc && typeof(e) === 'string')\r
2308                                 e = t.doc.getElementById(e);\r
2309 \r
2310                         if (!e)\r
2311                                 return false;\r
2312 \r
2313                         s = s || this;\r
2314                         if (!e.nodeType && (e.length || e.length === 0)) {\r
2315                                 o = [];\r
2316 \r
2317                                 each(e, function(e, i) {\r
2318                                         if (e) {\r
2319                                                 if (typeof(e) == 'string')\r
2320                                                         e = t.doc.getElementById(e);\r
2321 \r
2322                                                 o.push(f.call(s, e, i));\r
2323                                         }\r
2324                                 });\r
2325 \r
2326                                 return o;\r
2327                         }\r
2328 \r
2329                         return f.call(s, e);\r
2330                 },\r
2331 \r
2332                 getAttribs : function(n) {\r
2333                         var o;\r
2334 \r
2335                         n = this.get(n);\r
2336 \r
2337                         if (!n)\r
2338                                 return [];\r
2339 \r
2340                         if (isIE) {\r
2341                                 o = [];\r
2342 \r
2343                                 // Object will throw exception in IE\r
2344                                 if (n.nodeName == 'OBJECT')\r
2345                                         return n.attributes;\r
2346 \r
2347                                 // It's crazy that this is faster in IE but it's because it returns all attributes all the time\r
2348                                 n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
2349                                         o.push({specified : 1, nodeName : b});\r
2350                                 });\r
2351 \r
2352                                 return o;\r
2353                         }\r
2354 \r
2355                         return n.attributes;\r
2356                 },\r
2357 \r
2358                 destroy : function(s) {\r
2359                         var t = this;\r
2360 \r
2361                         t.win = t.doc = t.root = null;\r
2362 \r
2363                         // Manual destroy then remove unload handler\r
2364                         if (!s)\r
2365                                 tinymce.removeUnload(t.destroy);\r
2366                 },\r
2367 \r
2368                 _isRes : function(c) {\r
2369                         // Is live resizble element\r
2370                         return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c);\r
2371                 }\r
2372 \r
2373                 /*\r
2374                 walk : function(n, f, s) {\r
2375                         var d = this.doc, w;\r
2376 \r
2377                         if (d.createTreeWalker) {\r
2378                                 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
2379 \r
2380                                 while ((n = w.nextNode()) != null)\r
2381                                         f.call(s || this, n);\r
2382                         } else\r
2383                                 tinymce.walk(n, f, 'childNodes', s);\r
2384                 }\r
2385                 */\r
2386 \r
2387                 /*\r
2388                 toRGB : function(s) {\r
2389                         var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s);\r
2390 \r
2391                         if (c) {\r
2392                                 // #FFF -> #FFFFFF\r
2393                                 if (!is(c[3]))\r
2394                                         c[3] = c[2] = c[1];\r
2395 \r
2396                                 return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")";\r
2397                         }\r
2398 \r
2399                         return s;\r
2400                 }\r
2401                 */\r
2402 \r
2403                 });\r
2404 \r
2405         // Setup page DOM\r
2406         tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});\r
2407 })();\r
2408 \r
2409 /* file:jscripts/tiny_mce/classes/dom/Event.js */\r
2410 \r
2411 (function() {\r
2412         // Shorten names\r
2413         var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
2414 \r
2415         tinymce.create('static tinymce.dom.Event', {\r
2416                 inits : [],\r
2417                 events : [],\r
2418 \r
2419                 // #if !jquery\r
2420 \r
2421                 add : function(o, n, f, s) {\r
2422                         var cb, t = this, el = t.events, r;\r
2423 \r
2424                         // Handle array\r
2425                         if (o && o instanceof Array) {\r
2426                                 r = [];\r
2427 \r
2428                                 each(o, function(o) {\r
2429                                         o = DOM.get(o);\r
2430                                         r.push(t.add(o, n, f, s));\r
2431                                 });\r
2432 \r
2433                                 return r;\r
2434                         }\r
2435 \r
2436                         o = DOM.get(o);\r
2437 \r
2438                         if (!o)\r
2439                                 return;\r
2440 \r
2441                         // Setup event callback\r
2442                         cb = function(e) {\r
2443                                 e = e || window.event;\r
2444 \r
2445                                 // Patch in target in IE it's W3C valid\r
2446                                 if (e && !e.target && isIE)\r
2447                                         e.target = e.srcElement;\r
2448 \r
2449                                 if (!s)\r
2450                                         return f(e);\r
2451 \r
2452                                 return f.call(s, e);\r
2453                         };\r
2454 \r
2455                         if (n == 'unload') {\r
2456                                 tinymce.unloads.unshift({func : cb});\r
2457                                 return cb;\r
2458                         }\r
2459 \r
2460                         if (n == 'init') {\r
2461                                 if (t.domLoaded)\r
2462                                         cb();\r
2463                                 else\r
2464                                         t.inits.push(cb);\r
2465 \r
2466                                 return cb;\r
2467                         }\r
2468 \r
2469                         // Store away listener reference\r
2470                         el.push({\r
2471                                 obj : o,\r
2472                                 name : n,\r
2473                                 func : f,\r
2474                                 cfunc : cb,\r
2475                                 scope : s\r
2476                         });\r
2477 \r
2478                         t._add(o, n, cb);\r
2479 \r
2480                         return f;\r
2481                 },\r
2482 \r
2483                 remove : function(o, n, f) {\r
2484                         var t = this, a = t.events, s = false, r;\r
2485 \r
2486                         // Handle array\r
2487                         if (o && o instanceof Array) {\r
2488                                 r = [];\r
2489 \r
2490                                 each(o, function(o) {\r
2491                                         o = DOM.get(o);\r
2492                                         r.push(t.remove(o, n, f));\r
2493                                 });\r
2494 \r
2495                                 return r;\r
2496                         }\r
2497 \r
2498                         o = DOM.get(o);\r
2499 \r
2500                         each(a, function(e, i) {\r
2501                                 if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {\r
2502                                         a.splice(i, 1);\r
2503                                         t._remove(o, n, e.cfunc);\r
2504                                         s = true;\r
2505                                         return false;\r
2506                                 }\r
2507                         });\r
2508 \r
2509                         return s;\r
2510                 },\r
2511 \r
2512                 clear : function(o) {\r
2513                         var t = this, a = t.events, i, e;\r
2514 \r
2515                         if (o) {\r
2516                                 o = DOM.get(o);\r
2517 \r
2518                                 for (i = a.length - 1; i >= 0; i--) {\r
2519                                         e = a[i];\r
2520 \r
2521                                         if (e.obj === o) {\r
2522                                                 t._remove(e.obj, e.name, e.cfunc);\r
2523                                                 e.obj = e.cfunc = null;\r
2524                                                 a.splice(i, 1);\r
2525                                         }\r
2526                                 }\r
2527                         }\r
2528                 },\r
2529 \r
2530                 // #endif\r
2531 \r
2532                 cancel : function(e) {\r
2533                         if (!e)\r
2534                                 return false;\r
2535 \r
2536                         this.stop(e);\r
2537                         return this.prevent(e);\r
2538                 },\r
2539 \r
2540                 stop : function(e) {\r
2541                         if (e.stopPropagation)\r
2542                                 e.stopPropagation();\r
2543                         else\r
2544                                 e.cancelBubble = true;\r
2545 \r
2546                         return false;\r
2547                 },\r
2548 \r
2549                 prevent : function(e) {\r
2550                         if (e.preventDefault)\r
2551                                 e.preventDefault();\r
2552                         else\r
2553                                 e.returnValue = false;\r
2554 \r
2555                         return false;\r
2556                 },\r
2557 \r
2558                 _unload : function() {\r
2559                         var t = Event;\r
2560 \r
2561                         each(t.events, function(e, i) {\r
2562                                 t._remove(e.obj, e.name, e.cfunc);\r
2563                                 e.obj = e.cfunc = null;\r
2564                         });\r
2565 \r
2566                         t.events = [];\r
2567                         t = null;\r
2568                 },\r
2569 \r
2570                 _add : function(o, n, f) {\r
2571                         if (o.attachEvent)\r
2572                                 o.attachEvent('on' + n, f);\r
2573                         else if (o.addEventListener)\r
2574                                 o.addEventListener(n, f, false);\r
2575                         else\r
2576                                 o['on' + n] = f;\r
2577                 },\r
2578 \r
2579                 _remove : function(o, n, f) {\r
2580                         if (o) {\r
2581                                 try {\r
2582                                         if (o.detachEvent)\r
2583                                                 o.detachEvent('on' + n, f);\r
2584                                         else if (o.removeEventListener)\r
2585                                                 o.removeEventListener(n, f, false);\r
2586                                         else\r
2587                                                 o['on' + n] = null;\r
2588                                 } catch (ex) {\r
2589                                         // Might fail with permission denined on IE so we just ignore that\r
2590                                 }\r
2591                         }\r
2592                 },\r
2593 \r
2594                 _pageInit : function() {\r
2595                         var e = Event;\r
2596 \r
2597                         e._remove(window, 'DOMContentLoaded', e._pageInit);\r
2598                         e.domLoaded = true;\r
2599 \r
2600                         each(e.inits, function(c) {\r
2601                                 c();\r
2602                         });\r
2603 \r
2604                         e.inits = [];\r
2605                 },\r
2606 \r
2607                 _wait : function() {\r
2608                         var t;\r
2609 \r
2610                         // No need since the document is already loaded\r
2611                         if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) {\r
2612                                 Event.domLoaded = 1;\r
2613                                 return;\r
2614                         }\r
2615 \r
2616                         if (isIE && document.location.protocol != 'https:') {\r
2617                                 // Fake DOMContentLoaded on IE\r
2618                                 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');\r
2619                                 DOM.get("__ie_onload").onreadystatechange = function() {\r
2620                                         if (this.readyState == "complete") {\r
2621                                                 Event._pageInit();\r
2622                                                 DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak\r
2623                                         }\r
2624                                 };\r
2625                         } else {\r
2626                                 Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);\r
2627 \r
2628                                 if (isIE || isWebKit) {\r
2629                                         t = setInterval(function() {\r
2630                                                 if (/loaded|complete/.test(document.readyState)) {\r
2631                                                         clearInterval(t);\r
2632                                                         Event._pageInit();\r
2633                                                 }\r
2634                                         }, 10);\r
2635                                 }\r
2636                         }\r
2637                 }\r
2638 \r
2639                 });\r
2640 \r
2641         // Shorten name\r
2642         Event = tinymce.dom.Event;\r
2643 \r
2644         // Dispatch DOM content loaded event for IE and Safari\r
2645         Event._wait();\r
2646         tinymce.addUnload(Event._unload);\r
2647 })();\r
2648 \r
2649 /* file:jscripts/tiny_mce/classes/dom/Element.js */\r
2650 \r
2651 (function() {\r
2652         var each = tinymce.each;\r
2653 \r
2654         tinymce.create('tinymce.dom.Element', {\r
2655                 Element : function(id, s) {\r
2656                         var t = this, dom, el;\r
2657 \r
2658                         s = s || {};\r
2659                         t.id = id;\r
2660                         t.dom = dom = s.dom || tinymce.DOM;\r
2661                         t.settings = s;\r
2662 \r
2663                         // Only IE leaks DOM references, this is a lot faster\r
2664                         if (!tinymce.isIE)\r
2665                                 el = t.dom.get(t.id);\r
2666 \r
2667                         each([\r
2668                                 'getPos',\r
2669                                 'getRect',\r
2670                                 'getParent',\r
2671                                 'add',\r
2672                                 'setStyle',\r
2673                                 'getStyle',\r
2674                                 'setStyles',\r
2675                                 'setAttrib',\r
2676                                 'setAttribs',\r
2677                                 'getAttrib',\r
2678                                 'addClass',\r
2679                                 'removeClass',\r
2680                                 'hasClass',\r
2681                                 'getOuterHTML',\r
2682                                 'setOuterHTML',\r
2683                                 'remove',\r
2684                                 'show',\r
2685                                 'hide',\r
2686                                 'isHidden',\r
2687                                 'setHTML',\r
2688                                 'get'\r
2689                         ], function(k) {\r
2690                                 t[k] = function() {\r
2691                                         var a = arguments, o;\r
2692 \r
2693                                         // Opera fails\r
2694                                         if (tinymce.isOpera) {\r
2695                                                 a = [id];\r
2696 \r
2697                                                 each(arguments, function(v) {\r
2698                                                         a.push(v);\r
2699                                                 });\r
2700                                         } else\r
2701                                                 Array.prototype.unshift.call(a, el || id);\r
2702 \r
2703                                         o = dom[k].apply(dom, a);\r
2704                                         t.update(k);\r
2705 \r
2706                                         return o;\r
2707                                 };\r
2708                         });\r
2709                 },\r
2710 \r
2711                 on : function(n, f, s) {\r
2712                         return tinymce.dom.Event.add(this.id, n, f, s);\r
2713                 },\r
2714 \r
2715                 getXY : function() {\r
2716                         return {\r
2717                                 x : parseInt(this.getStyle('left')),\r
2718                                 y : parseInt(this.getStyle('top'))\r
2719                         };\r
2720                 },\r
2721 \r
2722                 getSize : function() {\r
2723                         var n = this.dom.get(this.id);\r
2724 \r
2725                         return {\r
2726                                 w : parseInt(this.getStyle('width') || n.clientWidth),\r
2727                                 h : parseInt(this.getStyle('height') || n.clientHeight)\r
2728                         };\r
2729                 },\r
2730 \r
2731                 moveTo : function(x, y) {\r
2732                         this.setStyles({left : x, top : y});\r
2733                 },\r
2734 \r
2735                 moveBy : function(x, y) {\r
2736                         var p = this.getXY();\r
2737 \r
2738                         this.moveTo(p.x + x, p.y + y);\r
2739                 },\r
2740 \r
2741                 resizeTo : function(w, h) {\r
2742                         this.setStyles({width : w, height : h});\r
2743                 },\r
2744 \r
2745                 resizeBy : function(w, h) {\r
2746                         var s = this.getSize();\r
2747 \r
2748                         this.resizeTo(s.w + w, s.h + h);\r
2749                 },\r
2750 \r
2751                 update : function(k) {\r
2752                         var t = this, b, dom = t.dom;\r
2753 \r
2754                         if (tinymce.isIE6 && t.settings.blocker) {\r
2755                                 k = k || '';\r
2756 \r
2757                                 // Ignore getters\r
2758                                 if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0)\r
2759                                         return;\r
2760 \r
2761                                 // Remove blocker on remove\r
2762                                 if (k == 'remove') {\r
2763                                         dom.remove(t.blocker);\r
2764                                         return;\r
2765                                 }\r
2766 \r
2767                                 if (!t.blocker) {\r
2768                                         t.blocker = dom.uniqueId();\r
2769                                         b = dom.add(t.settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'});\r
2770                                         dom.setStyle(b, 'opacity', 0);\r
2771                                 } else\r
2772                                         b = dom.get(t.blocker);\r
2773 \r
2774                                 dom.setStyle(b, 'left', t.getStyle('left', 1));\r
2775                                 dom.setStyle(b, 'top', t.getStyle('top', 1));\r
2776                                 dom.setStyle(b, 'width', t.getStyle('width', 1));\r
2777                                 dom.setStyle(b, 'height', t.getStyle('height', 1));\r
2778                                 dom.setStyle(b, 'display', t.getStyle('display', 1));\r
2779                                 dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);\r
2780                         }\r
2781                 }\r
2782 \r
2783                 });\r
2784 })();\r
2785 \r
2786 /* file:jscripts/tiny_mce/classes/dom/Selection.js */\r
2787 \r
2788 (function() {\r
2789         function trimNl(s) {\r
2790                 return s.replace(/[\n\r]+/g, '');\r
2791         };\r
2792 \r
2793         // Shorten names\r
2794         var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;\r
2795 \r
2796         tinymce.create('tinymce.dom.Selection', {\r
2797                 Selection : function(dom, win, serializer) {\r
2798                         var t = this;\r
2799 \r
2800                         t.dom = dom;\r
2801                         t.win = win;\r
2802                         t.serializer = serializer;\r
2803 \r
2804                         // Prevent leaks\r
2805                         tinymce.addUnload(t.destroy, t);\r
2806                 },\r
2807 \r
2808                 getContent : function(s) {\r
2809                         var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;\r
2810 \r
2811                         s = s || {};\r
2812                         wb = wa = '';\r
2813                         s.get = true;\r
2814                         s.format = s.format || 'html';\r
2815 \r
2816                         if (s.format == 'text')\r
2817                                 return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));\r
2818 \r
2819                         if (r.cloneContents) {\r
2820                                 n = r.cloneContents();\r
2821 \r
2822                                 if (n)\r
2823                                         e.appendChild(n);\r
2824                         } else if (is(r.item) || is(r.htmlText))\r
2825                                 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;\r
2826                         else\r
2827                                 e.innerHTML = r.toString();\r
2828 \r
2829                         // Keep whitespace before and after\r
2830                         if (/^\s/.test(e.innerHTML))\r
2831                                 wb = ' ';\r
2832 \r
2833                         if (/\s+$/.test(e.innerHTML))\r
2834                                 wa = ' ';\r
2835 \r
2836                         s.getInner = true;\r
2837 \r
2838                         return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
2839                 },\r
2840 \r
2841                 setContent : function(h, s) {\r
2842                         var t = this, r = t.getRng(), d = t.win.document;\r
2843 \r
2844                         s = s || {format : 'html'};\r
2845                         s.set = true;\r
2846                         h = t.dom.processHTML(h);\r
2847 \r
2848                         if (r.insertNode) {\r
2849                                 // Gecko has a bug where if you insert &nbsp; using InsertHTML it will insert a space instead\r
2850                                 // So we simply check if the input is HTML or text and then insert text using the insertNode method\r
2851                                 if (tinymce.isGecko && h.indexOf('<') == -1) {\r
2852                                         r.deleteContents();\r
2853                                         r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>'));\r
2854                                         t.select(t.dom.get('__caret'));\r
2855                                         t.getRng().deleteContents();\r
2856                                         return;\r
2857                                 }\r
2858 \r
2859                                 // Use insert HTML if it exists (places cursor after content)\r
2860                                 try {\r
2861                                         // This might fail with an exception see bug #1893736\r
2862                                         if (d.queryCommandEnabled('InsertHTML'))\r
2863                                                 return d.execCommand('InsertHTML', false, h);\r
2864                                 } catch (ex) {\r
2865                                         // Use old school method\r
2866                                         r.deleteContents();\r
2867                                         r.insertNode(t.getRng().createContextualFragment(h));\r
2868                                 }\r
2869                         } else {\r
2870                                 if (r.item) {\r
2871                                         // Delete content and get caret text selection\r
2872                                         d.execCommand('Delete', false, null);\r
2873                                         r = t.getRng();\r
2874                                 }\r
2875 \r
2876                                 r.pasteHTML(h);\r
2877                         }\r
2878                 },\r
2879 \r
2880                 getStart : function() {\r
2881                         var t = this, r = t.getRng(), e;\r
2882 \r
2883                         if (isIE) {\r
2884                                 if (r.item)\r
2885                                         return r.item(0);\r
2886 \r
2887                                 r = r.duplicate();\r
2888                                 r.collapse(1);\r
2889                                 e = r.parentElement();\r
2890 \r
2891                                 if (e && e.nodeName == 'BODY')\r
2892                                         return e.firstChild;\r
2893 \r
2894                                 return e;\r
2895                         } else {\r
2896                                 e = r.startContainer;\r
2897 \r
2898                                 if (e.nodeName == 'BODY')\r
2899                                         return e.firstChild;\r
2900 \r
2901                                 return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
2902                         }\r
2903                 },\r
2904 \r
2905                 getEnd : function() {\r
2906                         var t = this, r = t.getRng(), e;\r
2907 \r
2908                         if (isIE) {\r
2909                                 if (r.item)\r
2910                                         return r.item(0);\r
2911 \r
2912                                 r = r.duplicate();\r
2913                                 r.collapse(0);\r
2914                                 e = r.parentElement();\r
2915 \r
2916                                 if (e && e.nodeName == 'BODY')\r
2917                                         return e.lastChild;\r
2918 \r
2919                                 return e;\r
2920                         } else {\r
2921                                 e = r.endContainer;\r
2922 \r
2923                                 if (e.nodeName == 'BODY')\r
2924                                         return e.lastChild;\r
2925 \r
2926                                 return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
2927                         }\r
2928                 },\r
2929 \r
2930                 getBookmark : function(si) {\r
2931                         var t = this, r = t.getRng(), tr, sx, sy, vp = t.dom.getViewPort(t.win), e, sp, bp, le, c = -0xFFFFFF, s, ro = t.dom.getRoot(), wb = 0, wa = 0, nv;\r
2932                         sx = vp.x;\r
2933                         sy = vp.y;\r
2934 \r
2935                         // Simple bookmark fast but not as persistent\r
2936                         if (si == 'simple')\r
2937                                 return {rng : r, scrollX : sx, scrollY : sy};\r
2938 \r
2939                         // Handle IE\r
2940                         if (isIE) {\r
2941                                 // Control selection\r
2942                                 if (r.item) {\r
2943                                         e = r.item(0);\r
2944 \r
2945                                         each(t.dom.select(e.nodeName), function(n, i) {\r
2946                                                 if (e == n) {\r
2947                                                         sp = i;\r
2948                                                         return false;\r
2949                                                 }\r
2950                                         });\r
2951 \r
2952                                         return {\r
2953                                                 tag : e.nodeName,\r
2954                                                 index : sp,\r
2955                                                 scrollX : sx,\r
2956                                                 scrollY : sy\r
2957                                         };\r
2958                                 }\r
2959 \r
2960                                 // Text selection\r
2961                                 tr = t.dom.doc.body.createTextRange();\r
2962                                 tr.moveToElementText(ro);\r
2963                                 tr.collapse(true);\r
2964                                 bp = Math.abs(tr.move('character', c));\r
2965 \r
2966                                 tr = r.duplicate();\r
2967                                 tr.collapse(true);\r
2968                                 sp = Math.abs(tr.move('character', c));\r
2969 \r
2970                                 tr = r.duplicate();\r
2971                                 tr.collapse(false);\r
2972                                 le = Math.abs(tr.move('character', c)) - sp;\r
2973 \r
2974                                 return {\r
2975                                         start : sp - bp,\r
2976                                         length : le,\r
2977                                         scrollX : sx,\r
2978                                         scrollY : sy\r
2979                                 };\r
2980                         }\r
2981 \r
2982                         // Handle W3C\r
2983                         e = t.getNode();\r
2984                         s = t.getSel();\r
2985 \r
2986                         if (!s)\r
2987                                 return null;\r
2988 \r
2989                         // Image selection\r
2990                         if (e && e.nodeName == 'IMG') {\r
2991                                 return {\r
2992                                         scrollX : sx,\r
2993                                         scrollY : sy\r
2994                                 };\r
2995                         }\r
2996 \r
2997                         // Text selection\r
2998 \r
2999                         function getPos(r, sn, en) {\r
3000                                 var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};\r
3001 \r
3002                                 while ((n = w.nextNode()) != null) {\r
3003                                         if (n == sn)\r
3004                                                 d.start = p;\r
3005 \r
3006                                         if (n == en) {\r
3007                                                 d.end = p;\r
3008                                                 return d;\r
3009                                         }\r
3010 \r
3011                                         p += trimNl(n.nodeValue || '').length;\r
3012                                 }\r
3013 \r
3014                                 return null;\r
3015                         };\r
3016 \r
3017                         // Caret or selection\r
3018                         if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) {\r
3019                                 e = getPos(ro, s.anchorNode, s.focusNode);\r
3020 \r
3021                                 if (!e)\r
3022                                         return {scrollX : sx, scrollY : sy};\r
3023 \r
3024                                 // Count whitespace before\r
3025                                 trimNl(s.anchorNode.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;});\r
3026 \r
3027                                 return {\r
3028                                         start : Math.max(e.start + s.anchorOffset - wb, 0),\r
3029                                         end : Math.max(e.end + s.focusOffset - wb, 0),\r
3030                                         scrollX : sx,\r
3031                                         scrollY : sy,\r
3032                                         beg : s.anchorOffset - wb == 0\r
3033                                 };\r
3034                         } else {\r
3035                                 e = getPos(ro, r.startContainer, r.endContainer);\r
3036 \r
3037                                 // Count whitespace before start and end container\r
3038                                 //(r.startContainer.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;});\r
3039                                 //(r.endContainer.nodeValue || '').replace(/^\s+/, function(a) {wa = a.length;});\r
3040 \r
3041                                 if (!e)\r
3042                                         return {scrollX : sx, scrollY : sy};\r
3043 \r
3044                                 return {\r
3045                                         start : Math.max(e.start + r.startOffset - wb, 0),\r
3046                                         end : Math.max(e.end + r.endOffset - wa, 0),\r
3047                                         scrollX : sx,\r
3048                                         scrollY : sy,\r
3049                                         beg : r.startOffset - wb == 0\r
3050                                 };\r
3051                         }\r
3052                 },\r
3053 \r
3054                 moveToBookmark : function(b) {\r
3055                         var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd, nvl, nv;\r
3056 \r
3057                         function getPos(r, sp, ep) {\r
3058                                 var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}, o, v, wa, wb;\r
3059 \r
3060                                 while ((n = w.nextNode()) != null) {\r
3061                                         wa = wb = 0;\r
3062 \r
3063                                         nv = n.nodeValue || '';\r
3064                                         //nv.replace(/^\s+[^\s]/, function(a) {wb = a.length - 1;});\r
3065                                         //nv.replace(/[^\s]\s+$/, function(a) {wa = a.length - 1;});\r
3066 \r
3067                                         nvl = trimNl(nv).length;\r
3068                                         p += nvl;\r
3069 \r
3070                                         if (p >= sp && !d.startNode) {\r
3071                                                 o = sp - (p - nvl);\r
3072 \r
3073                                                 // Fix for odd quirk in FF\r
3074                                                 if (b.beg && o >= nvl)\r
3075                                                         continue;\r
3076 \r
3077                                                 d.startNode = n;\r
3078                                                 d.startOffset = o + wb;\r
3079                                         }\r
3080 \r
3081                                         if (p >= ep) {\r
3082                                                 d.endNode = n;\r
3083                                                 d.endOffset = ep - (p - nvl) + wb;\r
3084                                                 return d;\r
3085                                         }\r
3086                                 }\r
3087 \r
3088                                 return null;\r
3089                         };\r
3090 \r
3091                         if (!b)\r
3092                                 return false;\r
3093 \r
3094                         t.win.scrollTo(b.scrollX, b.scrollY);\r
3095 \r
3096                         // Handle explorer\r
3097                         if (isIE) {\r
3098                                 // Handle simple\r
3099                                 if (r = b.rng) {\r
3100                                         try {\r
3101                                                 r.select();\r
3102                                         } catch (ex) {\r
3103                                                 // Ignore\r
3104                                         }\r
3105 \r
3106                                         return true;\r
3107                                 }\r
3108 \r
3109                                 t.win.focus();\r
3110 \r
3111                                 // Handle control bookmark\r
3112                                 if (b.tag) {\r
3113                                         r = ro.createControlRange();\r
3114 \r
3115                                         each(t.dom.select(b.tag), function(n, i) {\r
3116                                                 if (i == b.index)\r
3117                                                         r.addElement(n);\r
3118                                         });\r
3119                                 } else {\r
3120                                         // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs\r
3121                                         try {\r
3122                                                 // Incorrect bookmark\r
3123                                                 if (b.start < 0)\r
3124                                                         return true;\r
3125 \r
3126                                                 r = s.createRange();\r
3127                                                 r.moveToElementText(ro);\r
3128                                                 r.collapse(true);\r
3129                                                 r.moveStart('character', b.start);\r
3130                                                 r.moveEnd('character', b.length);\r
3131                                         } catch (ex2) {\r
3132                                                 return true;\r
3133                                         }\r
3134                                 }\r
3135 \r
3136                                 try {\r
3137                                         r.select();\r
3138                                 } catch (ex) {\r
3139                                         // Needed for some odd IE bug #1843306\r
3140                                 }\r
3141 \r
3142                                 return true;\r
3143                         }\r
3144 \r
3145                         // Handle W3C\r
3146                         if (!s)\r
3147                                 return false;\r
3148 \r
3149                         // Handle simple\r
3150                         if (b.rng) {\r
3151                                 s.removeAllRanges();\r
3152                                 s.addRange(b.rng);\r
3153                         } else {\r
3154                                 if (is(b.start) && is(b.end)) {\r
3155                                         try {\r
3156                                                 sd = getPos(ro, b.start, b.end);\r
3157 \r
3158                                                 if (sd) {\r
3159                                                         r = t.dom.doc.createRange();\r
3160                                                         r.setStart(sd.startNode, sd.startOffset);\r
3161                                                         r.setEnd(sd.endNode, sd.endOffset);\r
3162                                                         s.removeAllRanges();\r
3163                                                         s.addRange(r);\r
3164                                                 }\r
3165 \r
3166                                                 if (!tinymce.isOpera)\r
3167                                                         t.win.focus();\r
3168                                         } catch (ex) {\r
3169                                                 // Ignore\r
3170                                         }\r
3171                                 }\r
3172                         }\r
3173                 },\r
3174 \r
3175                 select : function(n, c) {\r
3176                         var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;\r
3177 \r
3178                         function first(n) {\r
3179                                 return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;\r
3180                         };\r
3181 \r
3182                         function last(n) {\r
3183                                 var c, o, w;\r
3184 \r
3185                                 if (!n)\r
3186                                         return null;\r
3187 \r
3188                                 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
3189                                 while (c = w.nextNode())\r
3190                                         o = c;\r
3191 \r
3192                                 return o;\r
3193                         };\r
3194 \r
3195                         if (isIE) {\r
3196                                 try {\r
3197                                         b = d.body;\r
3198 \r
3199                                         if (/^(IMG|TABLE)$/.test(n.nodeName)) {\r
3200                                                 r = b.createControlRange();\r
3201                                                 r.addElement(n);\r
3202                                         } else {\r
3203                                                 r = b.createTextRange();\r
3204                                                 r.moveToElementText(n);\r
3205                                         }\r
3206 \r
3207                                         r.select();\r
3208                                 } catch (ex) {\r
3209                                         // Throws illigal agrument in IE some times\r
3210                                 }\r
3211                         } else {\r
3212                                 if (c) {\r
3213                                         fn = first(n);\r
3214                                         ln = last(n);\r
3215 \r
3216                                         if (fn && ln) {\r
3217                                                 //console.debug(fn, ln);\r
3218                                                 r = d.createRange();\r
3219                                                 r.setStart(fn, 0);\r
3220                                                 r.setEnd(ln, ln.nodeValue.length);\r
3221                                         } else\r
3222                                                 r.selectNode(n);\r
3223                                 } else\r
3224                                         r.selectNode(n);\r
3225 \r
3226                                 t.setRng(r);\r
3227                         }\r
3228 \r
3229                         return n;\r
3230                 },\r
3231 \r
3232                 isCollapsed : function() {\r
3233                         var t = this, r = t.getRng(), s = t.getSel();\r
3234 \r
3235                         if (!r || r.item)\r
3236                                 return false;\r
3237 \r
3238                         return !s || r.boundingWidth == 0 || s.isCollapsed;\r
3239                 },\r
3240 \r
3241                 collapse : function(b) {\r
3242                         var t = this, r = t.getRng(), n;\r
3243 \r
3244                         // Control range on IE\r
3245                         if (r.item) {\r
3246                                 n = r.item(0);\r
3247                                 r = this.win.document.body.createTextRange();\r
3248                                 r.moveToElementText(n);\r
3249                         }\r
3250 \r
3251                         r.collapse(!!b);\r
3252                         t.setRng(r);\r
3253                 },\r
3254 \r
3255                 getSel : function() {\r
3256                         var t = this, w = this.win;\r
3257 \r
3258                         return w.getSelection ? w.getSelection() : w.document.selection;\r
3259                 },\r
3260 \r
3261                 getRng : function() {\r
3262                         var t = this, s = t.getSel(), r;\r
3263 \r
3264                         try {\r
3265                                 if (s)\r
3266                                         r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());\r
3267                         } catch (ex) {\r
3268                                 // IE throws unspecified error here if TinyMCE is placed in a frame/iframe\r
3269                         }\r
3270 \r
3271                         // No range found then create an empty one\r
3272                         // This can occur when the editor is placed in a hidden container element on Gecko\r
3273                         // Or on IE when there was an exception\r
3274                         if (!r)\r
3275                                 r = isIE ? t.win.document.body.createTextRange() : t.win.document.createRange();\r
3276 \r
3277                         return r;\r
3278                 },\r
3279 \r
3280                 setRng : function(r) {\r
3281                         var s;\r
3282 \r
3283                         if (!isIE) {\r
3284                                 s = this.getSel();\r
3285 \r
3286                                 if (s) {\r
3287                                         s.removeAllRanges();\r
3288                                         s.addRange(r);\r
3289                                 }\r
3290                         } else {\r
3291                                 try {\r
3292                                         r.select();\r
3293                                 } catch (ex) {\r
3294                                         // Needed for some odd IE bug #1843306\r
3295                                 }\r
3296                         }\r
3297                 },\r
3298 \r
3299                 setNode : function(n) {\r
3300                         var t = this;\r
3301 \r
3302                         t.setContent(t.dom.getOuterHTML(n));\r
3303 \r
3304                         return n;\r
3305                 },\r
3306 \r
3307                 getNode : function() {\r
3308                         var t = this, r = t.getRng(), s = t.getSel(), e;\r
3309 \r
3310                         if (!isIE) {\r
3311                                 // Range maybe lost after the editor is made visible again\r
3312                                 if (!r)\r
3313                                         return t.dom.getRoot();\r
3314 \r
3315                                 e = r.commonAncestorContainer;\r
3316 \r
3317                                 // Handle selection a image or other control like element such as anchors\r
3318                                 if (!r.collapsed) {\r
3319                                         if (r.startContainer == r.endContainer || (tinymce.isWebKit && r.startContainer == r.endContainer.parentNode)) {\r
3320                                                 if (r.startOffset - r.endOffset < 2 || tinymce.isWebKit) {\r
3321                                                         if (r.startContainer.hasChildNodes())\r
3322                                                                 e = r.startContainer.childNodes[r.startOffset];\r
3323                                                 }\r
3324                                         }\r
3325                                 }\r
3326 \r
3327                                 return t.dom.getParent(e, function(n) {\r
3328                                         return n.nodeType == 1;\r
3329                                 });\r
3330                         }\r
3331 \r
3332                         return r.item ? r.item(0) : r.parentElement();\r
3333                 },\r
3334 \r
3335                 destroy : function(s) {\r
3336                         var t = this;\r
3337 \r
3338                         t.win = null;\r
3339 \r
3340                         // Manual destroy then remove unload handler\r
3341                         if (!s)\r
3342                                 tinymce.removeUnload(t.destroy);\r
3343                 }\r
3344 \r
3345                 });\r
3346 })();\r
3347 \r
3348 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */\r
3349 \r
3350 (function() {\r
3351         tinymce.create('tinymce.dom.XMLWriter', {\r
3352                 node : null,\r
3353 \r
3354                 XMLWriter : function(s) {\r
3355                         // Get XML document\r
3356                         function getXML() {\r
3357                                 var i = document.implementation;\r
3358 \r
3359                                 if (!i || !i.createDocument) {\r
3360                                         // Try IE objects\r
3361                                         try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {}\r
3362                                         try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {}\r
3363                                 } else\r
3364                                         return i.createDocument('', '', null);\r
3365                         };\r
3366 \r
3367                         this.doc = getXML();\r
3368                         \r
3369                         // Since Opera and WebKit doesn't escape > into &gt; we need to do it our self to normalize the output for all browsers\r
3370                         this.valid = tinymce.isOpera || tinymce.isWebKit;\r
3371 \r
3372                         this.reset();\r
3373                 },\r
3374 \r
3375                 reset : function() {\r
3376                         var t = this, d = t.doc;\r
3377 \r
3378                         if (d.firstChild)\r
3379                                 d.removeChild(d.firstChild);\r
3380 \r
3381                         t.node = d.appendChild(d.createElement("html"));\r
3382                 },\r
3383 \r
3384                 writeStartElement : function(n) {\r
3385                         var t = this;\r
3386 \r
3387                         t.node = t.node.appendChild(t.doc.createElement(n));\r
3388                 },\r
3389 \r
3390                 writeAttribute : function(n, v) {\r
3391                         if (this.valid)\r
3392                                 v = v.replace(/>/g, '%MCGT%');\r
3393 \r
3394                         this.node.setAttribute(n, v);\r
3395                 },\r
3396 \r
3397                 writeEndElement : function() {\r
3398                         this.node = this.node.parentNode;\r
3399                 },\r
3400 \r
3401                 writeFullEndElement : function() {\r
3402                         var t = this, n = t.node;\r
3403 \r
3404                         n.appendChild(t.doc.createTextNode(""));\r
3405                         t.node = n.parentNode;\r
3406                 },\r
3407 \r
3408                 writeText : function(v) {\r
3409                         if (this.valid)\r
3410                                 v = v.replace(/>/g, '%MCGT%');\r
3411 \r
3412                         this.node.appendChild(this.doc.createTextNode(v));\r
3413                 },\r
3414 \r
3415                 writeCDATA : function(v) {\r
3416                         this.node.appendChild(this.doc.createCDATA(v));\r
3417                 },\r
3418 \r
3419                 writeComment : function(v) {\r
3420                         this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' ')));\r
3421                 },\r
3422 \r
3423                 getContent : function() {\r
3424                         var h;\r
3425 \r
3426                         h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);\r
3427                         h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, '');\r
3428                         h = h.replace(/ ?\/>/g, ' />');\r
3429 \r
3430                         if (this.valid)\r
3431                                 h = h.replace(/\%MCGT%/g, '&gt;');\r
3432 \r
3433                         return h;\r
3434                 }\r
3435 \r
3436                 });\r
3437 })();\r
3438 \r
3439 /* file:jscripts/tiny_mce/classes/dom/StringWriter.js */\r
3440 \r
3441 (function() {\r
3442         tinymce.create('tinymce.dom.StringWriter', {\r
3443                 str : null,\r
3444                 tags : null,\r
3445                 count : 0,\r
3446                 settings : null,\r
3447                 indent : null,\r
3448 \r
3449                 StringWriter : function(s) {\r
3450                         this.settings = tinymce.extend({\r
3451                                 indent_char : ' ',\r
3452                                 indentation : 1\r
3453                         }, s);\r
3454 \r
3455                         this.reset();\r
3456                 },\r
3457 \r
3458                 reset : function() {\r
3459                         this.indent = '';\r
3460                         this.str = "";\r
3461                         this.tags = [];\r
3462                         this.count = 0;\r
3463                 },\r
3464 \r
3465                 writeStartElement : function(n) {\r
3466                         this._writeAttributesEnd();\r
3467                         this.writeRaw('<' + n);\r
3468                         this.tags.push(n);\r
3469                         this.inAttr = true;\r
3470                         this.count++;\r
3471                         this.elementCount = this.count;\r
3472                 },\r
3473 \r
3474                 writeAttribute : function(n, v) {\r
3475                         var t = this;\r
3476 \r
3477                         t.writeRaw(" " + t.encode(n) + '="' + t.encode(v) + '"');\r
3478                 },\r
3479 \r
3480                 writeEndElement : function() {\r
3481                         var n;\r
3482 \r
3483                         if (this.tags.length > 0) {\r
3484                                 n = this.tags.pop();\r
3485 \r
3486                                 if (this._writeAttributesEnd(1))\r
3487                                         this.writeRaw('</' + n + '>');\r
3488 \r
3489                                 if (this.settings.indentation > 0)\r
3490                                         this.writeRaw('\n');\r
3491                         }\r
3492                 },\r
3493 \r
3494                 writeFullEndElement : function() {\r
3495                         if (this.tags.length > 0) {\r
3496                                 this._writeAttributesEnd();\r
3497                                 this.writeRaw('</' + this.tags.pop() + '>');\r
3498 \r
3499                                 if (this.settings.indentation > 0)\r
3500                                         this.writeRaw('\n');\r
3501                         }\r
3502                 },\r
3503 \r
3504                 writeText : function(v) {\r
3505                         this._writeAttributesEnd();\r
3506                         this.writeRaw(this.encode(v));\r
3507                         this.count++;\r
3508                 },\r
3509 \r
3510                 writeCDATA : function(v) {\r
3511                         this._writeAttributesEnd();\r
3512                         this.writeRaw('<![CDATA[' + v + ']]>');\r
3513                         this.count++;\r
3514                 },\r
3515 \r
3516                 writeComment : function(v) {\r
3517                         this._writeAttributesEnd();\r
3518                         this.writeRaw('<!-- ' + v + '-->');\r
3519                         this.count++;\r
3520                 },\r
3521 \r
3522                 writeRaw : function(v) {\r
3523                         this.str += v;\r
3524                 },\r
3525 \r
3526                 encode : function(s) {\r
3527                         return s.replace(/[<>&"]/g, function(v) {\r
3528                                 switch (v) {\r
3529                                         case '<':\r
3530                                                 return '&lt;';\r
3531 \r
3532                                         case '>':\r
3533                                                 return '&gt;';\r
3534 \r
3535                                         case '&':\r
3536                                                 return '&amp;';\r
3537 \r
3538                                         case '"':\r
3539                                                 return '&quot;';\r
3540                                 }\r
3541 \r
3542                                 return v;\r
3543                         });\r
3544                 },\r
3545 \r
3546                 getContent : function() {\r
3547                         return this.str;\r
3548                 },\r
3549 \r
3550                 _writeAttributesEnd : function(s) {\r
3551                         if (!this.inAttr)\r
3552                                 return;\r
3553 \r
3554                         this.inAttr = false;\r
3555 \r
3556                         if (s && this.elementCount == this.count) {\r
3557                                 this.writeRaw(' />');\r
3558                                 return false;\r
3559                         }\r
3560 \r
3561                         this.writeRaw('>');\r
3562 \r
3563                         return true;\r
3564                 }\r
3565 \r
3566                 });\r
3567 })();\r
3568 \r
3569 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */\r
3570 \r
3571 (function() {\r
3572         // Shorten names\r
3573         var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;\r
3574 \r
3575         // Returns only attribites that have values not all attributes in IE\r
3576         function getIEAtts(n) {\r
3577                 var o = [];\r
3578 \r
3579                 // Object will throw exception in IE\r
3580                 if (n.nodeName == 'OBJECT')\r
3581                         return n.attributes;\r
3582 \r
3583                 n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
3584                         o.push({specified : 1, nodeName : b});\r
3585                 });\r
3586 \r
3587                 return o;\r
3588         };\r
3589 \r
3590         function wildcardToRE(s) {\r
3591                 return s.replace(/([?+*])/g, '.$1');\r
3592         };\r
3593 \r
3594         tinymce.create('tinymce.dom.Serializer', {\r
3595                 Serializer : function(s) {\r
3596                         var t = this;\r
3597 \r
3598                         t.key = 0;\r
3599                         t.onPreProcess = new Dispatcher(t);\r
3600                         t.onPostProcess = new Dispatcher(t);\r
3601 \r
3602                         if (tinymce.relaxedDomain && tinymce.isGecko) {\r
3603                                 // Gecko has a bug where we can't create a new XML document if domain relaxing is used\r
3604                                 t.writer = new tinymce.dom.StringWriter();\r
3605                         } else {\r
3606                                 try {\r
3607                                         t.writer = new tinymce.dom.XMLWriter();\r
3608                                 } catch (ex) {\r
3609                                         // IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter\r
3610                                         t.writer = new tinymce.dom.StringWriter();\r
3611                                 }\r
3612                         }\r
3613 \r
3614                         // Default settings\r
3615                         t.settings = s = extend({\r
3616                                 dom : tinymce.DOM,\r
3617                                 valid_nodes : 0,\r
3618                                 node_filter : 0,\r
3619                                 attr_filter : 0,\r
3620                                 invalid_attrs : /^(mce_|_moz_)/,\r
3621                                 closed : /(br|hr|input|meta|img|link|param)/,\r
3622                                 entity_encoding : 'named',\r
3623                                 entities : '160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro',\r
3624                                 valid_elements : '*[*]',\r
3625                                 extended_valid_elements : 0,\r
3626                                 valid_child_elements : 0,\r
3627                                 invalid_elements : 0,\r
3628                                 fix_table_elements : 0,\r
3629                                 fix_list_elements : true,\r
3630                                 fix_content_duplication : true,\r
3631                                 convert_fonts_to_spans : false,\r
3632                                 font_size_classes : 0,\r
3633                                 font_size_style_values : 0,\r
3634                                 apply_source_formatting : 0,\r
3635                                 indent_mode : 'simple',\r
3636                                 indent_char : '\t',\r
3637                                 indent_levels : 1,\r
3638                                 remove_linebreaks : 1\r
3639                         }, s);\r
3640 \r
3641                         t.dom = s.dom;\r
3642 \r
3643                         if (s.fix_list_elements) {\r
3644                                 t.onPreProcess.add(function(se, o) {\r
3645                                         var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np;\r
3646 \r
3647                                         function prevNode(e, n) {\r
3648                                                 var a = n.split(','), i;\r
3649 \r
3650                                                 while ((e = e.previousSibling) != null) {\r
3651                                                         for (i=0; i<a.length; i++) {\r
3652                                                                 if (e.nodeName == a[i])\r
3653                                                                         return e;\r
3654                                                         }\r
3655                                                 }\r
3656 \r
3657                                                 return null;\r
3658                                         };\r
3659 \r
3660                                         for (x=0; x<a.length; x++) {\r
3661                                                 nl = t.dom.select(a[x], o.node);\r
3662 \r
3663                                                 for (i=0; i<nl.length; i++) {\r
3664                                                         n = nl[i];\r
3665                                                         p = n.parentNode;\r
3666 \r
3667                                                         if (r.test(p.nodeName)) {\r
3668                                                                 np = prevNode(n, 'LI');\r
3669 \r
3670                                                                 if (!np) {\r
3671                                                                         np = t.dom.create('li');\r
3672                                                                         np.innerHTML = '&nbsp;';\r
3673                                                                         np.appendChild(n);\r
3674                                                                         p.insertBefore(np, p.firstChild);\r
3675                                                                 } else\r
3676                                                                         np.appendChild(n);\r
3677                                                         }\r
3678                                                 }\r
3679                                         }\r
3680                                 });\r
3681                         }\r
3682 \r
3683                         if (s.fix_table_elements) {\r
3684                                 t.onPreProcess.add(function(se, o) {\r
3685                                         each(t.dom.select('table', o.node), function(e) {\r
3686                                                 var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), pa2, n, tm, pl = [], i, ns;\r
3687 \r
3688                                                 if (pa) {\r
3689                                                         pa2 = pa.cloneNode(false);\r
3690 \r
3691                                                         pl.push(e);\r
3692                                                         for (n = e; n = n.parentNode;) {\r
3693                                                                 pl.push(n);\r
3694 \r
3695                                                                 if (n == pa)\r
3696                                                                         break;\r
3697                                                         }\r
3698 \r
3699                                                         tm = pa2;\r
3700                                                         for (i = pl.length - 1; i >= 0; i--) {\r
3701                                                                 if (i == pl.length - 1) {\r
3702                                                                         while (ns = pl[i - 1].nextSibling)\r
3703                                                                                 tm.appendChild(ns.parentNode.removeChild(ns));\r
3704                                                                 } else {\r
3705                                                                         n = pl[i].cloneNode(false);\r
3706 \r
3707                                                                         if (i != 0) {\r
3708                                                                                 while (ns = pl[i - 1].nextSibling)\r
3709                                                                                         n.appendChild(ns.parentNode.removeChild(ns));\r
3710                                                                         }\r
3711 \r
3712                                                                         tm = tm.appendChild(n);\r
3713                                                                 }\r
3714                                                         }\r
3715 \r
3716                                                         e = t.dom.insertAfter(e.parentNode.removeChild(e), pa);\r
3717                                                         t.dom.insertAfter(e, pa);\r
3718                                                         t.dom.insertAfter(pa2, e);\r
3719                                                 }\r
3720                                         });\r
3721                                 });\r
3722                         }\r
3723                 },\r
3724 \r
3725                 setEntities : function(s) {\r
3726                         var t = this, a, i, l = {}, re = '', v;\r
3727 \r
3728                         // No need to setup more than once\r
3729                         if (t.entityLookup)\r
3730                                 return;\r
3731 \r
3732                         // Build regex and lookup array\r
3733                         a = s.split(',');\r
3734                         for (i = 0; i < a.length; i += 2) {\r
3735                                 v = a[i];\r
3736 \r
3737                                 // Don't add default &amp; &quot; etc.\r
3738                                 if (v == 34 || v == 38 || v == 60 || v == 62)\r
3739                                         continue;\r
3740 \r
3741                                 l[String.fromCharCode(a[i])] = a[i + 1];\r
3742 \r
3743                                 v = parseInt(a[i]).toString(16);\r
3744                                 re += '\\u' + '0000'.substring(v.length) + v;\r
3745                         }\r
3746 \r
3747                         if (!re) {\r
3748                                 t.settings.entity_encoding = 'raw';\r
3749                                 return;\r
3750                         }\r
3751 \r
3752                         t.entitiesRE = new RegExp('[' + re + ']', 'g');\r
3753                         t.entityLookup = l;\r
3754                 },\r
3755 \r
3756                 setValidChildRules : function(s) {\r
3757                         this.childRules = null;\r
3758                         this.addValidChildRules(s);\r
3759                 },\r
3760 \r
3761                 addValidChildRules : function(s) {\r
3762                         var t = this, inst, intr, bloc;\r
3763 \r
3764                         if (!s)\r
3765                                 return;\r
3766 \r
3767                         inst = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment';\r
3768                         intr = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment';\r
3769                         bloc = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';\r
3770 \r
3771                         each(s.split(','), function(s) {\r
3772                                 var p = s.split(/\[|\]/), re;\r
3773 \r
3774                                 s = '';\r
3775                                 each(p[1].split('|'), function(v) {\r
3776                                         if (s)\r
3777                                                 s += '|';\r
3778 \r
3779                                         switch (v) {\r
3780                                                 case '%itrans':\r
3781                                                         v = intr;\r
3782                                                         break;\r
3783 \r
3784                                                 case '%itrans_na':\r
3785                                                         v = intr.substring(2);\r
3786                                                         break;\r
3787 \r
3788                                                 case '%istrict':\r
3789                                                         v = inst;\r
3790                                                         break;\r
3791 \r
3792                                                 case '%istrict_na':\r
3793                                                         v = inst.substring(2);\r
3794                                                         break;\r
3795 \r
3796                                                 case '%btrans':\r
3797                                                         v = bloc;\r
3798                                                         break;\r
3799 \r
3800                                                 case '%bstrict':\r
3801                                                         v = bloc;\r
3802                                                         break;\r
3803                                         }\r
3804 \r
3805                                         s += v;\r
3806                                 });\r
3807                                 re = new RegExp('^(' + s.toLowerCase() + ')$', 'i');\r
3808 \r
3809                                 each(p[0].split('/'), function(s) {\r
3810                                         t.childRules = t.childRules || {};\r
3811                                         t.childRules[s] = re;\r
3812                                 });\r
3813                         });\r
3814 \r
3815                         // Build regex\r
3816                         s = '';\r
3817                         each(t.childRules, function(v, k) {\r
3818                                 if (s)\r
3819                                         s += '|';\r
3820 \r
3821                                 s += k;\r
3822                         });\r
3823 \r
3824                         t.parentElementsRE = new RegExp('^(' + s.toLowerCase() + ')$', 'i');\r
3825 \r
3826                         /*console.debug(t.parentElementsRE.toString());\r
3827                         each(t.childRules, function(v) {\r
3828                                 console.debug(v.toString());\r
3829                         });*/\r
3830                 },\r
3831 \r
3832                 setRules : function(s) {\r
3833                         var t = this;\r
3834 \r
3835                         t._setup();\r
3836                         t.rules = {};\r
3837                         t.wildRules = [];\r
3838                         t.validElements = {};\r
3839 \r
3840                         return t.addRules(s);\r
3841                 },\r
3842 \r
3843                 addRules : function(s) {\r
3844                         var t = this, dr;\r
3845 \r
3846                         if (!s)\r
3847                                 return;\r
3848 \r
3849                         t._setup();\r
3850 \r
3851                         each(s.split(','), function(s) {\r
3852                                 var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = [];\r
3853 \r
3854                                 // Extend with default rules\r
3855                                 if (dr)\r
3856                                         at = tinymce.extend([], dr.attribs);\r
3857 \r
3858                                 // Parse attributes\r
3859                                 if (p.length > 1) {\r
3860                                         each(p[1].split('|'), function(s) {\r
3861                                                 var ar = {}, i;\r
3862 \r
3863                                                 at = at || [];\r
3864 \r
3865                                                 // Parse attribute rule\r
3866                                                 s = s.replace(/::/g, '~');\r
3867                                                 s = /^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(s);\r
3868                                                 s[2] = s[2].replace(/~/g, ':');\r
3869 \r
3870                                                 // Add required attributes\r
3871                                                 if (s[1] == '!') {\r
3872                                                         ra = ra || [];\r
3873                                                         ra.push(s[2]);\r
3874                                                 }\r
3875 \r
3876                                                 // Remove inherited attributes\r
3877                                                 if (s[1] == '-') {\r
3878                                                         for (i = 0; i <at.length; i++) {\r
3879                                                                 if (at[i].name == s[2]) {\r
3880                                                                         at.splice(i, 1);\r
3881                                                                         return;\r
3882                                                                 }\r
3883                                                         }\r
3884                                                 }\r
3885 \r
3886                                                 switch (s[3]) {\r
3887                                                         // Add default attrib values\r
3888                                                         case '=':\r
3889                                                                 ar.defaultVal = s[4] || '';\r
3890                                                                 break;\r
3891 \r
3892                                                         // Add forced attrib values\r
3893                                                         case ':':\r
3894                                                                 ar.forcedVal = s[4];\r
3895                                                                 break;\r
3896 \r
3897                                                         // Add validation values\r
3898                                                         case '<':\r
3899                                                                 ar.validVals = s[4].split('?');\r
3900                                                                 break;\r
3901                                                 }\r
3902 \r
3903                                                 if (/[*.?]/.test(s[2])) {\r
3904                                                         wat = wat || [];\r
3905                                                         ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$');\r
3906                                                         wat.push(ar);\r
3907                                                 } else {\r
3908                                                         ar.name = s[2];\r
3909                                                         at.push(ar);\r
3910                                                 }\r
3911 \r
3912                                                 va.push(s[2]);\r
3913                                         });\r
3914                                 }\r
3915 \r
3916                                 // Handle element names\r
3917                                 each(tn, function(s, i) {\r
3918                                         var pr = s.charAt(0), x = 1, ru = {};\r
3919 \r
3920                                         // Extend with default rule data\r
3921                                         if (dr) {\r
3922                                                 if (dr.noEmpty)\r
3923                                                         ru.noEmpty = dr.noEmpty;\r
3924 \r
3925                                                 if (dr.fullEnd)\r
3926                                                         ru.fullEnd = dr.fullEnd;\r
3927 \r
3928                                                 if (dr.padd)\r
3929                                                         ru.padd = dr.padd;\r
3930                                         }\r
3931 \r
3932                                         // Handle prefixes\r
3933                                         switch (pr) {\r
3934                                                 case '-':\r
3935                                                         ru.noEmpty = true;\r
3936                                                         break;\r
3937 \r
3938                                                 case '+':\r
3939                                                         ru.fullEnd = true;\r
3940                                                         break;\r
3941 \r
3942                                                 case '#':\r
3943                                                         ru.padd = true;\r
3944                                                         break;\r
3945 \r
3946                                                 default:\r
3947                                                         x = 0;\r
3948                                         }\r
3949 \r
3950                                         tn[i] = s = s.substring(x);\r
3951                                         t.validElements[s] = 1;\r
3952 \r
3953                                         // Add element name or element regex\r
3954                                         if (/[*.?]/.test(tn[0])) {\r
3955                                                 ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$');\r
3956                                                 t.wildRules = t.wildRules || {};\r
3957                                                 t.wildRules.push(ru);\r
3958                                         } else {\r
3959                                                 ru.name = tn[0];\r
3960 \r
3961                                                 // Store away default rule\r
3962                                                 if (tn[0] == '@')\r
3963                                                         dr = ru;\r
3964 \r
3965                                                 t.rules[s] = ru;\r
3966                                         }\r
3967 \r
3968                                         ru.attribs = at;\r
3969 \r
3970                                         if (ra)\r
3971                                                 ru.requiredAttribs = ra;\r
3972 \r
3973                                         if (wat) {\r
3974                                                 // Build valid attributes regexp\r
3975                                                 s = '';\r
3976                                                 each(va, function(v) {\r
3977                                                         if (s)\r
3978                                                                 s += '|';\r
3979 \r
3980                                                         s += '(' + wildcardToRE(v) + ')';\r
3981                                                 });\r
3982                                                 ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$');\r
3983                                                 ru.wildAttribs = wat;\r
3984                                         }\r
3985                                 });\r
3986                         });\r
3987 \r
3988                         // Build valid elements regexp\r
3989                         s = '';\r
3990                         each(t.validElements, function(v, k) {\r
3991                                 if (s)\r
3992                                         s += '|';\r
3993 \r
3994                                 if (k != '@')\r
3995                                         s += k;\r
3996                         });\r
3997                         t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$');\r
3998 \r
3999                         //console.debug(t.validElementsRE.toString());\r
4000                         //console.dir(t.rules);\r
4001                         //console.dir(t.wildRules);\r
4002                 },\r
4003 \r
4004                 findRule : function(n) {\r
4005                         var t = this, rl = t.rules, i, r;\r
4006 \r
4007                         t._setup();\r
4008 \r
4009                         // Exact match\r
4010                         r = rl[n];\r
4011                         if (r)\r
4012                                 return r;\r
4013 \r
4014                         // Try wildcards\r
4015                         rl = t.wildRules;\r
4016                         for (i = 0; i < rl.length; i++) {\r
4017                                 if (rl[i].nameRE.test(n))\r
4018                                         return rl[i];\r
4019                         }\r
4020 \r
4021                         return null;\r
4022                 },\r
4023 \r
4024                 findAttribRule : function(ru, n) {\r
4025                         var i, wa = ru.wildAttribs;\r
4026 \r
4027                         for (i = 0; i < wa.length; i++) {\r
4028                                 if (wa[i].nameRE.test(n))\r
4029                                         return wa[i];\r
4030                         }\r
4031 \r
4032                         return null;\r
4033                 },\r
4034 \r
4035                 serialize : function(n, o) {\r
4036                         var h, t = this;\r
4037 \r
4038                         t._setup();\r
4039                         o = o || {};\r
4040                         o.format = o.format || 'html';\r
4041                         t.processObj = o;\r
4042                         n = n.cloneNode(true);\r
4043                         t.key = '' + (parseInt(t.key) + 1);\r
4044 \r
4045                         // Pre process\r
4046                         if (!o.no_events) {\r
4047                                 o.node = n;\r
4048                                 t.onPreProcess.dispatch(t, o);\r
4049                         }\r
4050 \r
4051                         // Serialize HTML DOM into a string\r
4052                         t.writer.reset();\r
4053                         t._serializeNode(n, o.getInner);\r
4054 \r
4055                         // Post process\r
4056                         o.content = t.writer.getContent();\r
4057 \r
4058                         if (!o.no_events)\r
4059                                 t.onPostProcess.dispatch(t, o);\r
4060 \r
4061                         t._postProcess(o);\r
4062                         o.node = null;\r
4063 \r
4064                         return tinymce.trim(o.content);\r
4065                 },\r
4066 \r
4067                 // Internal functions\r
4068 \r
4069                 _postProcess : function(o) {\r
4070                         var t = this, s = t.settings, h = o.content, sc = [], p;\r
4071 \r
4072                         if (o.format == 'html') {\r
4073                                 // Protect some elements\r
4074                                 p = t._protect({\r
4075                                         content : h,\r
4076                                         patterns : [\r
4077                                                 {pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},\r
4078                                                 {pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},\r
4079                                                 {pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1}\r
4080                                         ]\r
4081                                 });\r
4082 \r
4083                                 h = p.content;\r
4084 \r
4085                                 // Entity encode\r
4086                                 if (s.entity_encoding !== 'raw')\r
4087                                         h = t._encode(h);\r
4088 \r
4089                                 // Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor\r
4090 /*                              if (o.set)\r
4091                                         h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');\r
4092                                 else\r
4093                                         h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');*/\r
4094 \r
4095                                 // Since Gecko and Safari keeps whitespace in the DOM we need to\r
4096                                 // remove it inorder to match other browsers. But I think Gecko and Safari is right.\r
4097                                 // This process is only done when getting contents out from the editor.\r
4098                                 if (!o.set) {\r
4099                                         // We need to replace paragraph whitespace with an nbsp before indentation to keep the \u00a0 char\r
4100                                         h = h.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g, s.entity_encoding == 'numeric' ? '<p$1>&#160;</p>' : '<p$1>&nbsp;</p>');\r
4101 \r
4102                                         if (s.remove_linebreaks) {\r
4103                                                 h = h.replace(/\r?\n|\r/g, ' ');\r
4104                                                 h = h.replace(/(<[^>]+>)\s+/g, '$1 ');\r
4105                                                 h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');\r
4106                                                 h = h.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start\r
4107                                                 h = h.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start\r
4108                                                 h = h.replace(/\s+<\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end\r
4109                                         }\r
4110 \r
4111                                         // Simple indentation\r
4112                                         if (s.apply_source_formatting && s.indent_mode == 'simple') {\r
4113                                                 // Add line breaks before and after block elements\r
4114                                                 h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');\r
4115                                                 h = h.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');\r
4116                                                 h = h.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');\r
4117                                                 h = h.replace(/\n\n/g, '\n');\r
4118                                         }\r
4119                                 }\r
4120 \r
4121                                 h = t._unprotect(h, p);\r
4122 \r
4123                                 // Restore the \u00a0 character if raw mode is enabled\r
4124                                 if (s.entity_encoding == 'raw')\r
4125                                         h = h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g, '<p$1>\u00a0</p>');\r
4126                         }\r
4127 \r
4128                         o.content = h;\r
4129                 },\r
4130 \r
4131                 _serializeNode : function(n, inn) {\r
4132                         var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;\r
4133 \r
4134                         if (!s.node_filter || s.node_filter(n)) {\r
4135                                 switch (n.nodeType) {\r
4136                                         case 1: // Element\r
4137                                                 if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))\r
4138                                                         return;\r
4139 \r
4140                                                 iv = false;\r
4141                                                 hc = n.hasChildNodes();\r
4142                                                 nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase();\r
4143 \r
4144                                                 // Add correct prefix on IE\r
4145                                                 if (isIE) {\r
4146                                                         if (n.scopeName !== 'HTML' && n.scopeName !== 'html')\r
4147                                                                 nn = n.scopeName + ':' + nn;\r
4148                                                 }\r
4149 \r
4150                                                 // Remove mce prefix on IE needed for the abbr element\r
4151                                                 if (nn.indexOf('mce:') === 0)\r
4152                                                         nn = nn.substring(4);\r
4153 \r
4154                                                 // Check if valid\r
4155                                                 if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {\r
4156                                                         iv = true;\r
4157                                                         break;\r
4158                                                 }\r
4159 \r
4160                                                 if (isIE) {\r
4161                                                         // Fix IE content duplication (DOM can have multiple copies of the same node)\r
4162                                                         if (s.fix_content_duplication) {\r
4163                                                                 if (n.mce_serialized == t.key)\r
4164                                                                         return;\r
4165 \r
4166                                                                 n.mce_serialized = t.key;\r
4167                                                         }\r
4168 \r
4169                                                         // IE sometimes adds a / infront of the node name\r
4170                                                         if (nn.charAt(0) == '/')\r
4171                                                                 nn = nn.substring(1);\r
4172                                                 } else if (isGecko) {\r
4173                                                         // Ignore br elements\r
4174                                                         if (n.nodeName === 'BR' && n.getAttribute('type') == '_moz')\r
4175                                                                 return;\r
4176                                                 }\r
4177 \r
4178                                                 // Check if valid child\r
4179                                                 if (t.childRules) {\r
4180                                                         if (t.parentElementsRE.test(t.elementName)) {\r
4181                                                                 if (!t.childRules[t.elementName].test(nn)) {\r
4182                                                                         iv = true;\r
4183                                                                         break;\r
4184                                                                 }\r
4185                                                         }\r
4186 \r
4187                                                         t.elementName = nn;\r
4188                                                 }\r
4189 \r
4190                                                 ru = t.findRule(nn);\r
4191                                                 nn = ru.name || nn;\r
4192 \r
4193                                                 // Skip empty nodes or empty node name in IE\r
4194                                                 if ((!hc && ru.noEmpty) || (isIE && !nn)) {\r
4195                                                         iv = true;\r
4196                                                         break;\r
4197                                                 }\r
4198 \r
4199                                                 // Check required\r
4200                                                 if (ru.requiredAttribs) {\r
4201                                                         a = ru.requiredAttribs;\r
4202 \r
4203                                                         for (i = a.length - 1; i >= 0; i--) {\r
4204                                                                 if (this.dom.getAttrib(n, a[i]) !== '')\r
4205                                                                         break;\r
4206                                                         }\r
4207 \r
4208                                                         // None of the required was there\r
4209                                                         if (i == -1) {\r
4210                                                                 iv = true;\r
4211                                                                 break;\r
4212                                                         }\r
4213                                                 }\r
4214 \r
4215                                                 w.writeStartElement(nn);\r
4216 \r
4217                                                 // Add ordered attributes\r
4218                                                 if (ru.attribs) {\r
4219                                                         for (i=0, at = ru.attribs, l = at.length; i<l; i++) {\r
4220                                                                 a = at[i];\r
4221                                                                 v = t._getAttrib(n, a);\r
4222 \r
4223                                                                 if (v !== null)\r
4224                                                                         w.writeAttribute(a.name, v);\r
4225                                                         }\r
4226                                                 }\r
4227 \r
4228                                                 // Add wild attributes\r
4229                                                 if (ru.validAttribsRE) {\r
4230                                                         at = isIE ? getIEAtts(n) : n.attributes;\r
4231                                                         for (i=at.length-1; i>-1; i--) {\r
4232                                                                 no = at[i];\r
4233 \r
4234                                                                 if (no.specified) {\r
4235                                                                         a = no.nodeName.toLowerCase();\r
4236 \r
4237                                                                         if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a))\r
4238                                                                                 continue;\r
4239 \r
4240                                                                         ar = t.findAttribRule(ru, a);\r
4241                                                                         v = t._getAttrib(n, ar, a);\r
4242 \r
4243                                                                         if (v !== null)\r
4244                                                                                 w.writeAttribute(a, v);\r
4245                                                                 }\r
4246                                                         }\r
4247                                                 }\r
4248 \r
4249                                                 // Padd empty nodes with a &nbsp;\r
4250                                                 if (!hc && ru.padd)\r
4251                                                         w.writeText('\u00a0');\r
4252 \r
4253                                                 break;\r
4254 \r
4255                                         case 3: // Text\r
4256                                                 // Check if valid child\r
4257                                                 if (t.childRules && t.parentElementsRE.test(t.elementName)) {\r
4258                                                         if (!t.childRules[t.elementName].test(n.nodeName))\r
4259                                                                 return;\r
4260                                                 }\r
4261 \r
4262                                                 return w.writeText(n.nodeValue);\r
4263 \r
4264                                         case 4: // CDATA\r
4265                                                 return w.writeCDATA(n.nodeValue);\r
4266 \r
4267                                         case 8: // Comment\r
4268                                                 return w.writeComment(n.nodeValue);\r
4269                                 }\r
4270                         } else if (n.nodeType == 1)\r
4271                                 hc = n.hasChildNodes();\r
4272 \r
4273                         if (hc) {\r
4274                                 cn = n.firstChild;\r
4275 \r
4276                                 while (cn) {\r
4277                                         t._serializeNode(cn);\r
4278                                         t.elementName = nn;\r
4279                                         cn = cn.nextSibling;\r
4280                                 }\r
4281                         }\r
4282 \r
4283                         // Write element end\r
4284                         if (!iv) {\r
4285                                 if (hc || !s.closed.test(nn))\r
4286                                         w.writeFullEndElement();\r
4287                                 else\r
4288                                         w.writeEndElement();\r
4289                         }\r
4290                 },\r
4291 \r
4292                 _protect : function(o) {\r
4293                         var t = this;\r
4294 \r
4295                         o.items = o.items || [];\r
4296 \r
4297                         function enc(s) {\r
4298                                 return s.replace(/[\r\n\\]/g, function(c) {\r
4299                                         if (c === '\n')\r
4300                                                 return '\\n';\r
4301                                         else if (c === '\\')\r
4302                                                 return '\\\\';\r
4303 \r
4304                                         return '\\r';\r
4305                                 });\r
4306                         };\r
4307 \r
4308                         function dec(s) {\r
4309                                 return s.replace(/\\[\\rn]/g, function(c) {\r
4310                                         if (c === '\\n')\r
4311                                                 return '\n';\r
4312                                         else if (c === '\\\\')\r
4313                                                 return '\\';\r
4314 \r
4315                                         return '\r';\r
4316                                 });\r
4317                         };\r
4318 \r
4319                         each(o.patterns, function(p) {\r
4320                                 o.content = dec(enc(o.content).replace(p.pattern, function(x, a, b, c) {\r
4321                                         b = dec(b);\r
4322 \r
4323                                         if (p.encode)\r
4324                                                 b = t._encode(b);\r
4325 \r
4326                                         o.items.push(b);\r
4327                                         return a + '<!--mce:' + (o.items.length - 1) + '-->' + c;\r
4328                                 }));\r
4329                         });\r
4330 \r
4331                         return o;\r
4332                 },\r
4333 \r
4334                 _unprotect : function(h, o) {\r
4335                         h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) {\r
4336                                 return o.items[parseInt(b)];\r
4337                         });\r
4338 \r
4339                         o.items = [];\r
4340 \r
4341                         return h;\r
4342                 },\r
4343 \r
4344                 _encode : function(h) {\r
4345                         var t = this, s = t.settings, l;\r
4346 \r
4347                         // Entity encode\r
4348                         if (s.entity_encoding !== 'raw') {\r
4349                                 if (s.entity_encoding.indexOf('named') != -1) {\r
4350                                         t.setEntities(s.entities);\r
4351                                         l = t.entityLookup;\r
4352 \r
4353                                         h = h.replace(t.entitiesRE, function(a) {\r
4354                                                 var v;\r
4355 \r
4356                                                 if (v = l[a])\r
4357                                                         a = '&' + v + ';';\r
4358 \r
4359                                                 return a;\r
4360                                         });\r
4361                                 }\r
4362 \r
4363                                 if (s.entity_encoding.indexOf('numeric') != -1) {\r
4364                                         h = h.replace(/[\u007E-\uFFFF]/g, function(a) {\r
4365                                                 return '&#' + a.charCodeAt(0) + ';';\r
4366                                         });\r
4367                                 }\r
4368                         }\r
4369 \r
4370                         return h;\r
4371                 },\r
4372 \r
4373                 _setup : function() {\r
4374                         var t = this, s = this.settings;\r
4375 \r
4376                         if (t.done)\r
4377                                 return;\r
4378 \r
4379                         t.done = 1;\r
4380 \r
4381                         t.setRules(s.valid_elements);\r
4382                         t.addRules(s.extended_valid_elements);\r
4383                         t.addValidChildRules(s.valid_child_elements);\r
4384 \r
4385                         if (s.invalid_elements)\r
4386                                 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(/,/g, '|').toLowerCase()) + ')$');\r
4387 \r
4388                         if (s.attrib_value_filter)\r
4389                                 t.attribValueFilter = s.attribValueFilter;\r
4390                 },\r
4391 \r
4392                 _getAttrib : function(n, a, na) {\r
4393                         var i, v;\r
4394 \r
4395                         na = na || a.name;\r
4396 \r
4397                         if (a.forcedVal && (v = a.forcedVal)) {\r
4398                                 if (v === '{$uid}')\r
4399                                         return this.dom.uniqueId();\r
4400 \r
4401                                 return v;\r
4402                         }\r
4403 \r
4404                         v = this.dom.getAttrib(n, na);\r
4405 \r
4406                         switch (na) {\r
4407                                 case 'rowspan':\r
4408                                 case 'colspan':\r
4409                                         // Whats the point? Remove usless attribute value\r
4410                                         if (v == '1')\r
4411                                                 v = '';\r
4412 \r
4413                                         break;\r
4414                         }\r
4415 \r
4416                         if (this.attribValueFilter)\r
4417                                 v = this.attribValueFilter(na, v, n);\r
4418 \r
4419                         if (a.validVals) {\r
4420                                 for (i = a.validVals.length - 1; i >= 0; i--) {\r
4421                                         if (v == a.validVals[i])\r
4422                                                 break;\r
4423                                 }\r
4424 \r
4425                                 if (i == -1)\r
4426                                         return null;\r
4427                         }\r
4428 \r
4429                         if (v === '' && typeof(a.defaultVal) != 'undefined') {\r
4430                                 v = a.defaultVal;\r
4431 \r
4432                                 if (v === '{$uid}')\r
4433                                         return this.dom.uniqueId();\r
4434 \r
4435                                 return v;\r
4436                         } else {\r
4437                                 // Remove internal mceItemXX classes when content is extracted from editor\r
4438                                 if (na == 'class' && this.processObj.get)\r
4439                                         v = v.replace(/\s?mceItem\w+\s?/g, '');\r
4440                         }\r
4441 \r
4442                         if (v === '')\r
4443                                 return null;\r
4444 \r
4445 \r
4446                         return v;\r
4447                 }\r
4448 \r
4449                 });\r
4450 })();\r
4451 \r
4452 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */\r
4453 \r
4454 (function() {\r
4455         var each = tinymce.each;\r
4456 \r
4457         tinymce.create('tinymce.dom.ScriptLoader', {\r
4458                 ScriptLoader : function(s) {\r
4459                         this.settings = s || {};\r
4460                         this.queue = [];\r
4461                         this.lookup = {};\r
4462                 },\r
4463 \r
4464                 isDone : function(u) {\r
4465                         return this.lookup[u] ? this.lookup[u].state == 2 : 0;\r
4466                 },\r
4467 \r
4468                 markDone : function(u) {\r
4469                         this.lookup[u] = {state : 2, url : u};\r
4470                 },\r
4471 \r
4472                 add : function(u, cb, s, pr) {\r
4473                         var t = this, lo = t.lookup, o;\r
4474 \r
4475                         if (o = lo[u]) {\r
4476                                 // Is loaded fire callback\r
4477                                 if (cb && o.state == 2)\r
4478                                         cb.call(s || this);\r
4479 \r
4480                                 return o;\r
4481                         }\r
4482 \r
4483                         o = {state : 0, url : u, func : cb, scope : s || this};\r
4484 \r
4485                         if (pr)\r
4486                                 t.queue.unshift(o);\r
4487                         else\r
4488                                 t.queue.push(o);\r
4489 \r
4490                         lo[u] = o;\r
4491 \r
4492                         return o;\r
4493                 },\r
4494 \r
4495                 load : function(u, cb, s) {\r
4496                         var t = this, o;\r
4497 \r
4498                         if (o = t.lookup[u]) {\r
4499                                 // Is loaded fire callback\r
4500                                 if (cb && o.state == 2)\r
4501                                         cb.call(s || t);\r
4502 \r
4503                                 return o;\r
4504                         }\r
4505 \r
4506                         function loadScript(u) {\r
4507                                 if (tinymce.dom.Event.domLoaded || t.settings.strict_mode) {\r
4508                                         tinymce.util.XHR.send({\r
4509                                                 url : tinymce._addVer(u),\r
4510                                                 error : t.settings.error,\r
4511                                                 async : false,\r
4512                                                 success : function(co) {\r
4513                                                         t.eval(co);\r
4514                                                 }\r
4515                                         });\r
4516                                 } else\r
4517                                         document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"></script>');\r
4518                         };\r
4519 \r
4520                         if (!tinymce.is(u, 'string')) {\r
4521                                 each(u, function(u) {\r
4522                                         loadScript(u);\r
4523                                 });\r
4524 \r
4525                                 if (cb)\r
4526                                         cb.call(s || t);\r
4527                         } else {\r
4528                                 loadScript(u);\r
4529 \r
4530                                 if (cb)\r
4531                                         cb.call(s || t);\r
4532                         }\r
4533                 },\r
4534 \r
4535                 loadQueue : function(cb, s) {\r
4536                         var t = this;\r
4537 \r
4538                         if (!t.queueLoading) {\r
4539                                 t.queueLoading = 1;\r
4540                                 t.queueCallbacks = [];\r
4541 \r
4542                                 t.loadScripts(t.queue, function() {\r
4543                                         t.queueLoading = 0;\r
4544 \r
4545                                         if (cb)\r
4546                                                 cb.call(s || t);\r
4547 \r
4548                                         each(t.queueCallbacks, function(o) {\r
4549                                                 o.func.call(o.scope);\r
4550                                         });\r
4551                                 });\r
4552                         } else if (cb)\r
4553                                 t.queueCallbacks.push({func : cb, scope : s || t});\r
4554                 },\r
4555 \r
4556                 eval : function(co) {\r
4557                         var w = window;\r
4558 \r
4559                         // Evaluate script\r
4560                         if (!w.execScript) {\r
4561                                 try {\r
4562                                         eval.call(w, co);\r
4563                                 } catch (ex) {\r
4564                                         eval(co, w); // Firefox 3.0a8\r
4565                                 }\r
4566                         } else\r
4567                                 w.execScript(co); // IE\r
4568                 },\r
4569 \r
4570                 loadScripts : function(sc, cb, s) {\r
4571                         var t = this, lo = t.lookup;\r
4572 \r
4573                         function done(o) {\r
4574                                 o.state = 2; // Has been loaded\r
4575 \r
4576                                 // Run callback\r
4577                                 if (o.func)\r
4578                                         o.func.call(o.scope || t);\r
4579                         };\r
4580 \r
4581                         function allDone() {\r
4582                                 var l;\r
4583 \r
4584                                 // Check if all files are loaded\r
4585                                 l = sc.length;\r
4586                                 each(sc, function(o) {\r
4587                                         o = lo[o.url];\r
4588 \r
4589                                         if (o.state === 2) {// It has finished loading\r
4590                                                 done(o);\r
4591                                                 l--;\r
4592                                         } else\r
4593                                                 load(o);\r
4594                                 });\r
4595 \r
4596                                 // They are all loaded\r
4597                                 if (l === 0 && cb) {\r
4598                                         cb.call(s || t);\r
4599                                         cb = 0;\r
4600                                 }\r
4601                         };\r
4602 \r
4603                         function load(o) {\r
4604                                 if (o.state > 0)\r
4605                                         return;\r
4606 \r
4607                                 o.state = 1; // Is loading\r
4608 \r
4609                                 tinymce.util.XHR.send({\r
4610                                         url : o.url,\r
4611                                         error : t.settings.error,\r
4612                                         success : function(co) {\r
4613                                                 t.eval(co);\r
4614                                                 done(o);\r
4615                                                 allDone();\r
4616                                         }\r
4617                                 });\r
4618                         };\r
4619 \r
4620                         each(sc, function(o) {\r
4621                                 var u = o.url;\r
4622 \r
4623                                 // Add to queue if needed\r
4624                                 if (!lo[u]) {\r
4625                                         lo[u] = o;\r
4626                                         t.queue.push(o);\r
4627                                 } else\r
4628                                         o = lo[u];\r
4629 \r
4630                                 // Is already loading or has been loaded\r
4631                                 if (o.state > 0)\r
4632                                         return;\r
4633 \r
4634                                 if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) {\r
4635                                         var ix, ol = '';\r
4636 \r
4637                                         // Add onload events\r
4638                                         if (cb || o.func) {\r
4639                                                 o.state = 1; // Is loading\r
4640 \r
4641                                                 ix = tinymce.dom.ScriptLoader._addOnLoad(function() {\r
4642                                                         done(o);\r
4643                                                         allDone();\r
4644                                                 });\r
4645 \r
4646                                                 if (tinymce.isIE)\r
4647                                                         ol = ' onreadystatechange="';\r
4648                                                 else\r
4649                                                         ol = ' onload="';\r
4650 \r
4651                                                 ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"';\r
4652                                         }\r
4653 \r
4654                                         document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"' + ol + '></script>');\r
4655 \r
4656                                         if (!o.func)\r
4657                                                 done(o);\r
4658                                 } else\r
4659                                         load(o);\r
4660                         });\r
4661 \r
4662                         allDone();\r
4663                 },\r
4664 \r
4665                 // Static methods\r
4666                 'static' : {\r
4667                         _addOnLoad : function(f) {\r
4668                                 var t = this;\r
4669 \r
4670                                 t._funcs = t._funcs || [];\r
4671                                 t._funcs.push(f);\r
4672 \r
4673                                 return t._funcs.length - 1;\r
4674                         },\r
4675 \r
4676                         _onLoad : function(e, u, ix) {\r
4677                                 if (!tinymce.isIE || e.readyState == 'complete')\r
4678                                         this._funcs[ix].call(this);\r
4679                         }\r
4680                 }\r
4681 \r
4682                 });\r
4683 \r
4684         // Global script loader\r
4685         tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();\r
4686 })();\r
4687 \r
4688 /* file:jscripts/tiny_mce/classes/ui/Control.js */\r
4689 \r
4690 (function() {\r
4691         // Shorten class names\r
4692         var DOM = tinymce.DOM, is = tinymce.is;\r
4693 \r
4694         tinymce.create('tinymce.ui.Control', {\r
4695                 Control : function(id, s) {\r
4696                         this.id = id;\r
4697                         this.settings = s = s || {};\r
4698                         this.rendered = false;\r
4699                         this.onRender = new tinymce.util.Dispatcher(this);\r
4700                         this.classPrefix = '';\r
4701                         this.scope = s.scope || this;\r
4702                         this.disabled = 0;\r
4703                         this.active = 0;\r
4704                 },\r
4705 \r
4706                 setDisabled : function(s) {\r
4707                         var e;\r
4708 \r
4709                         if (s != this.disabled) {\r
4710                                 e = DOM.get(this.id);\r
4711 \r
4712                                 // Add accessibility title for unavailable actions\r
4713                                 if (e && this.settings.unavailable_prefix) {\r
4714                                         if (s) {\r
4715                                                 this.prevTitle = e.title;\r
4716                                                 e.title = this.settings.unavailable_prefix + ": " + e.title;\r
4717                                         } else\r
4718                                                 e.title = this.prevTitle;\r
4719                                 }\r
4720 \r
4721                                 this.setState('Disabled', s);\r
4722                                 this.setState('Enabled', !s);\r
4723                                 this.disabled = s;\r
4724                         }\r
4725                 },\r
4726 \r
4727                 isDisabled : function() {\r
4728                         return this.disabled;\r
4729                 },\r
4730 \r
4731                 setActive : function(s) {\r
4732                         if (s != this.active) {\r
4733                                 this.setState('Active', s);\r
4734                                 this.active = s;\r
4735                         }\r
4736                 },\r
4737 \r
4738                 isActive : function() {\r
4739                         return this.active;\r
4740                 },\r
4741 \r
4742                 setState : function(c, s) {\r
4743                         var n = DOM.get(this.id);\r
4744 \r
4745                         c = this.classPrefix + c;\r
4746 \r
4747                         if (s)\r
4748                                 DOM.addClass(n, c);\r
4749                         else\r
4750                                 DOM.removeClass(n, c);\r
4751                 },\r
4752 \r
4753                 isRendered : function() {\r
4754                         return this.rendered;\r
4755                 },\r
4756 \r
4757                 renderHTML : function() {\r
4758                 },\r
4759 \r
4760                 renderTo : function(n) {\r
4761                         DOM.setHTML(n, this.renderHTML());\r
4762                 },\r
4763 \r
4764                 postRender : function() {\r
4765                         var t = this, b;\r
4766 \r
4767                         // Set pending states\r
4768                         if (is(t.disabled)) {\r
4769                                 b = t.disabled;\r
4770                                 t.disabled = -1;\r
4771                                 t.setDisabled(b);\r
4772                         }\r
4773 \r
4774                         if (is(t.active)) {\r
4775                                 b = t.active;\r
4776                                 t.active = -1;\r
4777                                 t.setActive(b);\r
4778                         }\r
4779                 },\r
4780 \r
4781                 remove : function() {\r
4782                         DOM.remove(this.id);\r
4783                         this.destroy();\r
4784                 },\r
4785 \r
4786                 destroy : function() {\r
4787                         tinymce.dom.Event.clear(this.id);\r
4788                 }\r
4789 \r
4790                 });\r
4791 })();\r
4792 /* file:jscripts/tiny_mce/classes/ui/Container.js */\r
4793 \r
4794 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {\r
4795         Container : function(id, s) {\r
4796                 this.parent(id, s);\r
4797                 this.controls = [];\r
4798                 this.lookup = {};\r
4799         },\r
4800 \r
4801         add : function(c) {\r
4802                 this.lookup[c.id] = c;\r
4803                 this.controls.push(c);\r
4804 \r
4805                 return c;\r
4806         },\r
4807 \r
4808         get : function(n) {\r
4809                 return this.lookup[n];\r
4810         }\r
4811 \r
4812         });\r
4813 \r
4814 \r
4815 /* file:jscripts/tiny_mce/classes/ui/Separator.js */\r
4816 \r
4817 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {\r
4818         Separator : function(id, s) {\r
4819                 this.parent(id, s);\r
4820                 this.classPrefix = 'mceSeparator';\r
4821         },\r
4822 \r
4823         renderHTML : function() {\r
4824                 return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});\r
4825         }\r
4826 \r
4827         });\r
4828 \r
4829 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */\r
4830 \r
4831 (function() {\r
4832         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
4833 \r
4834         tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {\r
4835                 MenuItem : function(id, s) {\r
4836                         this.parent(id, s);\r
4837                         this.classPrefix = 'mceMenuItem';\r
4838                 },\r
4839 \r
4840                 setSelected : function(s) {\r
4841                         this.setState('Selected', s);\r
4842                         this.selected = s;\r
4843                 },\r
4844 \r
4845                 isSelected : function() {\r
4846                         return this.selected;\r
4847                 },\r
4848 \r
4849                 postRender : function() {\r
4850                         var t = this;\r
4851                         \r
4852                         t.parent();\r
4853 \r
4854                         // Set pending state\r
4855                         if (is(t.selected))\r
4856                                 t.setSelected(t.selected);\r
4857                 }\r
4858 \r
4859                 });\r
4860 })();\r
4861 \r
4862 /* file:jscripts/tiny_mce/classes/ui/Menu.js */\r
4863 \r
4864 (function() {\r
4865         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
4866 \r
4867         tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {\r
4868                 Menu : function(id, s) {\r
4869                         var t = this;\r
4870 \r
4871                         t.parent(id, s);\r
4872                         t.items = {};\r
4873                         t.collapsed = false;\r
4874                         t.menuCount = 0;\r
4875                         t.onAddItem = new tinymce.util.Dispatcher(this);\r
4876                 },\r
4877 \r
4878                 expand : function(d) {\r
4879                         var t = this;\r
4880 \r
4881                         if (d) {\r
4882                                 walk(t, function(o) {\r
4883                                         if (o.expand)\r
4884                                                 o.expand();\r
4885                                 }, 'items', t);\r
4886                         }\r
4887 \r
4888                         t.collapsed = false;\r
4889                 },\r
4890 \r
4891                 collapse : function(d) {\r
4892                         var t = this;\r
4893 \r
4894                         if (d) {\r
4895                                 walk(t, function(o) {\r
4896                                         if (o.collapse)\r
4897                                                 o.collapse();\r
4898                                 }, 'items', t);\r
4899                         }\r
4900 \r
4901                         t.collapsed = true;\r
4902                 },\r
4903 \r
4904                 isCollapsed : function() {\r
4905                         return this.collapsed;\r
4906                 },\r
4907 \r
4908                 add : function(o) {\r
4909                         if (!o.settings)\r
4910                                 o = new tinymce.ui.MenuItem(o.id || DOM.uniqueId(), o);\r
4911 \r
4912                         this.onAddItem.dispatch(this, o);\r
4913 \r
4914                         return this.items[o.id] = o;\r
4915                 },\r
4916 \r
4917                 addSeparator : function() {\r
4918                         return this.add({separator : true});\r
4919                 },\r
4920 \r
4921                 addMenu : function(o) {\r
4922                         if (!o.collapse)\r
4923                                 o = this.createMenu(o);\r
4924 \r
4925                         this.menuCount++;\r
4926 \r
4927                         return this.add(o);\r
4928                 },\r
4929 \r
4930                 hasMenus : function() {\r
4931                         return this.menuCount !== 0;\r
4932                 },\r
4933 \r
4934                 remove : function(o) {\r
4935                         delete this.items[o.id];\r
4936                 },\r
4937 \r
4938                 removeAll : function() {\r
4939                         var t = this;\r
4940 \r
4941                         walk(t, function(o) {\r
4942                                 if (o.removeAll)\r
4943                                         o.removeAll();\r
4944                                 else\r
4945                                         o.remove();\r
4946 \r
4947                                 o.destroy();\r
4948                         }, 'items', t);\r
4949 \r
4950                         t.items = {};\r
4951                 },\r
4952 \r
4953                 createMenu : function(o) {\r
4954                         var m = new tinymce.ui.Menu(o.id || DOM.uniqueId(), o);\r
4955 \r
4956                         m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem);\r
4957 \r
4958                         return m;\r
4959                 }\r
4960 \r
4961                 });\r
4962 })();\r
4963 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */\r
4964 \r
4965 (function() {\r
4966         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;\r
4967 \r
4968         tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {\r
4969                 DropMenu : function(id, s) {\r
4970                         s = s || {};\r
4971                         s.container = s.container || DOM.doc.body;\r
4972                         s.offset_x = s.offset_x || 0;\r
4973                         s.offset_y = s.offset_y || 0;\r
4974                         s.vp_offset_x = s.vp_offset_x || 0;\r
4975                         s.vp_offset_y = s.vp_offset_y || 0;\r
4976 \r
4977                         if (is(s.icons) && !s.icons)\r
4978                                 s['class'] += ' mceNoIcons';\r
4979 \r
4980                         this.parent(id, s);\r
4981                         this.onShowMenu = new tinymce.util.Dispatcher(this);\r
4982                         this.onHideMenu = new tinymce.util.Dispatcher(this);\r
4983                         this.classPrefix = 'mceMenu';\r
4984                 },\r
4985 \r
4986                 createMenu : function(s) {\r
4987                         var t = this, cs = t.settings, m;\r
4988 \r
4989                         s.container = s.container || cs.container;\r
4990                         s.parent = t;\r
4991                         s.constrain = s.constrain || cs.constrain;\r
4992                         s['class'] = s['class'] || cs['class'];\r
4993                         s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x;\r
4994                         s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y;\r
4995                         m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s);\r
4996 \r
4997                         m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem);\r
4998 \r
4999                         return m;\r
5000                 },\r
5001 \r
5002                 update : function() {\r
5003                         var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;\r
5004 \r
5005                         tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth;\r
5006                         th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight;\r
5007 \r
5008                         if (!DOM.boxModel)\r
5009                                 t.element.setStyles({width : tw + 2, height : th + 2});\r
5010                         else\r
5011                                 t.element.setStyles({width : tw, height : th});\r
5012 \r
5013                         if (s.max_width)\r
5014                                 DOM.setStyle(co, 'width', tw);\r
5015 \r
5016                         if (s.max_height) {\r
5017                                 DOM.setStyle(co, 'height', th);\r
5018 \r
5019                                 if (tb.clientHeight < s.max_height)\r
5020                                         DOM.setStyle(co, 'overflow', 'hidden');\r
5021                         }\r
5022                 },\r
5023 \r
5024                 showMenu : function(x, y, px) {\r
5025                         var t = this, s = t.settings, co, vp = DOM.getViewPort(), w, h, mx, my, ot = 2, dm, tb, cp = t.classPrefix;\r
5026 \r
5027                         t.collapse(1);\r
5028 \r
5029                         if (t.isMenuVisible)\r
5030                                 return;\r
5031 \r
5032                         if (!t.rendered) {\r
5033                                 co = DOM.add(t.settings.container, t.renderNode());\r
5034 \r
5035                                 each(t.items, function(o) {\r
5036                                         o.postRender();\r
5037                                 });\r
5038 \r
5039                                 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
5040                         } else\r
5041                                 co = DOM.get('menu_' + t.id);\r
5042 \r
5043                         // Move layer out of sight unless it's Opera since it scrolls to top of page due to an bug\r
5044                         if (!tinymce.isOpera)\r
5045                                 DOM.setStyles(co, {left : -0xFFFF , top : -0xFFFF});\r
5046 \r
5047                         DOM.show(co);\r
5048                         t.update();\r
5049 \r
5050                         x += s.offset_x || 0;\r
5051                         y += s.offset_y || 0;\r
5052                         vp.w -= 4;\r
5053                         vp.h -= 4;\r
5054 \r
5055                         // Move inside viewport if not submenu\r
5056                         if (s.constrain) {\r
5057                                 w = co.clientWidth - ot;\r
5058                                 h = co.clientHeight - ot;\r
5059                                 mx = vp.x + vp.w;\r
5060                                 my = vp.y + vp.h;\r
5061 \r
5062                                 if ((x + s.vp_offset_x + w) > mx)\r
5063                                         x = px ? px - w : Math.max(0, (mx - s.vp_offset_x) - w);\r
5064 \r
5065                                 if ((y + s.vp_offset_y + h) > my)\r
5066                                         y = Math.max(0, (my - s.vp_offset_y) - h);\r
5067                         }\r
5068 \r
5069                         DOM.setStyles(co, {left : x , top : y});\r
5070                         t.element.update();\r
5071 \r
5072                         t.isMenuVisible = 1;\r
5073                         t.mouseClickFunc = Event.add(co, 'click', function(e) {\r
5074                                 var m;\r
5075 \r
5076                                 e = e.target;\r
5077 \r
5078                                 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) {\r
5079                                         m = t.items[e.id];\r
5080 \r
5081                                         if (m.isDisabled())\r
5082                                                 return;\r
5083 \r
5084                                         dm = t;\r
5085 \r
5086                                         while (dm) {\r
5087                                                 if (dm.hideMenu)\r
5088                                                         dm.hideMenu();\r
5089 \r
5090                                                 dm = dm.settings.parent;\r
5091                                         }\r
5092 \r
5093                                         if (m.settings.onclick)\r
5094                                                 m.settings.onclick(e);\r
5095 \r
5096                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem\r
5097                                 }\r
5098                         });\r
5099 \r
5100                         if (t.hasMenus()) {\r
5101                                 t.mouseOverFunc = Event.add(co, 'mouseover', function(e) {\r
5102                                         var m, r, mi;\r
5103 \r
5104                                         e = e.target;\r
5105                                         if (e && (e = DOM.getParent(e, 'TR'))) {\r
5106                                                 m = t.items[e.id];\r
5107 \r
5108                                                 if (t.lastMenu)\r
5109                                                         t.lastMenu.collapse(1);\r
5110 \r
5111                                                 if (m.isDisabled())\r
5112                                                         return;\r
5113 \r
5114                                                 if (e && DOM.hasClass(e, cp + 'ItemSub')) {\r
5115                                                         //p = DOM.getPos(s.container);\r
5116                                                         r = DOM.getRect(e);\r
5117                                                         m.showMenu((r.x + r.w - ot), r.y - ot, r.x);\r
5118                                                         t.lastMenu = m;\r
5119                                                         DOM.addClass(DOM.get(m.id).firstChild, cp + 'ItemActive');\r
5120                                                 }\r
5121                                         }\r
5122                                 });\r
5123                         }\r
5124 \r
5125                         t.onShowMenu.dispatch(t);\r
5126 \r
5127                         if (s.keyboard_focus) {\r
5128                                 Event.add(co, 'keydown', t._keyHandler, t);\r
5129                                 DOM.select('a', 'menu_' + t.id)[0].focus(); // Select first link\r
5130                                 t._focusIdx = 0;\r
5131                         }\r
5132                 },\r
5133 \r
5134                 hideMenu : function(c) {\r
5135                         var t = this, co = DOM.get('menu_' + t.id), e;\r
5136 \r
5137                         if (!t.isMenuVisible)\r
5138                                 return;\r
5139 \r
5140                         Event.remove(co, 'mouseover', t.mouseOverFunc);\r
5141                         Event.remove(co, 'click', t.mouseClickFunc);\r
5142                         Event.remove(co, 'keydown', t._keyHandler);\r
5143                         DOM.hide(co);\r
5144                         t.isMenuVisible = 0;\r
5145 \r
5146                         if (!c)\r
5147                                 t.collapse(1);\r
5148 \r
5149                         if (t.element)\r
5150                                 t.element.hide();\r
5151 \r
5152                         if (e = DOM.get(t.id))\r
5153                                 DOM.removeClass(e.firstChild, t.classPrefix + 'ItemActive');\r
5154 \r
5155                         t.onHideMenu.dispatch(t);\r
5156                 },\r
5157 \r
5158                 add : function(o) {\r
5159                         var t = this, co;\r
5160 \r
5161                         o = t.parent(o);\r
5162 \r
5163                         if (t.isRendered && (co = DOM.get('menu_' + t.id)))\r
5164                                 t._add(DOM.select('tbody', co)[0], o);\r
5165 \r
5166                         return o;\r
5167                 },\r
5168 \r
5169                 collapse : function(d) {\r
5170                         this.parent(d);\r
5171                         this.hideMenu(1);\r
5172                 },\r
5173 \r
5174                 remove : function(o) {\r
5175                         DOM.remove(o.id);\r
5176                         this.destroy();\r
5177 \r
5178                         return this.parent(o);\r
5179                 },\r
5180 \r
5181                 destroy : function() {\r
5182                         var t = this, co = DOM.get('menu_' + t.id);\r
5183 \r
5184                         Event.remove(co, 'mouseover', t.mouseOverFunc);\r
5185                         Event.remove(co, 'click', t.mouseClickFunc);\r
5186 \r
5187                         if (t.element)\r
5188                                 t.element.remove();\r
5189 \r
5190                         DOM.remove(co);\r
5191                 },\r
5192 \r
5193                 renderNode : function() {\r
5194                         var t = this, s = t.settings, n, tb, co, w;\r
5195 \r
5196                         w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:200000'});\r
5197                         co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : t.classPrefix + (s['class'] ? ' ' + s['class'] : '')});\r
5198                         t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
5199 \r
5200                         if (s.menu_line)\r
5201                                 DOM.add(co, 'span', {'class' : t.classPrefix + 'Line'});\r
5202 \r
5203 //                      n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'});\r
5204                         n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0});\r
5205                         tb = DOM.add(n, 'tbody');\r
5206 \r
5207                         each(t.items, function(o) {\r
5208                                 t._add(tb, o);\r
5209                         });\r
5210 \r
5211                         t.rendered = true;\r
5212 \r
5213                         return w;\r
5214                 },\r
5215 \r
5216                 // Internal functions\r
5217 \r
5218                 _keyHandler : function(e) {\r
5219                         var t = this, kc = e.keyCode;\r
5220 \r
5221                         function focus(d) {\r
5222                                 var i = t._focusIdx + d, e = DOM.select('a', 'menu_' + t.id)[i];\r
5223 \r
5224                                 if (e) {\r
5225                                         t._focusIdx = i;\r
5226                                         e.focus();\r
5227                                 }\r
5228                         };\r
5229 \r
5230                         switch (kc) {\r
5231                                 case 38:\r
5232                                         focus(-1); // Select first link\r
5233                                         return;\r
5234 \r
5235                                 case 40:\r
5236                                         focus(1);\r
5237                                         return;\r
5238 \r
5239                                 case 13:\r
5240                                         return;\r
5241 \r
5242                                 case 27:\r
5243                                         return this.hideMenu();\r
5244                         }\r
5245                 },\r
5246 \r
5247                 _add : function(tb, o) {\r
5248                         var n, s = o.settings, a, ro, it, cp = this.classPrefix;\r
5249 \r
5250                         if (s.separator) {\r
5251                                 ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'ItemSeparator'});\r
5252                                 DOM.add(ro, 'td', {'class' : cp + 'ItemSeparator'});\r
5253 \r
5254                                 if (n = ro.previousSibling)\r
5255                                         DOM.addClass(n, 'mceLast');\r
5256 \r
5257                                 return;\r
5258                         }\r
5259 \r
5260                         n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'Item ' + cp + 'ItemEnabled'});\r
5261                         n = it = DOM.add(n, 'td');\r
5262                         n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});\r
5263 \r
5264                         DOM.addClass(it, s['class']);\r
5265 //                      n = DOM.add(n, 'span', {'class' : 'item'});\r
5266                         DOM.add(n, 'span', {'class' : 'mceIcon' + (s.icon ? ' mce_' + s.icon : '')});\r
5267                         n = DOM.add(n, s.element || 'span', {'class' : 'mceText', title : o.settings.title}, o.settings.title);\r
5268 \r
5269                         if (o.settings.style)\r
5270                                 DOM.setAttrib(n, 'style', o.settings.style);\r
5271 \r
5272                         if (tb.childNodes.length == 1)\r
5273                                 DOM.addClass(ro, 'mceFirst');\r
5274 \r
5275                         if ((n = ro.previousSibling) && DOM.hasClass(n, cp + 'ItemSeparator'))\r
5276                                 DOM.addClass(ro, 'mceFirst');\r
5277 \r
5278                         if (o.collapse)\r
5279                                 DOM.addClass(ro, cp + 'ItemSub');\r
5280 \r
5281                         if (n = ro.previousSibling)\r
5282                                 DOM.removeClass(n, 'mceLast');\r
5283 \r
5284                         DOM.addClass(ro, 'mceLast');\r
5285                 }\r
5286 \r
5287                 });\r
5288 })();\r
5289 /* file:jscripts/tiny_mce/classes/ui/Button.js */\r
5290 \r
5291 (function() {\r
5292         var DOM = tinymce.DOM;\r
5293 \r
5294         tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {\r
5295                 Button : function(id, s) {\r
5296                         this.parent(id, s);\r
5297                         this.classPrefix = 'mceButton';\r
5298                 },\r
5299 \r
5300                 renderHTML : function() {\r
5301                         var cp = this.classPrefix, s = this.settings, h, l;\r
5302 \r
5303                         l = DOM.encode(s.label || '');\r
5304                         h = '<a id="' + this.id + '" href="javascript:;" class="' + cp + ' ' + cp + 'Enabled ' + s['class'] + (l ? ' ' + cp + 'Labeled' : '') +'" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">';\r
5305 \r
5306                         if (s.image)\r
5307                                 h += '<img class="mceIcon" src="' + s.image + '" />' + l + '</a>';\r
5308                         else\r
5309                                 h += '<span class="mceIcon ' + s['class'] + '"></span>' + (l ? '<span class="' + cp + 'Label">' + l + '</span>' : '') + '</a>';\r
5310 \r
5311                         return h;\r
5312                 },\r
5313 \r
5314                 postRender : function() {\r
5315                         var t = this, s = t.settings;\r
5316 \r
5317                         tinymce.dom.Event.add(t.id, 'click', function(e) {\r
5318                                 if (!t.isDisabled())\r
5319                                         return s.onclick.call(s.scope, e);\r
5320                         });\r
5321                 }\r
5322 \r
5323                 });\r
5324 })();\r
5325 \r
5326 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */\r
5327 \r
5328 (function() {\r
5329         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
5330 \r
5331         tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {\r
5332                 ListBox : function(id, s) {\r
5333                         var t = this;\r
5334 \r
5335                         t.parent(id, s);\r
5336                         t.items = [];\r
5337                         t.onChange = new Dispatcher(t);\r
5338                         t.onPostRender = new Dispatcher(t);\r
5339                         t.onAdd = new Dispatcher(t);\r
5340                         t.onRenderMenu = new tinymce.util.Dispatcher(this);\r
5341                         t.classPrefix = 'mceListBox';\r
5342                 },\r
5343 \r
5344                 select : function(v) {\r
5345                         var t = this, e, fv;\r
5346 \r
5347                         // Do we need to do something?\r
5348                         if (v != t.selectedValue) {\r
5349                                 e = DOM.get(t.id + '_text');\r
5350                                 t.selectedValue = v;\r
5351 \r
5352                                 // Find item\r
5353                                 each(t.items, function(o) {\r
5354                                         if (o.value == v) {\r
5355                                                 DOM.setHTML(e, DOM.encode(o.title));\r
5356                                                 fv = 1;\r
5357                                                 return false;\r
5358                                         }\r
5359                                 });\r
5360 \r
5361                                 // If no item was found then present title\r
5362                                 if (!fv) {\r
5363                                         DOM.setHTML(e, DOM.encode(t.settings.title));\r
5364                                         DOM.addClass(e, 'mceTitle');\r
5365                                         e = 0;\r
5366                                         return;\r
5367                                 } else\r
5368                                         DOM.removeClass(e, 'mceTitle');\r
5369                         }\r
5370 \r
5371                         e = 0;\r
5372                 },\r
5373 \r
5374                 add : function(n, v, o) {\r
5375                         var t = this;\r
5376 \r
5377                         o = o || {};\r
5378                         o = tinymce.extend(o, {\r
5379                                 title : n,\r
5380                                 value : v\r
5381                         });\r
5382 \r
5383                         t.items.push(o);\r
5384                         t.onAdd.dispatch(t, o);\r
5385                 },\r
5386 \r
5387                 getLength : function() {\r
5388                         return this.items.length;\r
5389                 },\r
5390 \r
5391                 renderHTML : function() {\r
5392                         var h = '', t = this, s = t.settings, cp = t.classPrefix;\r
5393 \r
5394                         h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="' + cp + ' ' + cp + 'Enabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';\r
5395                         h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'mceText', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>';\r
5396                         h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', tabindex : -1, href : 'javascript:;', 'class' : 'mceOpen', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>';\r
5397                         h += '</tr></tbody></table>';\r
5398 \r
5399                         return h;\r
5400                 },\r
5401 \r
5402                 showMenu : function() {\r
5403                         var t = this, p1, p2, e = DOM.get(this.id), m;\r
5404 \r
5405                         if (t.isDisabled() || t.items.length == 0)\r
5406                                 return;\r
5407 \r
5408                         if (t.menu && t.menu.isMenuVisible)\r
5409                                 return t.hideMenu();\r
5410 \r
5411                         if (!t.isMenuRendered) {\r
5412                                 t.renderMenu();\r
5413                                 t.isMenuRendered = true;\r
5414                         }\r
5415 \r
5416                         p1 = DOM.getPos(this.settings.menu_container);\r
5417                         p2 = DOM.getPos(e);\r
5418 \r
5419                         m = t.menu;\r
5420                         m.settings.offset_x = p2.x;\r
5421                         m.settings.offset_y = p2.y;\r
5422                         m.settings.keyboard_focus = !tinymce.isOpera; // Opera is buggy when it comes to auto focus\r
5423 \r
5424                         // Select in menu\r
5425                         if (t.oldID)\r
5426                                 m.items[t.oldID].setSelected(0);\r
5427 \r
5428                         each(t.items, function(o) {\r
5429                                 if (o.value === t.selectedValue) {\r
5430                                         m.items[o.id].setSelected(1);\r
5431                                         t.oldID = o.id;\r
5432                                 }\r
5433                         });\r
5434 \r
5435                         m.showMenu(0, e.clientHeight);\r
5436 \r
5437                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5438                         DOM.addClass(t.id, t.classPrefix + 'Selected');\r
5439 \r
5440                         //DOM.get(t.id + '_text').focus();\r
5441                 },\r
5442 \r
5443                 hideMenu : function(e) {\r
5444                         var t = this;\r
5445 \r
5446                         // Prevent double toogles by canceling the mouse click event to the button\r
5447                         if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))\r
5448                                 return;\r
5449 \r
5450                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
5451                                 DOM.removeClass(t.id, t.classPrefix + 'Selected');\r
5452                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5453 \r
5454                                 if (t.menu)\r
5455                                         t.menu.hideMenu();\r
5456                         }\r
5457                 },\r
5458 \r
5459                 renderMenu : function() {\r
5460                         var t = this, m;\r
5461 \r
5462                         m = t.settings.control_manager.createDropMenu(t.id + '_menu', {\r
5463                                 menu_line : 1,\r
5464                                 'class' : t.classPrefix + 'Menu mceNoIcons',\r
5465                                 max_width : 150,\r
5466                                 max_height : 150\r
5467                         });\r
5468 \r
5469                         m.onHideMenu.add(t.hideMenu, t);\r
5470 \r
5471                         m.add({\r
5472                                 title : t.settings.title,\r
5473                                 'class' : 'mceMenuItemTitle',\r
5474                                 onclick : function() {\r
5475                                         if (t.settings.onselect('') !== false)\r
5476                                                 t.select(''); // Must be runned after\r
5477                                 }\r
5478                         });\r
5479 \r
5480                         each(t.items, function(o) {\r
5481                                 o.id = DOM.uniqueId();\r
5482                                 o.onclick = function() {\r
5483                                         if (t.settings.onselect(o.value) !== false)\r
5484                                                 t.select(o.value); // Must be runned after\r
5485                                 };\r
5486 \r
5487                                 m.add(o);\r
5488                         });\r
5489 \r
5490                         t.onRenderMenu.dispatch(t, m);\r
5491                         t.menu = m;\r
5492                 },\r
5493 \r
5494                 postRender : function() {\r
5495                         var t = this, cp = t.classPrefix;\r
5496 \r
5497                         Event.add(t.id, 'click', t.showMenu, t);\r
5498                         Event.add(t.id + '_text', 'focus', function(e) {\r
5499                                 if (!t._focused) {\r
5500                                         t.keyDownHandler = Event.add(t.id + '_text', 'keydown', function(e) {\r
5501                                                 var idx = -1, v, kc = e.keyCode;\r
5502 \r
5503                                                 // Find current index\r
5504                                                 each(t.items, function(v, i) {\r
5505                                                         if (t.selectedValue == v.value)\r
5506                                                                 idx = i;\r
5507                                                 });\r
5508 \r
5509                                                 // Move up/down\r
5510                                                 if (kc == 38)\r
5511                                                         v = t.items[idx - 1];\r
5512                                                 else if (kc == 40)\r
5513                                                         v = t.items[idx + 1];\r
5514                                                 else if (kc == 13) {\r
5515                                                         // Fake select on enter\r
5516                                                         v = t.selectedValue;\r
5517                                                         t.selectedValue = null; // Needs to be null to fake change\r
5518                                                         t.settings.onselect(v);\r
5519                                                         return Event.cancel(e);\r
5520                                                 }\r
5521 \r
5522                                                 if (v) {\r
5523                                                         t.hideMenu();\r
5524                                                         t.select(v.value);\r
5525                                                 }\r
5526                                         });\r
5527                                 }\r
5528 \r
5529                                 t._focused = 1;\r
5530                         });\r
5531                         Event.add(t.id + '_text', 'blur', function() {Event.remove(t.id + '_text', 'keydown', t.keyDownHandler); t._focused = 0;});\r
5532 \r
5533                         // Old IE doesn't have hover on all elements\r
5534                         if (tinymce.isIE6 || !DOM.boxModel) {\r
5535                                 Event.add(t.id, 'mouseover', function() {\r
5536                                         if (!DOM.hasClass(t.id, cp + 'Disabled'))\r
5537                                                 DOM.addClass(t.id, cp + 'Hover');\r
5538                                 });\r
5539 \r
5540                                 Event.add(t.id, 'mouseout', function() {\r
5541                                         if (!DOM.hasClass(t.id, cp + 'Disabled'))\r
5542                                                 DOM.removeClass(t.id, cp + 'Hover');\r
5543                                 });\r
5544                         }\r
5545 \r
5546                         t.onPostRender.dispatch(t, DOM.get(t.id));\r
5547                 },\r
5548 \r
5549                 destroy : function() {\r
5550                         this.parent();\r
5551 \r
5552                         Event.clear(this.id + '_text');\r
5553                 }\r
5554 \r
5555                 });\r
5556 })();\r
5557 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */\r
5558 \r
5559 (function() {\r
5560         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
5561 \r
5562         tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {\r
5563                 NativeListBox : function(id, s) {\r
5564                         this.parent(id, s);\r
5565                         this.classPrefix = 'mceNativeListBox';\r
5566                 },\r
5567 \r
5568                 setDisabled : function(s) {\r
5569                         DOM.get(this.id).disabled = s;\r
5570                 },\r
5571 \r
5572                 isDisabled : function() {\r
5573                         return DOM.get(this.id).disabled;\r
5574                 },\r
5575 \r
5576                 select : function(v) {\r
5577                         var e = DOM.get(this.id), ol = e.options;\r
5578 \r
5579                         v = '' + (v || '');\r
5580 \r
5581                         e.selectedIndex = 0;\r
5582                         each(ol, function(o, i) {\r
5583                                 if (o.value == v) {\r
5584                                         e.selectedIndex = i;\r
5585                                         return false;\r
5586                                 }\r
5587                         });\r
5588                 },\r
5589 \r
5590                 add : function(n, v, a) {\r
5591                         var o, t = this;\r
5592 \r
5593                         a = a || {};\r
5594                         a.value = v;\r
5595 \r
5596                         if (t.isRendered())\r
5597                                 DOM.add(DOM.get(this.id), 'option', a, n);\r
5598 \r
5599                         o = {\r
5600                                 title : n,\r
5601                                 value : v,\r
5602                                 attribs : a\r
5603                         };\r
5604 \r
5605                         t.items.push(o);\r
5606                         t.onAdd.dispatch(t, o);\r
5607                 },\r
5608 \r
5609                 getLength : function() {\r
5610                         return DOM.get(this.id).options.length - 1;\r
5611                 },\r
5612 \r
5613                 renderHTML : function() {\r
5614                         var h, t = this;\r
5615 \r
5616                         h = DOM.createHTML('option', {value : ''}, '-- ' + t.settings.title + ' --');\r
5617 \r
5618                         each(t.items, function(it) {\r
5619                                 h += DOM.createHTML('option', {value : it.value}, it.title);\r
5620                         });\r
5621 \r
5622                         h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h);\r
5623 \r
5624                         return h;\r
5625                 },\r
5626 \r
5627                 postRender : function() {\r
5628                         var t = this, ch;\r
5629 \r
5630                         t.rendered = true;\r
5631 \r
5632                         function onChange(e) {\r
5633                                 var v = e.target.options[e.target.selectedIndex].value;\r
5634 \r
5635                                 t.onChange.dispatch(t, v);\r
5636 \r
5637                                 if (t.settings.onselect)\r
5638                                         t.settings.onselect(v);\r
5639                         };\r
5640 \r
5641                         Event.add(t.id, 'change', onChange);\r
5642 \r
5643                         // Accessibility keyhandler\r
5644                         Event.add(t.id, 'keydown', function(e) {\r
5645                                 var bf;\r
5646 \r
5647                                 Event.remove(t.id, 'change', ch);\r
5648 \r
5649                                 bf = Event.add(t.id, 'blur', function() {\r
5650                                         Event.add(t.id, 'change', onChange);\r
5651                                         Event.remove(t.id, 'blur', bf);\r
5652                                 });\r
5653 \r
5654                                 if (e.keyCode == 13 || e.keyCode == 32) {\r
5655                                         onChange(e);\r
5656                                         return Event.cancel(e);\r
5657                                 }\r
5658                         });\r
5659 \r
5660                         t.onPostRender.dispatch(t, DOM.get(t.id));\r
5661                 }\r
5662 \r
5663                 });\r
5664 })();\r
5665 /* file:jscripts/tiny_mce/classes/ui/MenuButton.js */\r
5666 \r
5667 (function() {\r
5668         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
5669 \r
5670         tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {\r
5671                 MenuButton : function(id, s) {\r
5672                         this.parent(id, s);\r
5673                         this.onRenderMenu = new tinymce.util.Dispatcher(this);\r
5674                         s.menu_container = s.menu_container || DOM.doc.body;\r
5675                 },\r
5676 \r
5677                 showMenu : function() {\r
5678                         var t = this, p1, p2, e = DOM.get(t.id), m;\r
5679 \r
5680                         if (t.isDisabled())\r
5681                                 return;\r
5682 \r
5683                         if (!t.isMenuRendered) {\r
5684                                 t.renderMenu();\r
5685                                 t.isMenuRendered = true;\r
5686                         }\r
5687 \r
5688                         if (t.isMenuVisible)\r
5689                                 return t.hideMenu();\r
5690 \r
5691                         p1 = DOM.getPos(t.settings.menu_container);\r
5692                         p2 = DOM.getPos(e);\r
5693 \r
5694                         m = t.menu;\r
5695                         m.settings.offset_x = p2.x;\r
5696                         m.settings.offset_y = p2.y;\r
5697                         m.settings.vp_offset_x = p2.x;\r
5698                         m.settings.vp_offset_y = p2.y;\r
5699                         m.settings.keyboard_focus = t._focused;\r
5700                         m.showMenu(0, e.clientHeight);\r
5701 \r
5702                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5703                         t.setState('Selected', 1);\r
5704 \r
5705                         t.isMenuVisible = 1;\r
5706                 },\r
5707 \r
5708                 renderMenu : function() {\r
5709                         var t = this, m;\r
5710 \r
5711                         m = t.settings.control_manager.createDropMenu(t.id + '_menu', {\r
5712                                 menu_line : 1,\r
5713                                 'class' : this.classPrefix + 'Menu',\r
5714                                 icons : t.settings.icons\r
5715                         });\r
5716 \r
5717                         m.onHideMenu.add(t.hideMenu, t);\r
5718 \r
5719                         t.onRenderMenu.dispatch(t, m);\r
5720                         t.menu = m;\r
5721                 },\r
5722 \r
5723                 hideMenu : function(e) {\r
5724                         var t = this;\r
5725 \r
5726                         // Prevent double toogles by canceling the mouse click event to the button\r
5727                         if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id || e.id === t.id + '_open';}))\r
5728                                 return;\r
5729 \r
5730                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
5731                                 t.setState('Selected', 0);\r
5732                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5733                                 if (t.menu)\r
5734                                         t.menu.hideMenu();\r
5735                         }\r
5736 \r
5737                         t.isMenuVisible = 0;\r
5738                 },\r
5739 \r
5740                 postRender : function() {\r
5741                         var t = this, s = t.settings;\r
5742 \r
5743                         Event.add(t.id, 'click', function() {\r
5744                                 if (!t.isDisabled()) {\r
5745                                         if (s.onclick)\r
5746                                                 s.onclick(t.value);\r
5747 \r
5748                                         t.showMenu();\r
5749                                 }\r
5750                         });\r
5751                 }\r
5752 \r
5753                 });\r
5754 })();\r
5755 \r
5756 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */\r
5757 \r
5758 (function() {\r
5759         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
5760 \r
5761         tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {\r
5762                 SplitButton : function(id, s) {\r
5763                         this.parent(id, s);\r
5764                         this.classPrefix = 'mceSplitButton';\r
5765                 },\r
5766 \r
5767                 renderHTML : function() {\r
5768                         var h, t = this, s = t.settings, h1;\r
5769 \r
5770                         h = '<tbody><tr>';\r
5771 \r
5772                         if (s.image)\r
5773                                 h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'mceAction ' + s['class']});\r
5774                         else\r
5775                                 h1 = DOM.createHTML('span', {'class' : 'mceAction ' + s['class']}, '');\r
5776 \r
5777                         h += '<td>' + DOM.createHTML('a', {id : t.id + '_action', href : 'javascript:;', 'class' : 'mceAction ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';\r
5778         \r
5779                         h1 = DOM.createHTML('span', {'class' : 'mceOpen ' + s['class']});\r
5780                         h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'mceOpen ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';\r
5781 \r
5782                         h += '</tr></tbody>';\r
5783 \r
5784                         return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);\r
5785                 },\r
5786 \r
5787                 postRender : function() {\r
5788                         var t = this, s = t.settings;\r
5789 \r
5790                         if (s.onclick) {\r
5791                                 Event.add(t.id + '_action', 'click', function() {\r
5792                                         if (!t.isDisabled())\r
5793                                                 s.onclick(t.value);\r
5794                                 });\r
5795                         }\r
5796 \r
5797                         Event.add(t.id + '_open', 'click', t.showMenu, t);\r
5798                         Event.add(t.id + '_open', 'focus', function() {t._focused = 1;});\r
5799                         Event.add(t.id + '_open', 'blur', function() {t._focused = 0;});\r
5800 \r
5801                         // Old IE doesn't have hover on all elements\r
5802                         if (tinymce.isIE6 || !DOM.boxModel) {\r
5803                                 Event.add(t.id, 'mouseover', function() {\r
5804                                         if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))\r
5805                                                 DOM.addClass(t.id, 'mceSplitButtonHover');\r
5806                                 });\r
5807 \r
5808                                 Event.add(t.id, 'mouseout', function() {\r
5809                                         if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))\r
5810                                                 DOM.removeClass(t.id, 'mceSplitButtonHover');\r
5811                                 });\r
5812                         }\r
5813                 },\r
5814 \r
5815                 destroy : function() {\r
5816                         this.parent();\r
5817 \r
5818                         Event.clear(this.id + '_action');\r
5819                         Event.clear(this.id + '_open');\r
5820                 }\r
5821 \r
5822                 });\r
5823 })();\r
5824 \r
5825 /* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */\r
5826 \r
5827 (function() {\r
5828         var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;\r
5829 \r
5830         tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {\r
5831                 ColorSplitButton : function(id, s) {\r
5832                         var t = this;\r
5833 \r
5834                         t.parent(id, s);\r
5835 \r
5836                         t.settings = s = tinymce.extend({\r
5837                                 colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF',\r
5838                                 grid_width : 8,\r
5839                                 default_color : '#888888'\r
5840                         }, t.settings);\r
5841 \r
5842                         t.onShowMenu = new tinymce.util.Dispatcher(t);\r
5843                         t.onHideMenu = new tinymce.util.Dispatcher(t);\r
5844 \r
5845                         t.value = s.default_color;\r
5846                 },\r
5847 \r
5848                 showMenu : function() {\r
5849                         var t = this, r, p, e, p2;\r
5850 \r
5851                         if (t.isDisabled())\r
5852                                 return;\r
5853 \r
5854                         if (!t.isMenuRendered) {\r
5855                                 t.renderMenu();\r
5856                                 t.isMenuRendered = true;\r
5857                         }\r
5858 \r
5859                         if (t.isMenuVisible)\r
5860                                 return t.hideMenu();\r
5861 \r
5862                         e = DOM.get(t.id);\r
5863                         DOM.show(t.id + '_menu');\r
5864                         DOM.addClass(e, 'mceSplitButtonSelected');\r
5865                         p2 = DOM.getPos(e);\r
5866                         DOM.setStyles(t.id + '_menu', {\r
5867                                 left : p2.x,\r
5868                                 top : p2.y + e.clientHeight,\r
5869                                 zIndex : 200000\r
5870                         });\r
5871                         e = 0;\r
5872 \r
5873                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5874 \r
5875                         if (t._focused) {\r
5876                                 t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {\r
5877                                         if (e.keyCode == 27)\r
5878                                                 t.hideMenu();\r
5879                                 });\r
5880 \r
5881                                 DOM.select('a', t.id + '_menu')[0].focus(); // Select first link\r
5882                         }\r
5883 \r
5884                         t.onShowMenu.dispatch(t);\r
5885 \r
5886                         t.isMenuVisible = 1;\r
5887                 },\r
5888 \r
5889                 hideMenu : function(e) {\r
5890                         var t = this;\r
5891 \r
5892                         // Prevent double toogles by canceling the mouse click event to the button\r
5893                         if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))\r
5894                                 return;\r
5895 \r
5896                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {\r
5897                                 DOM.removeClass(t.id, 'mceSplitButtonSelected');\r
5898                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5899                                 Event.remove(t.id + '_menu', 'keydown', t._keyHandler);\r
5900                                 DOM.hide(t.id + '_menu');\r
5901                         }\r
5902 \r
5903                         t.onHideMenu.dispatch(t);\r
5904 \r
5905                         t.isMenuVisible = 0;\r
5906                 },\r
5907 \r
5908                 renderMenu : function() {\r
5909                         var t = this, m, i = 0, s = t.settings, n, tb, tr, w;\r
5910 \r
5911                         w = DOM.add(s.menu_container, 'div', {id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});\r
5912                         m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});\r
5913                         DOM.add(m, 'span', {'class' : 'mceMenuLine'});\r
5914 \r
5915                         n = DOM.add(m, 'table', {'class' : 'mceColorSplitMenu'});\r
5916                         tb = DOM.add(n, 'tbody');\r
5917 \r
5918                         // Generate color grid\r
5919                         i = 0;\r
5920                         each(is(s.colors, 'array') ? s.colors : s.colors.split(','), function(c) {\r
5921                                 c = c.replace(/^#/, '');\r
5922 \r
5923                                 if (!i--) {\r
5924                                         tr = DOM.add(tb, 'tr');\r
5925                                         i = s.grid_width - 1;\r
5926                                 }\r
5927 \r
5928                                 n = DOM.add(tr, 'td');\r
5929 \r
5930                                 n = DOM.add(n, 'a', {\r
5931                                         href : 'javascript:;',\r
5932                                         style : {\r
5933                                                 backgroundColor : '#' + c\r
5934                                         },\r
5935                                         mce_color : '#' + c\r
5936                                 });\r
5937                         });\r
5938 \r
5939                         if (s.more_colors_func) {\r
5940                                 n = DOM.add(tb, 'tr');\r
5941                                 n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'mceMoreColors'});\r
5942                                 n = DOM.add(n, 'a', {id : t.id + '_more', href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);\r
5943 \r
5944                                 Event.add(n, 'click', function(e) {\r
5945                                         s.more_colors_func.call(s.more_colors_scope || this);\r
5946                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem\r
5947                                 });\r
5948                         }\r
5949 \r
5950                         DOM.addClass(m, 'mceColorSplitMenu');\r
5951 \r
5952                         Event.add(t.id + '_menu', 'click', function(e) {\r
5953                                 var c;\r
5954 \r
5955                                 e = e.target;\r
5956 \r
5957                                 if (e.nodeName == 'A' && (c = e.getAttribute('mce_color')))\r
5958                                         t.setColor(c);\r
5959 \r
5960                                 return Event.cancel(e); // Prevent IE auto save warning\r
5961                         });\r
5962 \r
5963                         return w;\r
5964                 },\r
5965 \r
5966                 setColor : function(c) {\r
5967                         var t = this;\r
5968 \r
5969                         DOM.setStyle(t.id + '_preview', 'backgroundColor', c);\r
5970 \r
5971                         t.value = c;\r
5972                         t.hideMenu();\r
5973                         t.settings.onselect(c);\r
5974                 },\r
5975 \r
5976                 postRender : function() {\r
5977                         var t = this, id = t.id;\r
5978 \r
5979                         t.parent();\r
5980                         DOM.add(id + '_action', 'div', {id : id + '_preview', 'class' : 'mceColorPreview'});\r
5981                 },\r
5982 \r
5983                 destroy : function() {\r
5984                         this.parent();\r
5985 \r
5986                         Event.clear(this.id + '_menu');\r
5987                         Event.clear(this.id + '_more');\r
5988                         DOM.remove(this.id + '_menu');\r
5989                 }\r
5990 \r
5991                 });\r
5992 })();\r
5993 \r
5994 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */\r
5995 \r
5996 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {\r
5997         renderHTML : function() {\r
5998                 var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl;\r
5999 \r
6000                 cl = t.controls;\r
6001                 for (i=0; i<cl.length; i++) {\r
6002                         // Get current control, prev control, next control and if the control is a list box or not\r
6003                         co = cl[i];\r
6004                         pr = cl[i - 1];\r
6005                         nx = cl[i + 1];\r
6006 \r
6007                         // Add toolbar start\r
6008                         if (i === 0) {\r
6009                                 c = 'mceToolbarStart';\r
6010 \r
6011                                 if (co.Button)\r
6012                                         c += ' mceToolbarStartButton';\r
6013                                 else if (co.SplitButton)\r
6014                                         c += ' mceToolbarStartSplitButton';\r
6015                                 else if (co.ListBox)\r
6016                                         c += ' mceToolbarStartListBox';\r
6017 \r
6018                                 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
6019                         }\r
6020 \r
6021                         // Add toolbar end before list box and after the previous button\r
6022                         // This is to fix the o2k7 editor skins\r
6023                         if (pr && co.ListBox) {\r
6024                                 if (pr.Button || pr.SplitButton)\r
6025                                         h += dom.createHTML('td', {'class' : 'mceToolbarEnd'}, dom.createHTML('span', null, '<!-- IE -->'));\r
6026                         }\r
6027 \r
6028                         // Render control HTML\r
6029 \r
6030                         // IE 8 quick fix, needed to propertly generate a hit area for anchors\r
6031                         if (dom.stdMode)\r
6032                                 h += '<td style="position: relative">' + co.renderHTML() + '</td>';\r
6033                         else\r
6034                                 h += '<td>' + co.renderHTML() + '</td>';\r
6035 \r
6036                         // Add toolbar start after list box and before the next button\r
6037                         // This is to fix the o2k7 editor skins\r
6038                         if (nx && co.ListBox) {\r
6039                                 if (nx.Button || nx.SplitButton)\r
6040                                         h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->'));\r
6041                         }\r
6042                 }\r
6043 \r
6044                 c = 'mceToolbarEnd';\r
6045 \r
6046                 if (co.Button)\r
6047                         c += ' mceToolbarEndButton';\r
6048                 else if (co.SplitButton)\r
6049                         c += ' mceToolbarEndSplitButton';\r
6050                 else if (co.ListBox)\r
6051                         c += ' mceToolbarEndListBox';\r
6052 \r
6053                 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
6054 \r
6055                 return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '<tbody><tr>' + h + '</tr></tbody>');\r
6056         }\r
6057 \r
6058         });\r
6059 \r
6060 /* file:jscripts/tiny_mce/classes/AddOnManager.js */\r
6061 \r
6062 (function() {\r
6063         var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;\r
6064 \r
6065         tinymce.create('tinymce.AddOnManager', {\r
6066                 items : [],\r
6067                 urls : {},\r
6068                 lookup : {},\r
6069                 onAdd : new Dispatcher(this),\r
6070 \r
6071                 get : function(n) {\r
6072                         return this.lookup[n];\r
6073                 },\r
6074 \r
6075                 requireLangPack : function(n) {\r
6076                         var u, s;\r
6077 \r
6078                         if (tinymce.EditorManager.settings) {\r
6079                                 u = this.urls[n] + '/langs/' + tinymce.EditorManager.settings.language + '.js';\r
6080                                 s = tinymce.EditorManager.settings;\r
6081 \r
6082                                 if (s) {\r
6083                                         if (!tinymce.dom.Event.domLoaded && !s.strict_mode)\r
6084                                                 tinymce.ScriptLoader.load(u);\r
6085                                         else\r
6086                                                 tinymce.ScriptLoader.add(u);\r
6087                                 }\r
6088                         }\r
6089                 },\r
6090 \r
6091                 add : function(id, o) {\r
6092                         this.items.push(o);\r
6093                         this.lookup[id] = o;\r
6094                         this.onAdd.dispatch(this, id, o);\r
6095 \r
6096                         return o;\r
6097                 },\r
6098 \r
6099                 load : function(n, u, cb, s) {\r
6100                         var t = this;\r
6101 \r
6102                         if (t.urls[n])\r
6103                                 return;\r
6104 \r
6105                         if (u.indexOf('/') != 0 && u.indexOf('://') == -1)\r
6106                                 u = tinymce.baseURL + '/' +  u;\r
6107 \r
6108                         t.urls[n] = u.substring(0, u.lastIndexOf('/'));\r
6109                         tinymce.ScriptLoader.add(u, cb, s);\r
6110                 }\r
6111 \r
6112                 });\r
6113 \r
6114         // Create plugin and theme managers\r
6115         tinymce.PluginManager = new tinymce.AddOnManager();\r
6116         tinymce.ThemeManager = new tinymce.AddOnManager();\r
6117 }());\r
6118 /* file:jscripts/tiny_mce/classes/EditorManager.js */\r
6119 \r
6120 (function() {\r
6121         // Shorten names\r
6122         var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;\r
6123 \r
6124         tinymce.create('static tinymce.EditorManager', {\r
6125                 editors : {},\r
6126                 i18n : {},\r
6127                 activeEditor : null,\r
6128 \r
6129                 preInit : function() {\r
6130                         var t = this, lo = window.location;\r
6131 \r
6132                         // Setup some URLs where the editor API is located and where the document is\r
6133                         tinymce.documentBaseURL = lo.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');\r
6134                         if (!/[\/\\]$/.test(tinymce.documentBaseURL))\r
6135                                 tinymce.documentBaseURL += '/';\r
6136 \r
6137                         tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);\r
6138                         tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);\r
6139 \r
6140                         // Setup document domain\r
6141                         if (tinymce.EditorManager.baseURI.host != lo.hostname && lo.hostname)\r
6142                                 document.domain = tinymce.relaxedDomain = lo.hostname.replace(/.*\.(.+\..+)$/, '$1');\r
6143 \r
6144                         // Add before unload listener\r
6145                         // This was required since IE was leaking memory if you added and removed beforeunload listeners\r
6146                         // with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event\r
6147                         t.onBeforeUnload = new tinymce.util.Dispatcher(t);\r
6148 \r
6149                         // Must be on window or IE will leak if the editor is placed in frame or iframe\r
6150                         Event.add(window, 'beforeunload', function(e) {\r
6151                                 t.onBeforeUnload.dispatch(t, e);\r
6152                         });\r
6153                 },\r
6154 \r
6155                 init : function(s) {\r
6156                         var t = this, pl, sl = tinymce.ScriptLoader, c, e;\r
6157 \r
6158                         function execCallback(se, n, s) {\r
6159                                 var f = se[n];\r
6160 \r
6161                                 if (!f)\r
6162                                         return;\r
6163 \r
6164                                 if (tinymce.is(f, 'string')) {\r
6165                                         s = f.replace(/\.\w+$/, '');\r
6166                                         s = s ? tinymce.resolve(s) : 0;\r
6167                                         f = tinymce.resolve(f);\r
6168                                 }\r
6169 \r
6170                                 return f.apply(s || this, Array.prototype.slice.call(arguments, 2));\r
6171                         };\r
6172 \r
6173                         s = extend({\r
6174                                 theme : "simple",\r
6175                                 language : "en",\r
6176                                 strict_loading_mode : document.contentType == 'application/xhtml+xml'\r
6177                         }, s);\r
6178 \r
6179                         t.settings = s;\r
6180 \r
6181                         // If page not loaded and strict mode isn't enabled then load them\r
6182                         if (!Event.domLoaded && !s.strict_loading_mode) {\r
6183                                 // Load language\r
6184                                 if (s.language)\r
6185                                         sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
6186 \r
6187                                 // Load theme\r
6188                                 if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
6189                                         ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
6190 \r
6191                                 // Load plugins\r
6192                                 if (s.plugins) {\r
6193                                         pl = explode(s.plugins);\r
6194 \r
6195                                         // Load compat2x first\r
6196                                         if (tinymce.inArray(pl, 'compat2x') != -1)\r
6197                                                 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');\r
6198 \r
6199                                         // Load rest if plugins\r
6200                                         each(pl, function(v) {\r
6201                                                 if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) {\r
6202                                                         // Skip safari plugin for other browsers\r
6203                                                         if (!tinymce.isWebKit && v == 'safari')\r
6204                                                                 return;\r
6205 \r
6206                                                         PluginManager.load(v, 'plugins/' + v + '/editor_plugin' + tinymce.suffix + '.js');\r
6207                                                 }\r
6208                                         });\r
6209                                 }\r
6210 \r
6211                                 sl.loadQueue();\r
6212                         }\r
6213 \r
6214                         // Legacy call\r
6215                         Event.add(document, 'init', function() {\r
6216                                 var l, co;\r
6217 \r
6218                                 execCallback(s, 'onpageload');\r
6219 \r
6220                                 // Verify that it's a valid browser\r
6221                                 if (s.browsers) {\r
6222                                         l = false;\r
6223 \r
6224                                         each(explode(s.browsers), function(v) {\r
6225                                                 switch (v) {\r
6226                                                         case 'ie':\r
6227                                                         case 'msie':\r
6228                                                                 if (tinymce.isIE)\r
6229                                                                         l = true;\r
6230                                                                 break;\r
6231 \r
6232                                                         case 'gecko':\r
6233                                                                 if (tinymce.isGecko)\r
6234                                                                         l = true;\r
6235                                                                 break;\r
6236 \r
6237                                                         case 'safari':\r
6238                                                         case 'webkit':\r
6239                                                                 if (tinymce.isWebKit)\r
6240                                                                         l = true;\r
6241                                                                 break;\r
6242 \r
6243                                                         case 'opera':\r
6244                                                                 if (tinymce.isOpera)\r
6245                                                                         l = true;\r
6246 \r
6247                                                                 break;\r
6248                                                 }\r
6249                                         });\r
6250 \r
6251                                         // Not a valid one\r
6252                                         if (!l)\r
6253                                                 return;\r
6254                                 }\r
6255 \r
6256                                 switch (s.mode) {\r
6257                                         case "exact":\r
6258                                                 l = s.elements || '';\r
6259 \r
6260                                                 if(l.length > 0) {\r
6261                                                         each(explode(l), function(v) {\r
6262                                                                 if (DOM.get(v))\r
6263                                                                         new tinymce.Editor(v, s).render(1);\r
6264                                                                 else {\r
6265                                                                         c = 0;\r
6266 \r
6267                                                                         each(document.forms, function(f) {\r
6268                                                                                 each(f.elements, function(e) {\r
6269                                                                                         if (e.name === v) {\r
6270                                                                                                 v = 'mce_editor_' + c;\r
6271                                                                                                 DOM.setAttrib(e, 'id', v);\r
6272                                                                                                 new tinymce.Editor(v, s).render(1);\r
6273                                                                                         }\r
6274                                                                                 });\r
6275                                                                         });\r
6276                                                                 }\r
6277                                                         });\r
6278                                                 }\r
6279                                                 break;\r
6280 \r
6281                                         case "textareas":\r
6282                                         case "specific_textareas":\r
6283                                                 function hasClass(n, c) {\r
6284                                                         return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);\r
6285                                                 };\r
6286 \r
6287                                                 each(DOM.select('textarea'), function(v) {\r
6288                                                         if (s.editor_deselector && hasClass(v, s.editor_deselector))\r
6289                                                                 return;\r
6290 \r
6291                                                         if (!s.editor_selector || hasClass(v, s.editor_selector)) {\r
6292                                                                 // Can we use the name\r
6293                                                                 e = DOM.get(v.name);\r
6294                                                                 if (!v.id && !e)\r
6295                                                                         v.id = v.name;\r
6296 \r
6297                                                                 // Generate unique name if missing or already exists\r
6298                                                                 if (!v.id || t.get(v.id))\r
6299                                                                         v.id = DOM.uniqueId();\r
6300 \r
6301                                                                 new tinymce.Editor(v.id, s).render(1);\r
6302                                                         }\r
6303                                                 });\r
6304                                                 break;\r
6305                                 }\r
6306 \r
6307                                 // Call onInit when all editors are initialized\r
6308                                 if (s.oninit) {\r
6309                                         l = co = 0;\r
6310 \r
6311                                         each (t.editors, function(ed) {\r
6312                                                 co++;\r
6313 \r
6314                                                 if (!ed.initialized) {\r
6315                                                         // Wait for it\r
6316                                                         ed.onInit.add(function() {\r
6317                                                                 l++;\r
6318 \r
6319                                                                 // All done\r
6320                                                                 if (l == co)\r
6321                                                                         execCallback(s, 'oninit');\r
6322                                                         });\r
6323                                                 } else\r
6324                                                         l++;\r
6325 \r
6326                                                 // All done\r
6327                                                 if (l == co)\r
6328                                                         execCallback(s, 'oninit');                                      \r
6329                                         });\r
6330                                 }\r
6331                         });\r
6332                 },\r
6333 \r
6334                 get : function(id) {\r
6335                         return this.editors[id];\r
6336                 },\r
6337 \r
6338                 getInstanceById : function(id) {\r
6339                         return this.get(id);\r
6340                 },\r
6341 \r
6342                 add : function(e) {\r
6343                         this.editors[e.id] = e;\r
6344                         this._setActive(e);\r
6345 \r
6346                         return e;\r
6347                 },\r
6348 \r
6349                 remove : function(e) {\r
6350                         var t = this;\r
6351 \r
6352                         // Not in the collection\r
6353                         if (!t.editors[e.id])\r
6354                                 return null;\r
6355 \r
6356                         delete t.editors[e.id];\r
6357 \r
6358                         // Select another editor since the active one was removed\r
6359                         if (t.activeEditor == e) {\r
6360                                 each(t.editors, function(e) {\r
6361                                         t._setActive(e);\r
6362                                         return false; // Break\r
6363                                 });\r
6364                         }\r
6365 \r
6366                         e.destroy();\r
6367 \r
6368                         return e;\r
6369                 },\r
6370 \r
6371                 execCommand : function(c, u, v) {\r
6372                         var t = this, ed = t.get(v), w;\r
6373 \r
6374                         // Manager commands\r
6375                         switch (c) {\r
6376                                 case "mceFocus":\r
6377                                         ed.focus();\r
6378                                         return true;\r
6379 \r
6380                                 case "mceAddEditor":\r
6381                                 case "mceAddControl":\r
6382                                         if (!t.get(v))\r
6383                                                 new tinymce.Editor(v, t.settings).render();\r
6384 \r
6385                                         return true;\r
6386 \r
6387                                 case "mceAddFrameControl":\r
6388                                         w = v.window;\r
6389 \r
6390                                         // Add tinyMCE global instance and tinymce namespace to specified window\r
6391                                         w.tinyMCE = tinyMCE;\r
6392                                         w.tinymce = tinymce;\r
6393 \r
6394                                         tinymce.DOM.doc = w.document;\r
6395                                         tinymce.DOM.win = w;\r
6396 \r
6397                                         ed = new tinymce.Editor(v.element_id, v);\r
6398                                         ed.render();\r
6399 \r
6400                                         // Fix IE memory leaks\r
6401                                         if (tinymce.isIE) {\r
6402                                                 function clr() {\r
6403                                                         ed.destroy();\r
6404                                                         w.detachEvent('onunload', clr);\r
6405                                                         w = w.tinyMCE = w.tinymce = null; // IE leak\r
6406                                                 };\r
6407 \r
6408                                                 w.attachEvent('onunload', clr);\r
6409                                         }\r
6410 \r
6411                                         v.page_window = null;\r
6412 \r
6413                                         return true;\r
6414 \r
6415                                 case "mceRemoveEditor":\r
6416                                 case "mceRemoveControl":\r
6417                                         ed.remove();\r
6418                                         return true;\r
6419 \r
6420                                 case 'mceToggleEditor':\r
6421                                         if (!ed) {\r
6422                                                 t.execCommand('mceAddControl', 0, v);\r
6423                                                 return true;\r
6424                                         }\r
6425 \r
6426                                         if (ed.isHidden())\r
6427                                                 ed.show();\r
6428                                         else\r
6429                                                 ed.hide();\r
6430 \r
6431                                         return true;\r
6432                         }\r
6433 \r
6434                         // Run command on active editor\r
6435                         if (t.activeEditor)\r
6436                                 return t.activeEditor.execCommand(c, u, v);\r
6437 \r
6438                         return false;\r
6439                 },\r
6440 \r
6441                 execInstanceCommand : function(id, c, u, v) {\r
6442                         var ed = this.get(id);\r
6443 \r
6444                         if (ed)\r
6445                                 return ed.execCommand(c, u, v);\r
6446 \r
6447                         return false;\r
6448                 },\r
6449 \r
6450                 triggerSave : function() {\r
6451                         each(this.editors, function(e) {\r
6452                                 e.save();\r
6453                         });\r
6454                 },\r
6455 \r
6456                 addI18n : function(p, o) {\r
6457                         var lo, i18n = this.i18n;\r
6458 \r
6459                         if (!tinymce.is(p, 'string')) {\r
6460                                 each(p, function(o, lc) {\r
6461                                         each(o, function(o, g) {\r
6462                                                 each(o, function(o, k) {\r
6463                                                         if (g === 'common')\r
6464                                                                 i18n[lc + '.' + k] = o;\r
6465                                                         else\r
6466                                                                 i18n[lc + '.' + g + '.' + k] = o;\r
6467                                                 });\r
6468                                         });\r
6469                                 });\r
6470                         } else {\r
6471                                 each(o, function(o, k) {\r
6472                                         i18n[p + '.' + k] = o;\r
6473                                 });\r
6474                         }\r
6475                 },\r
6476 \r
6477                 // Private methods\r
6478 \r
6479                 _setActive : function(e) {\r
6480                         this.selectedInstance = this.activeEditor = e;\r
6481                 }\r
6482 \r
6483                 });\r
6484 \r
6485         tinymce.EditorManager.preInit();\r
6486 })();\r
6487 \r
6488 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call\r
6489 var tinyMCE = window.tinyMCE = tinymce.EditorManager;\r
6490 \r
6491 /* file:jscripts/tiny_mce/classes/Editor.js */\r
6492 \r
6493 (function() {\r
6494         var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;\r
6495         var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;\r
6496         var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;\r
6497         var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;\r
6498 \r
6499         tinymce.create('tinymce.Editor', {\r
6500                 Editor : function(id, s) {\r
6501                         var t = this;\r
6502 \r
6503                         t.id = t.editorId = id;\r
6504                         t.execCommands = {};\r
6505                         t.queryStateCommands = {};\r
6506                         t.queryValueCommands = {};\r
6507                         t.plugins = {};\r
6508 \r
6509                         // Add events to the editor\r
6510                         each([\r
6511                                 'onPreInit',\r
6512                                 'onBeforeRenderUI',\r
6513                                 'onPostRender',\r
6514                                 'onInit',\r
6515                                 'onRemove',\r
6516                                 'onActivate',\r
6517                                 'onDeactivate',\r
6518                                 'onClick',\r
6519                                 'onEvent',\r
6520                                 'onMouseUp',\r
6521                                 'onMouseDown',\r
6522                                 'onDblClick',\r
6523                                 'onKeyDown',\r
6524                                 'onKeyUp',\r
6525                                 'onKeyPress',\r
6526                                 'onContextMenu',\r
6527                                 'onSubmit',\r
6528                                 'onReset',\r
6529                                 'onPaste',\r
6530                                 'onPreProcess',\r
6531                                 'onPostProcess',\r
6532                                 'onBeforeSetContent',\r
6533                                 'onBeforeGetContent',\r
6534                                 'onSetContent',\r
6535                                 'onGetContent',\r
6536                                 'onLoadContent',\r
6537                                 'onSaveContent',\r
6538                                 'onNodeChange',\r
6539                                 'onChange',\r
6540                                 'onBeforeExecCommand',\r
6541                                 'onExecCommand',\r
6542                                 'onUndo',\r
6543                                 'onRedo',\r
6544                                 'onVisualAid',\r
6545                                 'onSetProgressState'\r
6546                         ], function(e) {\r
6547                                 t[e] = new Dispatcher(t);\r
6548                         });\r
6549 \r
6550                         // Default editor config\r
6551                         t.settings = s = extend({\r
6552                                 id : id,\r
6553                                 language : 'en',\r
6554                                 docs_language : 'en',\r
6555                                 theme : 'simple',\r
6556                                 skin : 'default',\r
6557                                 delta_width : 0,\r
6558                                 delta_height : 0,\r
6559                                 popup_css : '',\r
6560                                 plugins : '',\r
6561                                 document_base_url : tinymce.documentBaseURL,\r
6562                                 add_form_submit_trigger : 1,\r
6563                                 submit_patch : 1,\r
6564                                 add_unload_trigger : 1,\r
6565                                 convert_urls : 1,\r
6566                                 relative_urls : 1,\r
6567                                 remove_script_host : 1,\r
6568                                 table_inline_editing : 0,\r
6569                                 object_resizing : 1,\r
6570                                 cleanup : 1,\r
6571                                 accessibility_focus : 1,\r
6572                                 custom_shortcuts : 1,\r
6573                                 custom_undo_redo_keyboard_shortcuts : 1,\r
6574                                 custom_undo_redo_restore_selection : 1,\r
6575                                 custom_undo_redo : 1,\r
6576                                 doctype : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',\r
6577                                 visual_table_class : 'mceItemTable',\r
6578                                 visual : 1,\r
6579                                 inline_styles : true,\r
6580                                 convert_fonts_to_spans : true,\r
6581                                 font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',\r
6582                                 apply_source_formatting : 1,\r
6583                                 directionality : 'ltr',\r
6584                                 forced_root_block : 'p',\r
6585                                 valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',\r
6586                                 hidden_input : 1,\r
6587                                 padd_empty_editor : 1,\r
6588                                 render_ui : 1,\r
6589                                 init_theme : 1,\r
6590                                 force_p_newlines : 1,\r
6591                                 indentation : '30px'\r
6592                         }, s);\r
6593 \r
6594                         // Setup URIs\r
6595                         t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {\r
6596                                 base_uri : tinyMCE.baseURI\r
6597                         });\r
6598                         t.baseURI = EditorManager.baseURI;\r
6599 \r
6600                         // Call setup\r
6601                         t.execCallback('setup', t);\r
6602                 },\r
6603 \r
6604                 render : function(nst) {\r
6605                         var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;\r
6606 \r
6607                         // Page is not loaded yet, wait for it\r
6608                         if (!Event.domLoaded) {\r
6609                                 Event.add(document, 'init', function() {\r
6610                                         t.render();\r
6611                                 });\r
6612                                 return;\r
6613                         }\r
6614 \r
6615                         // Force strict loading mode if render us called by user and not internally\r
6616                         if (!nst) {\r
6617                                 s.strict_loading_mode = 1;\r
6618                                 tinyMCE.settings = s;\r
6619                         }\r
6620 \r
6621                         // Element not found, then skip initialization\r
6622                         if (!t.getElement())\r
6623                                 return;\r
6624 \r
6625                         if (s.strict_loading_mode) {\r
6626                                 sl.settings.strict_mode = s.strict_loading_mode;\r
6627                                 tinymce.DOM.settings.strict = 1;\r
6628                         }\r
6629 \r
6630                         // Add hidden input for non input elements inside form elements\r
6631                         if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))\r
6632                                 DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);\r
6633 \r
6634                         t.windowManager = new tinymce.WindowManager(t);\r
6635 \r
6636                         if (s.encoding == 'xml') {\r
6637                                 t.onGetContent.add(function(ed, o) {\r
6638                                         if (o.save)\r
6639                                                 o.content = DOM.encode(o.content);\r
6640                                 });\r
6641                         }\r
6642 \r
6643                         if (s.add_form_submit_trigger) {\r
6644                                 t.onSubmit.addToTop(function() {\r
6645                                         if (t.initialized) {\r
6646                                                 t.save();\r
6647                                                 t.isNotDirty = 1;\r
6648                                         }\r
6649                                 });\r
6650                         }\r
6651 \r
6652                         if (s.add_unload_trigger && !s.ask) {\r
6653                                 t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {\r
6654                                         if (t.initialized && !t.destroyed && !t.isHidden())\r
6655                                                 t.save({format : 'raw', no_events : true});\r
6656                                 });\r
6657                         }\r
6658 \r
6659                         tinymce.addUnload(t.destroy, t);\r
6660 \r
6661                         if (s.submit_patch) {\r
6662                                 t.onBeforeRenderUI.add(function() {\r
6663                                         var n = t.getElement().form;\r
6664 \r
6665                                         if (!n)\r
6666                                                 return;\r
6667 \r
6668                                         // Already patched\r
6669                                         if (n._mceOldSubmit)\r
6670                                                 return;\r
6671 \r
6672                                         // Check page uses id="submit" or name="submit" for it's submit button\r
6673                                         if (!n.submit.nodeType && !n.submit.length) {\r
6674                                                 t.formElement = n;\r
6675                                                 n._mceOldSubmit = n.submit;\r
6676                                                 n.submit = function() {\r
6677                                                         // Save all instances\r
6678                                                         EditorManager.triggerSave();\r
6679                                                         t.isNotDirty = 1;\r
6680 \r
6681                                                         return this._mceOldSubmit(this);\r
6682                                                 };\r
6683                                         }\r
6684 \r
6685                                         n = null;\r
6686                                 });\r
6687                         }\r
6688 \r
6689                         // Load scripts\r
6690                         function loadScripts() {\r
6691                                 if (s.language)\r
6692                                         sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
6693 \r
6694                                 if (s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
6695                                         ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
6696 \r
6697                                 each(explode(s.plugins), function(p) {\r
6698                                         if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) {\r
6699                                                 // Skip safari plugin for other browsers\r
6700                                                 if (!isWebKit && p == 'safari')\r
6701                                                         return;\r
6702 \r
6703                                                 PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js');\r
6704                                         }\r
6705                                 });\r
6706 \r
6707                                 // Init when que is loaded\r
6708                                 sl.loadQueue(function() {\r
6709                                         if (s.ask) {\r
6710                                                 function ask() {\r
6711                                                         // Yield for awhile to avoid focus bug on FF 3 when cancel is pressed\r
6712                                                         window.setTimeout(function() {\r
6713                                                                 Event.remove(t.id, 'focus', ask);\r
6714 \r
6715                                                                 t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {\r
6716                                                                         if (s)\r
6717                                                                                 t.init();\r
6718                                                                 });\r
6719                                                         }, 0);\r
6720                                                 };\r
6721 \r
6722                                                 Event.add(t.id, 'focus', ask);\r
6723                                                 return;\r
6724                                         }\r
6725 \r
6726                                         if (!t.removed)\r
6727                                                 t.init();\r
6728                                 });\r
6729                         };\r
6730 \r
6731                         // Load compat2x first\r
6732                         if (s.plugins.indexOf('compat2x') != -1) {\r
6733                                 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');\r
6734                                 sl.loadQueue(loadScripts);\r
6735                         } else\r
6736                                 loadScripts();\r
6737                 },\r
6738 \r
6739                 init : function() {\r
6740                         var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;\r
6741 \r
6742                         EditorManager.add(t);\r
6743 \r
6744                         // Create theme\r
6745                         s.theme = s.theme.replace(/-/, '');\r
6746                         o = ThemeManager.get(s.theme);\r
6747                         t.theme = new o();\r
6748 \r
6749                         if (t.theme.init && s.init_theme)\r
6750                                 t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));\r
6751 \r
6752                         // Create all plugins\r
6753                         each(explode(s.plugins.replace(/\-/g, '')), function(p) {\r
6754                                 var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;\r
6755 \r
6756                                 if (c) {\r
6757                                         po = new c(t, u);\r
6758 \r
6759                                         t.plugins[p] = po;\r
6760 \r
6761                                         if (po.init)\r
6762                                                 po.init(t, u);\r
6763                                 }\r
6764                         });\r
6765 \r
6766                         // Setup popup CSS path(s)\r
6767                         if (s.popup_css)\r
6768                                 s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);\r
6769                         else\r
6770                                 s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");\r
6771 \r
6772                         if (s.popup_css_add)\r
6773                                 s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);\r
6774 \r
6775                         // Setup control factory\r
6776                         t.controlManager = new tinymce.ControlManager(t);\r
6777                         t.undoManager = new tinymce.UndoManager(t);\r
6778 \r
6779                         // Pass through\r
6780                         t.undoManager.onAdd.add(function(um, l) {\r
6781                                 if (!l.initial)\r
6782                                         return t.onChange.dispatch(t, l, um);\r
6783                         });\r
6784 \r
6785                         t.undoManager.onUndo.add(function(um, l) {\r
6786                                 return t.onUndo.dispatch(t, l, um);\r
6787                         });\r
6788 \r
6789                         t.undoManager.onRedo.add(function(um, l) {\r
6790                                 return t.onRedo.dispatch(t, l, um);\r
6791                         });\r
6792 \r
6793                         if (s.custom_undo_redo) {\r
6794                                 t.onExecCommand.add(function(ed, cmd, ui, val, a) {\r
6795                                         if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))\r
6796                                                 t.undoManager.add();\r
6797                                 });\r
6798                         }\r
6799 \r
6800                         t.onExecCommand.add(function(ed, c) {\r
6801                                 // Don't refresh the select lists until caret move\r
6802                                 if (!/^(FontName|FontSize)$/.test(c))\r
6803                                         t.nodeChanged();\r
6804                         });\r
6805 \r
6806                         // Remove ghost selections on images and tables in Gecko\r
6807                         if (isGecko) {\r
6808                                 function repaint(a, o) {\r
6809                                         if (!o || !o.initial)\r
6810                                                 t.execCommand('mceRepaint');\r
6811                                 };\r
6812 \r
6813                                 t.onUndo.add(repaint);\r
6814                                 t.onRedo.add(repaint);\r
6815                                 t.onSetContent.add(repaint);\r
6816                         }\r
6817 \r
6818                         // Enables users to override the control factory\r
6819                         t.onBeforeRenderUI.dispatch(t, t.controlManager);\r
6820 \r
6821                         // Measure box\r
6822                         if (s.render_ui) {\r
6823                                 w = s.width || e.style.width || e.offsetWidth;\r
6824                                 h = s.height || e.style.height || e.offsetHeight;\r
6825                                 t.orgDisplay = e.style.display;\r
6826                                 re = /^[0-9\.]+(|px)$/i;\r
6827 \r
6828                                 if (re.test('' + w))\r
6829                                         w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);\r
6830 \r
6831                                 if (re.test('' + h))\r
6832                                         h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);\r
6833 \r
6834                                 // Render UI\r
6835                                 o = t.theme.renderUI({\r
6836                                         targetNode : e,\r
6837                                         width : w,\r
6838                                         height : h,\r
6839                                         deltaWidth : s.delta_width,\r
6840                                         deltaHeight : s.delta_height\r
6841                                 });\r
6842 \r
6843                                 t.editorContainer = o.editorContainer;\r
6844                         }\r
6845 \r
6846                         \r
6847                         // Resize editor\r
6848                         DOM.setStyles(o.sizeContainer || o.editorContainer, {\r
6849                                 width : w,\r
6850                                 height : h\r
6851                         });\r
6852 \r
6853                         h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');\r
6854                         if (h < 100)\r
6855                                 h = 100;\r
6856 \r
6857                         t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" />';\r
6858                         t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';\r
6859 \r
6860                         if (tinymce.relaxedDomain)\r
6861                                 t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';\r
6862 \r
6863                         bi = s.body_id || 'tinymce';\r
6864                         if (bi.indexOf('=') != -1) {\r
6865                                 bi = t.getParam('body_id', '', 'hash');\r
6866                                 bi = bi[t.id] || bi;\r
6867                         }\r
6868 \r
6869                         bc = s.body_class || '';\r
6870                         if (bc.indexOf('=') != -1) {\r
6871                                 bc = t.getParam('body_class', '', 'hash');\r
6872                                 bc = bc[t.id] || '';\r
6873                         }\r
6874 \r
6875                         t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';\r
6876 \r
6877                         // Domain relaxing enabled, then set document domain\r
6878                         if (tinymce.relaxedDomain) {\r
6879                                 // We need to write the contents here in IE since multiple writes messes up refresh button and back button\r
6880                                 if (isIE)\r
6881                                         u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';\r
6882                                 else if (tinymce.isOpera)\r
6883                                         u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';                                  \r
6884                         }\r
6885 \r
6886                         // Create iframe\r
6887                         n = DOM.add(o.iframeContainer, 'iframe', {\r
6888                                 id : t.id + "_ifr",\r
6889                                 src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7\r
6890                                 frameBorder : '0',\r
6891                                 style : {\r
6892                                         width : '100%',\r
6893                                         height : h\r
6894                                 }\r
6895                         });\r
6896 \r
6897                         t.contentAreaContainer = o.iframeContainer;\r
6898                         DOM.get(o.editorContainer).style.display = t.orgDisplay;\r
6899                         DOM.get(t.id).style.display = 'none';\r
6900 \r
6901                         // Safari 2.x requires us to wait for the load event and load a real HTML doc\r
6902                         if (tinymce.isOldWebKit) {\r
6903                                 Event.add(n, 'load', t.setupIframe, t);\r
6904                                 n.src = tinymce.baseURL + '/plugins/safari/blank.htm';\r
6905                         } else {\r
6906                                 if (!isIE || !tinymce.relaxedDomain)\r
6907                                         t.setupIframe();\r
6908 \r
6909                                 e = n = o = null; // Cleanup\r
6910                         }\r
6911                 },\r
6912 \r
6913                 setupIframe : function() {\r
6914                         var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;\r
6915 \r
6916                         // Setup iframe body\r
6917                         if (!isIE || !tinymce.relaxedDomain) {\r
6918                                 d.open();\r
6919                                 d.write(t.iframeHTML);\r
6920                                 d.close();\r
6921                         }\r
6922 \r
6923                         // Design mode needs to be added here Ctrl+A will fail otherwise\r
6924                         if (!isIE) {\r
6925                                 try {\r
6926                                         d.designMode = 'On';\r
6927                                 } catch (ex) {\r
6928                                         // Will fail on Gecko if the editor is placed in an hidden container element\r
6929                                         // The design mode will be set ones the editor is focused\r
6930                                 }\r
6931                         }\r
6932 \r
6933                         // IE needs to use contentEditable or it will display non secure items for HTTPS\r
6934                         if (isIE) {\r
6935                                 // It will not steal focus if we hide it while setting contentEditable\r
6936                                 b = t.getBody();\r
6937                                 DOM.hide(b);\r
6938                                 b.contentEditable = true;\r
6939                                 DOM.show(b);\r
6940                         }\r
6941 \r
6942                         // Setup objects\r
6943                         t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {\r
6944                                 keep_values : true,\r
6945                                 url_converter : t.convertURL,\r
6946                                 url_converter_scope : t,\r
6947                                 hex_colors : s.force_hex_style_colors,\r
6948                                 class_filter : s.class_filter,\r
6949                                 update_styles : 1,\r
6950                                 fix_ie_paragraphs : 1\r
6951                         });\r
6952 \r
6953                         t.serializer = new tinymce.dom.Serializer({\r
6954                                 entity_encoding : s.entity_encoding,\r
6955                                 entities : s.entities,\r
6956                                 valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,\r
6957                                 extended_valid_elements : s.extended_valid_elements,\r
6958                                 valid_child_elements : s.valid_child_elements,\r
6959                                 invalid_elements : s.invalid_elements,\r
6960                                 fix_table_elements : s.fix_table_elements,\r
6961                                 fix_list_elements : s.fix_list_elements,\r
6962                                 fix_content_duplication : s.fix_content_duplication,\r
6963                                 convert_fonts_to_spans : s.convert_fonts_to_spans,\r
6964                                 font_size_classes  : s.font_size_classes,\r
6965                                 font_size_style_values : s.font_size_style_values,\r
6966                                 apply_source_formatting : s.apply_source_formatting,\r
6967                                 remove_linebreaks : s.remove_linebreaks,\r
6968                                 dom : t.dom\r
6969                         });\r
6970 \r
6971                         t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);\r
6972                         t.forceBlocks = new tinymce.ForceBlocks(t, {\r
6973                                 forced_root_block : s.forced_root_block\r
6974                         });\r
6975                         t.editorCommands = new tinymce.EditorCommands(t);\r
6976 \r
6977                         // Pass through\r
6978                         t.serializer.onPreProcess.add(function(se, o) {\r
6979                                 return t.onPreProcess.dispatch(t, o, se);\r
6980                         });\r
6981 \r
6982                         t.serializer.onPostProcess.add(function(se, o) {\r
6983                                 return t.onPostProcess.dispatch(t, o, se);\r
6984                         });\r
6985 \r
6986                         t.onPreInit.dispatch(t);\r
6987 \r
6988                         if (!s.gecko_spellcheck)\r
6989                                 t.getBody().spellcheck = 0;\r
6990 \r
6991                         t._addEvents();\r
6992 \r
6993                         t.controlManager.onPostRender.dispatch(t, t.controlManager);\r
6994                         t.onPostRender.dispatch(t);\r
6995 \r
6996                         if (s.directionality)\r
6997                                 t.getBody().dir = s.directionality;\r
6998 \r
6999                         if (s.nowrap)\r
7000                                 t.getBody().style.whiteSpace = "nowrap";\r
7001 \r
7002                         if (s.auto_resize)\r
7003                                 t.onNodeChange.add(t.resizeToContent, t);\r
7004 \r
7005                         if (s.custom_elements) {\r
7006                                 function handleCustom(ed, o) {\r
7007                                         each(explode(s.custom_elements), function(v) {\r
7008                                                 var n;\r
7009 \r
7010                                                 if (v.indexOf('~') === 0) {\r
7011                                                         v = v.substring(1);\r
7012                                                         n = 'span';\r
7013                                                 } else\r
7014                                                         n = 'div';\r
7015 \r
7016                                                 o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' mce_name="$1"$2>');\r
7017                                                 o.content = o.content.replace(new RegExp('</(' + v + ')>', 'g'), '</' + n + '>');\r
7018                                         });\r
7019                                 };\r
7020 \r
7021                                 t.onBeforeSetContent.add(handleCustom);\r
7022                                 t.onPostProcess.add(function(ed, o) {\r
7023                                         if (o.set)\r
7024                                                 handleCustom(ed, o)\r
7025                                 });\r
7026                         }\r
7027 \r
7028                         if (s.handle_node_change_callback) {\r
7029                                 t.onNodeChange.add(function(ed, cm, n) {\r
7030                                         t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());\r
7031                                 });\r
7032                         }\r
7033 \r
7034                         if (s.save_callback) {\r
7035                                 t.onSaveContent.add(function(ed, o) {\r
7036                                         var h = t.execCallback('save_callback', t.id, o.content, t.getBody());\r
7037 \r
7038                                         if (h)\r
7039                                                 o.content = h;\r
7040                                 });\r
7041                         }\r
7042 \r
7043                         if (s.onchange_callback) {\r
7044                                 t.onChange.add(function(ed, l) {\r
7045                                         t.execCallback('onchange_callback', t, l);\r
7046                                 });\r
7047                         }\r
7048 \r
7049                         if (s.convert_newlines_to_brs) {\r
7050                                 t.onBeforeSetContent.add(function(ed, o) {\r
7051                                         if (o.initial)\r
7052                                                 o.content = o.content.replace(/\r?\n/g, '<br />');\r
7053                                 });\r
7054                         }\r
7055 \r
7056                         if (s.fix_nesting && isIE) {\r
7057                                 t.onBeforeSetContent.add(function(ed, o) {\r
7058                                         o.content = t._fixNesting(o.content);\r
7059                                 });\r
7060                         }\r
7061 \r
7062                         if (s.preformatted) {\r
7063                                 t.onPostProcess.add(function(ed, o) {\r
7064                                         o.content = o.content.replace(/^\s*<pre.*?>/, '');\r
7065                                         o.content = o.content.replace(/<\/pre>\s*$/, '');\r
7066 \r
7067                                         if (o.set)\r
7068                                                 o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';\r
7069                                 });\r
7070                         }\r
7071 \r
7072                         if (s.verify_css_classes) {\r
7073                                 t.serializer.attribValueFilter = function(n, v) {\r
7074                                         var s, cl;\r
7075 \r
7076                                         if (n == 'class') {\r
7077                                                 // Build regexp for classes\r
7078                                                 if (!t.classesRE) {\r
7079                                                         cl = t.dom.getClasses();\r
7080 \r
7081                                                         if (cl.length > 0) {\r
7082                                                                 s = '';\r
7083 \r
7084                                                                 each (cl, function(o) {\r
7085                                                                         s += (s ? '|' : '') + o['class'];\r
7086                                                                 });\r
7087 \r
7088                                                                 t.classesRE = new RegExp('(' + s + ')', 'gi');\r
7089                                                         }\r
7090                                                 }\r
7091 \r
7092                                                 return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';\r
7093                                         }\r
7094 \r
7095                                         return v;\r
7096                                 };\r
7097                         }\r
7098 \r
7099                         if (s.convert_fonts_to_spans)\r
7100                                 t._convertFonts();\r
7101 \r
7102                         if (s.inline_styles)\r
7103                                 t._convertInlineElements();\r
7104 \r
7105                         if (s.cleanup_callback) {\r
7106                                 t.onBeforeSetContent.add(function(ed, o) {\r
7107                                         o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);\r
7108                                 });\r
7109 \r
7110                                 t.onPreProcess.add(function(ed, o) {\r
7111                                         if (o.set)\r
7112                                                 t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);\r
7113 \r
7114                                         if (o.get)\r
7115                                                 t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);\r
7116                                 });\r
7117 \r
7118                                 t.onPostProcess.add(function(ed, o) {\r
7119                                         if (o.set)\r
7120                                                 o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);\r
7121 \r
7122                                         if (o.get)                                              \r
7123                                                 o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);\r
7124                                 });\r
7125                         }\r
7126 \r
7127                         if (s.save_callback) {\r
7128                                 t.onGetContent.add(function(ed, o) {\r
7129                                         if (o.save)\r
7130                                                 o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());\r
7131                                 });\r
7132                         }\r
7133 \r
7134                         if (s.handle_event_callback) {\r
7135                                 t.onEvent.add(function(ed, e, o) {\r
7136                                         if (t.execCallback('handle_event_callback', e, ed, o) === false)\r
7137                                                 Event.cancel(e);\r
7138                                 });\r
7139                         }\r
7140 \r
7141                         t.onSetContent.add(function() {\r
7142                                 // Safari needs some time, it will crash the browser when a link is created otherwise\r
7143                                 // I think this crash issue is resolved in the latest 3.0.4\r
7144                                 //window.setTimeout(function() {\r
7145                                         t.addVisual(t.getBody());\r
7146                                 //}, 1);\r
7147                         });\r
7148 \r
7149                         // Remove empty contents\r
7150                         if (s.padd_empty_editor) {\r
7151                                 t.onPostProcess.add(function(ed, o) {\r
7152                                         o.content = o.content.replace(/^(<p>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');\r
7153                                 });\r
7154                         }\r
7155 \r
7156                         if (isGecko) {\r
7157                                 try {\r
7158                                         // Design mode must be set here once again to fix a bug where\r
7159                                         // Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again\r
7160                                         d.designMode = 'Off';\r
7161                                         d.designMode = 'On';\r
7162                                 } catch (ex) {\r
7163                                         // Will fail on Gecko if the editor is placed in an hidden container element\r
7164                                         // The design mode will be set ones the editor is focused\r
7165                                 }\r
7166                         }\r
7167 \r
7168                         // A small timeout was needed since firefox will remove. Bug: #1838304\r
7169                         setTimeout(function () {\r
7170                                 if (t.removed)\r
7171                                         return;\r
7172 \r
7173                                 t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});\r
7174                                 t.startContent = t.getContent({format : 'raw'});\r
7175                                 t.undoManager.add({initial : true});\r
7176                                 t.initialized = true;\r
7177 \r
7178                                 t.onInit.dispatch(t);\r
7179                                 t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());\r
7180                                 t.execCallback('init_instance_callback', t);\r
7181                                 t.focus(true);\r
7182                                 t.nodeChanged({initial : 1});\r
7183 \r
7184                                 // Load specified content CSS last\r
7185                                 if (s.content_css) {\r
7186                                         tinymce.each(explode(s.content_css), function(u) {\r
7187                                                 t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));\r
7188                                         });\r
7189                                 }\r
7190 \r
7191                                 // Handle auto focus\r
7192                                 if (s.auto_focus) {\r
7193                                         setTimeout(function () {\r
7194                                                 var ed = EditorManager.get(s.auto_focus);\r
7195 \r
7196                                                 ed.selection.select(ed.getBody(), 1);\r
7197                                                 ed.selection.collapse(1);\r
7198                                                 ed.getWin().focus();\r
7199                                         }, 100);\r
7200                                 }\r
7201                         }, 1);\r
7202         \r
7203                         e = null;\r
7204                 },\r
7205 \r
7206                 \r
7207                 focus : function(sf) {\r
7208                         var oed, t = this, ce = t.settings.content_editable;\r
7209 \r
7210                         if (!sf) {\r
7211                                 // Is not content editable or the selection is outside the area in IE\r
7212                                 // the IE statement is needed to avoid bluring if element selections inside layers since\r
7213                                 // the layer is like it's own document in IE\r
7214                                 if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc()))\r
7215                                         t.getWin().focus();\r
7216 \r
7217                                                         }\r
7218 \r
7219                         if (EditorManager.activeEditor != t) {\r
7220                                 if ((oed = EditorManager.activeEditor) != null)\r
7221                                         oed.onDeactivate.dispatch(oed, t);\r
7222 \r
7223                                 t.onActivate.dispatch(t, oed);\r
7224                         }\r
7225 \r
7226                         EditorManager._setActive(t);\r
7227                 },\r
7228 \r
7229                 execCallback : function(n) {\r
7230                         var t = this, f = t.settings[n], s;\r
7231 \r
7232                         if (!f)\r
7233                                 return;\r
7234 \r
7235                         // Look through lookup\r
7236                         if (t.callbackLookup && (s = t.callbackLookup[n])) {\r
7237                                 f = s.func;\r
7238                                 s = s.scope;\r
7239                         }\r
7240 \r
7241                         if (is(f, 'string')) {\r
7242                                 s = f.replace(/\.\w+$/, '');\r
7243                                 s = s ? tinymce.resolve(s) : 0;\r
7244                                 f = tinymce.resolve(f);\r
7245                                 t.callbackLookup = t.callbackLookup || {};\r
7246                                 t.callbackLookup[n] = {func : f, scope : s};\r
7247                         }\r
7248 \r
7249                         return f.apply(s || t, Array.prototype.slice.call(arguments, 1));\r
7250                 },\r
7251 \r
7252                 translate : function(s) {\r
7253                         var c = this.settings.language, i18n = EditorManager.i18n;\r
7254 \r
7255                         if (!s)\r
7256                                 return '';\r
7257 \r
7258                         return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {\r
7259                                 return i18n[c + '.' + b] || '{#' + b + '}';\r
7260                         });\r
7261                 },\r
7262 \r
7263                 getLang : function(n, dv) {\r
7264                         return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');\r
7265                 },\r
7266 \r
7267                 getParam : function(n, dv, ty) {\r
7268                         var tr = tinymce.trim, v = is(this.settings[n]) ? this.settings[n] : dv, o;\r
7269 \r
7270                         if (ty === 'hash') {\r
7271                                 o = {};\r
7272 \r
7273                                 if (is(v, 'string')) {\r
7274                                         each(v.indexOf('=') > 0 ? v.split(/[;,](?![^=;,]*(?:[;,]|$))/) : v.split(','), function(v) {\r
7275                                                 v = v.split('=');\r
7276 \r
7277                                                 if (v.length > 1)\r
7278                                                         o[tr(v[0])] = tr(v[1]);\r
7279                                                 else\r
7280                                                         o[tr(v[0])] = tr(v);\r
7281                                         });\r
7282                                 } else\r
7283                                         o = v;\r
7284 \r
7285                                 return o;\r
7286                         }\r
7287 \r
7288                         return v;\r
7289                 },\r
7290 \r
7291                 nodeChanged : function(o) {\r
7292                         var t = this, s = t.selection, n = s.getNode() || t.getBody();\r
7293 \r
7294                         // Fix for bug #1896577 it seems that this can not be fired while the editor is loading\r
7295                         if (t.initialized) {\r
7296                                 t.onNodeChange.dispatch(\r
7297                                         t,\r
7298                                         o ? o.controlManager || t.controlManager : t.controlManager,\r
7299                                         isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n, // Fix for IE initial state\r
7300                                         s.isCollapsed(),\r
7301                                         o\r
7302                                 );\r
7303                         }\r
7304                 },\r
7305 \r
7306                 addButton : function(n, s) {\r
7307                         var t = this;\r
7308 \r
7309                         t.buttons = t.buttons || {};\r
7310                         t.buttons[n] = s;\r
7311                 },\r
7312 \r
7313                 addCommand : function(n, f, s) {\r
7314                         this.execCommands[n] = {func : f, scope : s || this};\r
7315                 },\r
7316 \r
7317                 addQueryStateHandler : function(n, f, s) {\r
7318                         this.queryStateCommands[n] = {func : f, scope : s || this};\r
7319                 },\r
7320 \r
7321                 addQueryValueHandler : function(n, f, s) {\r
7322                         this.queryValueCommands[n] = {func : f, scope : s || this};\r
7323                 },\r
7324 \r
7325                 addShortcut : function(pa, desc, cmd_func, sc) {\r
7326                         var t = this, c;\r
7327 \r
7328                         if (!t.settings.custom_shortcuts)\r
7329                                 return false;\r
7330 \r
7331                         t.shortcuts = t.shortcuts || {};\r
7332 \r
7333                         if (is(cmd_func, 'string')) {\r
7334                                 c = cmd_func;\r
7335 \r
7336                                 cmd_func = function() {\r
7337                                         t.execCommand(c, false, null);\r
7338                                 };\r
7339                         }\r
7340 \r
7341                         if (is(cmd_func, 'object')) {\r
7342                                 c = cmd_func;\r
7343 \r
7344                                 cmd_func = function() {\r
7345                                         t.execCommand(c[0], c[1], c[2]);\r
7346                                 };\r
7347                         }\r
7348 \r
7349                         each(explode(pa), function(pa) {\r
7350                                 var o = {\r
7351                                         func : cmd_func,\r
7352                                         scope : sc || this,\r
7353                                         desc : desc,\r
7354                                         alt : false,\r
7355                                         ctrl : false,\r
7356                                         shift : false\r
7357                                 };\r
7358 \r
7359                                 each(explode(pa, '+'), function(v) {\r
7360                                         switch (v) {\r
7361                                                 case 'alt':\r
7362                                                 case 'ctrl':\r
7363                                                 case 'shift':\r
7364                                                         o[v] = true;\r
7365                                                         break;\r
7366 \r
7367                                                 default:\r
7368                                                         o.charCode = v.charCodeAt(0);\r
7369                                                         o.keyCode = v.toUpperCase().charCodeAt(0);\r
7370                                         }\r
7371                                 });\r
7372 \r
7373                                 t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o;\r
7374                         });\r
7375 \r
7376                         return true;\r
7377                 },\r
7378 \r
7379                 execCommand : function(cmd, ui, val, a) {\r
7380                         var t = this, s = 0, o, st;\r
7381 \r
7382                         if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus))\r
7383                                 t.focus();\r
7384 \r
7385                         o = {};\r
7386                         t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o);\r
7387                         if (o.terminate)\r
7388                                 return false;\r
7389 \r
7390                         // Command callback\r
7391                         if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) {\r
7392                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7393                                 return true;\r
7394                         }\r
7395 \r
7396                         // Registred commands\r
7397                         if (o = t.execCommands[cmd]) {\r
7398                                 st = o.func.call(o.scope, ui, val);\r
7399 \r
7400                                 // Fall through on true\r
7401                                 if (st !== true) {\r
7402                                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7403                                         return st;\r
7404                                 }\r
7405                         }\r
7406 \r
7407                         // Plugin commands\r
7408                         each(t.plugins, function(p) {\r
7409                                 if (p.execCommand && p.execCommand(cmd, ui, val)) {\r
7410                                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7411                                         s = 1;\r
7412                                         return false;\r
7413                                 }\r
7414                         });\r
7415 \r
7416                         if (s)\r
7417                                 return true;\r
7418 \r
7419                         // Theme commands\r
7420                         if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {\r
7421                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7422                                 return true;\r
7423                         }\r
7424 \r
7425                         // Editor commands\r
7426                         if (t.editorCommands.execCommand(cmd, ui, val)) {\r
7427                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7428                                 return true;\r
7429                         }\r
7430 \r
7431                         // Browser commands\r
7432                         t.getDoc().execCommand(cmd, ui, val);\r
7433                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7434                 },\r
7435 \r
7436                 queryCommandState : function(c) {\r
7437                         var t = this, o, s;\r
7438 \r
7439                         // Is hidden then return undefined\r
7440                         if (t._isHidden())\r
7441                                 return;\r
7442 \r
7443                         // Registred commands\r
7444                         if (o = t.queryStateCommands[c]) {\r
7445                                 s = o.func.call(o.scope);\r
7446 \r
7447                                 // Fall though on true\r
7448                                 if (s !== true)\r
7449                                         return s;\r
7450                         }\r
7451 \r
7452                         // Registred commands\r
7453                         o = t.editorCommands.queryCommandState(c);\r
7454                         if (o !== -1)\r
7455                                 return o;\r
7456 \r
7457                         // Browser commands\r
7458                         try {\r
7459                                 return this.getDoc().queryCommandState(c);\r
7460                         } catch (ex) {\r
7461                                 // Fails sometimes see bug: 1896577\r
7462                         }\r
7463                 },\r
7464 \r
7465                 queryCommandValue : function(c) {\r
7466                         var t = this, o, s;\r
7467 \r
7468                         // Is hidden then return undefined\r
7469                         if (t._isHidden())\r
7470                                 return;\r
7471 \r
7472                         // Registred commands\r
7473                         if (o = t.queryValueCommands[c]) {\r
7474                                 s = o.func.call(o.scope);\r
7475 \r
7476                                 // Fall though on true\r
7477                                 if (s !== true)\r
7478                                         return s;\r
7479                         }\r
7480 \r
7481                         // Registred commands\r
7482                         o = t.editorCommands.queryCommandValue(c);\r
7483                         if (is(o))\r
7484                                 return o;\r
7485 \r
7486                         // Browser commands\r
7487                         try {\r
7488                                 return this.getDoc().queryCommandValue(c);\r
7489                         } catch (ex) {\r
7490                                 // Fails sometimes see bug: 1896577\r
7491                         }\r
7492                 },\r
7493 \r
7494                 show : function() {\r
7495                         var t = this;\r
7496 \r
7497                         DOM.show(t.getContainer());\r
7498                         DOM.hide(t.id);\r
7499                         t.load();\r
7500                 },\r
7501 \r
7502                 hide : function() {\r
7503                         var t = this, d = t.getDoc();\r
7504 \r
7505                         // Fixed bug where IE has a blinking cursor left from the editor\r
7506                         if (isIE && d)\r
7507                                 d.execCommand('SelectAll');\r
7508 \r
7509                         // We must save before we hide so Safari doesn't crash\r
7510                         t.save();\r
7511                         DOM.hide(t.getContainer());\r
7512                         DOM.setStyle(t.id, 'display', t.orgDisplay);\r
7513                 },\r
7514 \r
7515                 isHidden : function() {\r
7516                         return !DOM.isHidden(this.id);\r
7517                 },\r
7518 \r
7519                 setProgressState : function(b, ti, o) {\r
7520                         this.onSetProgressState.dispatch(this, b, ti, o);\r
7521 \r
7522                         return b;\r
7523                 },\r
7524 \r
7525                 resizeToContent : function() {\r
7526                         var t = this;\r
7527 \r
7528                         DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight);\r
7529                 },\r
7530 \r
7531                 load : function(o) {\r
7532                         var t = this, e = t.getElement(), h;\r
7533 \r
7534                         o = o || {};\r
7535                         o.load = true;\r
7536 \r
7537                         h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);\r
7538                         o.element = e;\r
7539 \r
7540                         if (!o.no_events)\r
7541                                 t.onLoadContent.dispatch(t, o);\r
7542 \r
7543                         o.element = e = null;\r
7544 \r
7545                         return h;\r
7546                 },\r
7547 \r
7548                 save : function(o) {\r
7549                         var t = this, e = t.getElement(), h, f;\r
7550 \r
7551                         if (!t.initialized)\r
7552                                 return;\r
7553 \r
7554                         o = o || {};\r
7555                         o.save = true;\r
7556 \r
7557                         // Add undo level will trigger onchange event\r
7558                         if (!o.no_events) {\r
7559                                 t.undoManager.typing = 0;\r
7560                                 t.undoManager.add();\r
7561                         }\r
7562 \r
7563                         o.element = e;\r
7564                         h = o.content = t.getContent(o);\r
7565 \r
7566                         if (!o.no_events)\r
7567                                 t.onSaveContent.dispatch(t, o);\r
7568 \r
7569                         h = o.content;\r
7570 \r
7571                         if (!/TEXTAREA|INPUT/i.test(e.nodeName)) {\r
7572                                 e.innerHTML = h;\r
7573 \r
7574                                 // Update hidden form element\r
7575                                 if (f = DOM.getParent(t.id, 'form')) {\r
7576                                         each(f.elements, function(e) {\r
7577                                                 if (e.name == t.id) {\r
7578                                                         e.value = h;\r
7579                                                         return false;\r
7580                                                 }\r
7581                                         });\r
7582                                 }\r
7583                         } else\r
7584                                 e.value = h;\r
7585 \r
7586                         o.element = e = null;\r
7587 \r
7588                         return h;\r
7589                 },\r
7590 \r
7591                 setContent : function(h, o) {\r
7592                         var t = this;\r
7593 \r
7594                         o = o || {};\r
7595                         o.format = o.format || 'html';\r
7596                         o.set = true;\r
7597                         o.content = h;\r
7598 \r
7599                         if (!o.no_events)\r
7600                                 t.onBeforeSetContent.dispatch(t, o);\r
7601 \r
7602                         // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content\r
7603                         // It will also be impossible to place the caret in the editor unless there is a BR element present\r
7604                         if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {\r
7605                                 o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />');\r
7606                                 o.format = 'raw';\r
7607                         }\r
7608 \r
7609                         o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content));\r
7610 \r
7611                         if (o.format != 'raw' && t.settings.cleanup) {\r
7612                                 o.getInner = true;\r
7613                                 o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));\r
7614                         }\r
7615 \r
7616                         if (!o.no_events)\r
7617                                 t.onSetContent.dispatch(t, o);\r
7618 \r
7619                         return o.content;\r
7620                 },\r
7621 \r
7622                 getContent : function(o) {\r
7623                         var t = this, h;\r
7624 \r
7625                         o = o || {};\r
7626                         o.format = o.format || 'html';\r
7627                         o.get = true;\r
7628 \r
7629                         if (!o.no_events)\r
7630                                 t.onBeforeGetContent.dispatch(t, o);\r
7631 \r
7632                         if (o.format != 'raw' && t.settings.cleanup) {\r
7633                                 o.getInner = true;\r
7634                                 h = t.serializer.serialize(t.getBody(), o);\r
7635                         } else\r
7636                                 h = t.getBody().innerHTML;\r
7637 \r
7638                         h = h.replace(/^\s*|\s*$/g, '');\r
7639                         o.content = h;\r
7640 \r
7641                         if (!o.no_events)\r
7642                                 t.onGetContent.dispatch(t, o);\r
7643 \r
7644                         return o.content;\r
7645                 },\r
7646 \r
7647                 isDirty : function() {\r
7648                         var t = this;\r
7649 \r
7650                         return tinymce.trim(t.startContent) != tinymce.trim(t.getContent({format : 'raw', no_events : 1})) && !t.isNotDirty;\r
7651                 },\r
7652 \r
7653                 getContainer : function() {\r
7654                         var t = this;\r
7655 \r
7656                         if (!t.container)\r
7657                                 t.container = DOM.get(t.editorContainer || t.id + '_parent');\r
7658 \r
7659                         return t.container;\r
7660                 },\r
7661 \r
7662                 getContentAreaContainer : function() {\r
7663                         return this.contentAreaContainer;\r
7664                 },\r
7665 \r
7666                 getElement : function() {\r
7667                         return DOM.get(this.settings.content_element || this.id);\r
7668                 },\r
7669 \r
7670                 getWin : function() {\r
7671                         var t = this, e;\r
7672 \r
7673                         if (!t.contentWindow) {\r
7674                                 e = DOM.get(t.id + "_ifr");\r
7675 \r
7676                                 if (e)\r
7677                                         t.contentWindow = e.contentWindow;\r
7678                         }\r
7679 \r
7680                         return t.contentWindow;\r
7681                 },\r
7682 \r
7683                 getDoc : function() {\r
7684                         var t = this, w;\r
7685 \r
7686                         if (!t.contentDocument) {\r
7687                                 w = t.getWin();\r
7688 \r
7689                                 if (w)\r
7690                                         t.contentDocument = w.document;\r
7691                         }\r
7692 \r
7693                         return t.contentDocument;\r
7694                 },\r
7695 \r
7696                 getBody : function() {\r
7697                         return this.bodyElement || this.getDoc().body;\r
7698                 },\r
7699 \r
7700                 convertURL : function(u, n, e) {\r
7701                         var t = this, s = t.settings;\r
7702 \r
7703                         // Use callback instead\r
7704                         if (s.urlconverter_callback)\r
7705                                 return t.execCallback('urlconverter_callback', u, e, true, n);\r
7706 \r
7707                         // Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs\r
7708                         if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0)\r
7709                                 return u;\r
7710 \r
7711                         // Convert to relative\r
7712                         if (s.relative_urls)\r
7713                                 return t.documentBaseURI.toRelative(u);\r
7714 \r
7715                         // Convert to absolute\r
7716                         u = t.documentBaseURI.toAbsolute(u, s.remove_script_host);\r
7717 \r
7718                         return u;\r
7719                 },\r
7720 \r
7721                 addVisual : function(e) {\r
7722                         var t = this, s = t.settings;\r
7723 \r
7724                         e = e || t.getBody();\r
7725 \r
7726                         if (!is(t.hasVisual))\r
7727                                 t.hasVisual = s.visual;\r
7728 \r
7729                         each(t.dom.select('table,a', e), function(e) {\r
7730                                 var v;\r
7731 \r
7732                                 switch (e.nodeName) {\r
7733                                         case 'TABLE':\r
7734                                                 v = t.dom.getAttrib(e, 'border');\r
7735 \r
7736                                                 if (!v || v == '0') {\r
7737                                                         if (t.hasVisual)\r
7738                                                                 t.dom.addClass(e, s.visual_table_class);\r
7739                                                         else\r
7740                                                                 t.dom.removeClass(e, s.visual_table_class);\r
7741                                                 }\r
7742 \r
7743                                                 return;\r
7744 \r
7745                                         case 'A':\r
7746                                                 v = t.dom.getAttrib(e, 'name');\r
7747 \r
7748                                                 if (v) {\r
7749                                                         if (t.hasVisual)\r
7750                                                                 t.dom.addClass(e, 'mceItemAnchor');\r
7751                                                         else\r
7752                                                                 t.dom.removeClass(e, 'mceItemAnchor');\r
7753                                                 }\r
7754 \r
7755                                                 return;\r
7756                                 }\r
7757                         });\r
7758 \r
7759                         t.onVisualAid.dispatch(t, e, t.hasVisual);\r
7760                 },\r
7761 \r
7762                 remove : function() {\r
7763                         var t = this, e = t.getContainer();\r
7764 \r
7765                         t.removed = 1; // Cancels post remove event execution\r
7766                         t.hide();\r
7767 \r
7768                         t.execCallback('remove_instance_callback', t);\r
7769                         t.onRemove.dispatch(t);\r
7770 \r
7771                         // Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command\r
7772                         t.onExecCommand.listeners = [];\r
7773 \r
7774                         EditorManager.remove(t);\r
7775                         DOM.remove(e);\r
7776                 },\r
7777 \r
7778                 destroy : function(s) {\r
7779                         var t = this;\r
7780 \r
7781                         // One time is enough\r
7782                         if (t.destroyed)\r
7783                                 return;\r
7784 \r
7785                         if (!s) {\r
7786                                 tinymce.removeUnload(t.destroy);\r
7787                                 tinyMCE.onBeforeUnload.remove(t._beforeUnload);\r
7788 \r
7789                                 // Manual destroy\r
7790                                 if (t.theme.destroy)\r
7791                                         t.theme.destroy();\r
7792 \r
7793                                 // Destroy controls, selection and dom\r
7794                                 t.controlManager.destroy();\r
7795                                 t.selection.destroy();\r
7796                                 t.dom.destroy();\r
7797 \r
7798                                 // Remove all events\r
7799 \r
7800                                 // Don't clear the window or document if content editable\r
7801                                 // is enabled since other instances might still be present\r
7802                                 if (!t.settings.content_editable) {\r
7803                                         Event.clear(t.getWin());\r
7804                                         Event.clear(t.getDoc());\r
7805                                 }\r
7806 \r
7807                                 Event.clear(t.getBody());\r
7808                                 Event.clear(t.formElement);\r
7809                         }\r
7810 \r
7811                         if (t.formElement) {\r
7812                                 t.formElement.submit = t.formElement._mceOldSubmit;\r
7813                                 t.formElement._mceOldSubmit = null;\r
7814                         }\r
7815 \r
7816                         t.contentAreaContainer = t.formElement = t.container = t.settings.content_element = t.bodyElement = t.contentDocument = t.contentWindow = null;\r
7817 \r
7818                         if (t.selection)\r
7819                                 t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null;\r
7820 \r
7821                         t.destroyed = 1;\r
7822                 },\r
7823 \r
7824                 // Internal functions\r
7825 \r
7826                 _addEvents : function() {\r
7827                         // 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset\r
7828                         var t = this, i, s = t.settings, lo = {\r
7829                                 mouseup : 'onMouseUp',\r
7830                                 mousedown : 'onMouseDown',\r
7831                                 click : 'onClick',\r
7832                                 keyup : 'onKeyUp',\r
7833                                 keydown : 'onKeyDown',\r
7834                                 keypress : 'onKeyPress',\r
7835                                 submit : 'onSubmit',\r
7836                                 reset : 'onReset',\r
7837                                 contextmenu : 'onContextMenu',\r
7838                                 dblclick : 'onDblClick',\r
7839                                 paste : 'onPaste' // Doesn't work in all browsers yet\r
7840                         };\r
7841 \r
7842                         function eventHandler(e, o) {\r
7843                                 var ty = e.type;\r
7844 \r
7845                                 // Don't fire events when it's removed\r
7846                                 if (t.removed)\r
7847                                         return;\r
7848 \r
7849                                 // Generic event handler\r
7850                                 if (t.onEvent.dispatch(t, e, o) !== false) {\r
7851                                         // Specific event handler\r
7852                                         t[lo[e.fakeType || e.type]].dispatch(t, e, o);\r
7853                                 }\r
7854                         };\r
7855 \r
7856                         // Add DOM events\r
7857                         each(lo, function(v, k) {\r
7858                                 switch (k) {\r
7859                                         case 'contextmenu':\r
7860                                                 if (tinymce.isOpera) {\r
7861                                                         // Fake contextmenu on Opera\r
7862                                                         Event.add(t.getBody(), 'mousedown', function(e) {\r
7863                                                                 if (e.ctrlKey) {\r
7864                                                                         e.fakeType = 'contextmenu';\r
7865                                                                         eventHandler(e);\r
7866                                                                 }\r
7867                                                         });\r
7868                                                 } else\r
7869                                                         Event.add(t.getBody(), k, eventHandler);\r
7870                                                 break;\r
7871 \r
7872                                         case 'paste':\r
7873                                                 Event.add(t.getBody(), k, function(e) {\r
7874                                                         var tx, h, el, r;\r
7875 \r
7876                                                         // Get plain text data\r
7877                                                         if (e.clipboardData)\r
7878                                                                 tx = e.clipboardData.getData('text/plain');\r
7879                                                         else if (tinymce.isIE)\r
7880                                                                 tx = t.getWin().clipboardData.getData('Text');\r
7881 \r
7882                                                         // Get HTML data\r
7883                                                         /*if (tinymce.isIE) {\r
7884                                                                 el = DOM.add(DOM.doc.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'});\r
7885                                                                 r = DOM.doc.body.createTextRange();\r
7886                                                                 r.moveToElementText(el);\r
7887                                                                 r.execCommand('Paste');\r
7888                                                                 h = el.innerHTML;\r
7889                                                                 DOM.remove(el);\r
7890                                                         }*/\r
7891 \r
7892                                                         eventHandler(e, {text : tx, html : h});\r
7893                                                 });\r
7894                                                 break;\r
7895 \r
7896                                         case 'submit':\r
7897                                         case 'reset':\r
7898                                                 Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);\r
7899                                                 break;\r
7900 \r
7901                                         default:\r
7902                                                 Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);\r
7903                                 }\r
7904                         });\r
7905 \r
7906                         Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {\r
7907                                 t.focus(true);\r
7908                         });\r
7909 \r
7910                         \r
7911                         // Fixes bug where a specified document_base_uri could result in broken images\r
7912                         // This will also fix drag drop of images in Gecko\r
7913                         if (tinymce.isGecko) {\r
7914                                 // Convert all images to absolute URLs\r
7915 /*                              t.onSetContent.add(function(ed, o) {\r
7916                                         each(ed.dom.select('img'), function(e) {\r
7917                                                 var v;\r
7918 \r
7919                                                 if (v = e.getAttribute('mce_src'))\r
7920                                                         e.src = t.documentBaseURI.toAbsolute(v);\r
7921                                         })\r
7922                                 });*/\r
7923 \r
7924                                 Event.add(t.getDoc(), 'DOMNodeInserted', function(e) {\r
7925                                         var v;\r
7926 \r
7927                                         e = e.target;\r
7928 \r
7929                                         if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src')))\r
7930                                                 e.src = t.documentBaseURI.toAbsolute(v);\r
7931                                 });\r
7932                         }\r
7933 \r
7934                         // Set various midas options in Gecko\r
7935                         if (isGecko) {\r
7936                                 function setOpts() {\r
7937                                         var t = this, d = t.getDoc(), s = t.settings;\r
7938 \r
7939                                         if (isGecko) {\r
7940                                                 if (t._isHidden()) {\r
7941                                                         try {\r
7942                                                                 if (!s.content_editable)\r
7943                                                                         d.designMode = 'On';\r
7944                                                         } catch (ex) {\r
7945                                                                 // Fails if it's hidden\r
7946                                                         }\r
7947                                                 }\r
7948 \r
7949                                                 try {\r
7950                                                         // Try new Gecko method\r
7951                                                         d.execCommand("styleWithCSS", 0, false);\r
7952                                                 } catch (ex) {\r
7953                                                         // Use old method\r
7954                                                         if (!t._isHidden())\r
7955                                                                 try {d.execCommand("useCSS", 0, true);} catch (ex) {}\r
7956                                                 }\r
7957 \r
7958                                                 if (!s.table_inline_editing)\r
7959                                                         try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}\r
7960 \r
7961                                                 if (!s.object_resizing)\r
7962                                                         try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}\r
7963                                         }\r
7964                                 };\r
7965 \r
7966                                 t.onBeforeExecCommand.add(setOpts);\r
7967                                 t.onMouseDown.add(setOpts);\r
7968                         }\r
7969 \r
7970                         // Add node change handlers\r
7971                         t.onMouseUp.add(t.nodeChanged);\r
7972                         t.onClick.add(t.nodeChanged);\r
7973                         t.onKeyUp.add(function(ed, e) {\r
7974                                 if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.keyCode == 46 || e.keyCode == 8 || e.ctrlKey)\r
7975                                         t.nodeChanged();\r
7976                         });\r
7977 \r
7978                         // Add reset handler\r
7979                         t.onReset.add(function() {\r
7980                                 t.setContent(t.startContent, {format : 'raw'});\r
7981                         });\r
7982 \r
7983                         if (t.getParam('tab_focus')) {\r
7984                                 function tabCancel(ed, e) {\r
7985                                         if (e.keyCode === 9)\r
7986                                                 return Event.cancel(e);\r
7987                                 };\r
7988 \r
7989                                 function tabHandler(ed, e) {\r
7990                                         var x, i, f, el, v;\r
7991 \r
7992                                         function find(d) {\r
7993                                                 f = DOM.getParent(ed.id, 'form');\r
7994                                                 el = f.elements;\r
7995 \r
7996                                                 if (f) {\r
7997                                                         each(el, function(e, i) {\r
7998                                                                 if (e.id == ed.id) {\r
7999                                                                         x = i;\r
8000                                                                         return false;\r
8001                                                                 }\r
8002                                                         });\r
8003 \r
8004                                                         if (d > 0) {\r
8005                                                                 for (i = x + 1; i < el.length; i++) {\r
8006                                                                         if (el[i].type != 'hidden')\r
8007                                                                                 return el[i];\r
8008                                                                 }\r
8009                                                         } else {\r
8010                                                                 for (i = x - 1; i >= 0; i--) {\r
8011                                                                         if (el[i].type != 'hidden')\r
8012                                                                                 return el[i];\r
8013                                                                 }\r
8014                                                         }\r
8015                                                 }\r
8016 \r
8017                                                 return null;\r
8018                                         };\r
8019 \r
8020                                         if (e.keyCode === 9) {\r
8021                                                 v = explode(ed.getParam('tab_focus'));\r
8022 \r
8023                                                 if (v.length == 1) {\r
8024                                                         v[1] = v[0];\r
8025                                                         v[0] = ':prev';\r
8026                                                 }\r
8027 \r
8028                                                 // Find element to focus\r
8029                                                 if (e.shiftKey) {\r
8030                                                         if (v[0] == ':prev')\r
8031                                                                 el = find(-1);\r
8032                                                         else\r
8033                                                                 el = DOM.get(v[0]);\r
8034                                                 } else {\r
8035                                                         if (v[1] == ':next')\r
8036                                                                 el = find(1);\r
8037                                                         else\r
8038                                                                 el = DOM.get(v[1]);\r
8039                                                 }\r
8040 \r
8041                                                 if (el) {\r
8042                                                         if (ed = EditorManager.get(el.id || el.name))\r
8043                                                                 ed.focus();\r
8044                                                         else\r
8045                                                                 window.setTimeout(function() {window.focus();el.focus();}, 10);\r
8046 \r
8047                                                         return Event.cancel(e);\r
8048                                                 }\r
8049                                         }\r
8050                                 };\r
8051 \r
8052                                 t.onKeyUp.add(tabCancel);\r
8053 \r
8054                                 if (isGecko) {\r
8055                                         t.onKeyPress.add(tabHandler);\r
8056                                         t.onKeyDown.add(tabCancel);\r
8057                                 } else\r
8058                                         t.onKeyDown.add(tabHandler);\r
8059                         }\r
8060 \r
8061                         // Add shortcuts\r
8062                         if (s.custom_shortcuts) {\r
8063                                 if (s.custom_undo_redo_keyboard_shortcuts) {\r
8064                                         t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');\r
8065                                         t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');\r
8066                                 }\r
8067 \r
8068                                 // Add default shortcuts for gecko\r
8069                                 if (isGecko) {\r
8070                                         t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold');\r
8071                                         t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic');\r
8072                                         t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline');\r
8073                                 }\r
8074 \r
8075                                 // BlockFormat shortcuts keys\r
8076                                 for (i=1; i<=6; i++)\r
8077                                         t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, '<h' + i + '>']);\r
8078 \r
8079                                 t.addShortcut('ctrl+7', '', ['FormatBlock', false, '<p>']);\r
8080                                 t.addShortcut('ctrl+8', '', ['FormatBlock', false, '<div>']);\r
8081                                 t.addShortcut('ctrl+9', '', ['FormatBlock', false, '<address>']);\r
8082 \r
8083                                 function find(e) {\r
8084                                         var v = null;\r
8085 \r
8086                                         if (!e.altKey && !e.ctrlKey && !e.metaKey)\r
8087                                                 return v;\r
8088 \r
8089                                         each(t.shortcuts, function(o) {\r
8090                                                 if (o.ctrl != e.ctrlKey && (!tinymce.isMac || o.ctrl == e.metaKey))\r
8091                                                         return;\r
8092 \r
8093                                                 if (o.alt != e.altKey)\r
8094                                                         return;\r
8095 \r
8096                                                 if (o.shift != e.shiftKey)\r
8097                                                         return;\r
8098 \r
8099                                                 if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {\r
8100                                                         v = o;\r
8101                                                         return false;\r
8102                                                 }\r
8103                                         });\r
8104 \r
8105                                         return v;\r
8106                                 };\r
8107 \r
8108                                 t.onKeyUp.add(function(ed, e) {\r
8109                                         var o = find(e);\r
8110 \r
8111                                         if (o)\r
8112                                                 return Event.cancel(e);\r
8113                                 });\r
8114 \r
8115                                 t.onKeyPress.add(function(ed, e) {\r
8116                                         var o = find(e);\r
8117 \r
8118                                         if (o)\r
8119                                                 return Event.cancel(e);\r
8120                                 });\r
8121 \r
8122                                 t.onKeyDown.add(function(ed, e) {\r
8123                                         var o = find(e);\r
8124 \r
8125                                         if (o) {\r
8126                                                 o.func.call(o.scope);\r
8127                                                 return Event.cancel(e);\r
8128                                         }\r
8129                                 });\r
8130                         }\r
8131 \r
8132                         if (tinymce.isIE) {\r
8133                                 // Fix so resize will only update the width and height attributes not the styles of an image\r
8134                                 // It will also block mceItemNoResize items\r
8135                                 Event.add(t.getDoc(), 'controlselect', function(e) {\r
8136                                         var re = t.resizeInfo, cb;\r
8137 \r
8138                                         e = e.target;\r
8139 \r
8140                                         // Don't do this action for non image elements\r
8141                                         if (e.nodeName !== 'IMG')\r
8142                                                 return;\r
8143 \r
8144                                         if (re)\r
8145                                                 Event.remove(re.node, re.ev, re.cb);\r
8146 \r
8147                                         if (!t.dom.hasClass(e, 'mceItemNoResize')) {\r
8148                                                 ev = 'resizeend';\r
8149                                                 cb = Event.add(e, ev, function(e) {\r
8150                                                         var v;\r
8151 \r
8152                                                         e = e.target;\r
8153 \r
8154                                                         if (v = t.dom.getStyle(e, 'width')) {\r
8155                                                                 t.dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));\r
8156                                                                 t.dom.setStyle(e, 'width', '');\r
8157                                                         }\r
8158 \r
8159                                                         if (v = t.dom.getStyle(e, 'height')) {\r
8160                                                                 t.dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));\r
8161                                                                 t.dom.setStyle(e, 'height', '');\r
8162                                                         }\r
8163                                                 });\r
8164                                         } else {\r
8165                                                 ev = 'resizestart';\r
8166                                                 cb = Event.add(e, 'resizestart', Event.cancel, Event);\r
8167                                         }\r
8168 \r
8169                                         re = t.resizeInfo = {\r
8170                                                 node : e,\r
8171                                                 ev : ev,\r
8172                                                 cb : cb\r
8173                                         };\r
8174                                 });\r
8175 \r
8176                                 t.onKeyDown.add(function(ed, e) {\r
8177                                         switch (e.keyCode) {\r
8178                                                 case 8:\r
8179                                                         // Fix IE control + backspace browser bug\r
8180                                                         if (t.selection.getRng().item) {\r
8181                                                                 t.selection.getRng().item(0).removeNode();\r
8182                                                                 return Event.cancel(e);\r
8183                                                         }\r
8184                                         }\r
8185                                 });\r
8186                         }\r
8187 \r
8188                         if (tinymce.isOpera) {\r
8189                                 t.onClick.add(function(ed, e) {\r
8190                                         Event.prevent(e);\r
8191                                 });\r
8192                         }\r
8193 \r
8194                         // Add custom undo/redo handlers\r
8195                         if (s.custom_undo_redo) {\r
8196                                 function addUndo() {\r
8197                                         t.undoManager.typing = 0;\r
8198                                         t.undoManager.add();\r
8199                                 };\r
8200 \r
8201                                 // Add undo level on editor blur\r
8202                                 if (tinymce.isIE) {\r
8203                                         Event.add(t.getWin(), 'blur', function(e) {\r
8204                                                 var n;\r
8205 \r
8206                                                 // Check added for fullscreen bug\r
8207                                                 if (t.selection) {\r
8208                                                         n = t.selection.getNode();\r
8209 \r
8210                                                         // Add undo level is selection was lost to another document\r
8211                                                         if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc())\r
8212                                                                 addUndo();\r
8213                                                 }\r
8214                                         });\r
8215                                 } else {\r
8216                                         Event.add(t.getDoc(), 'blur', function() {\r
8217                                                 if (t.selection && !t.removed)\r
8218                                                         addUndo();\r
8219                                         });\r
8220                                 }\r
8221 \r
8222                                 t.onMouseDown.add(addUndo);\r
8223 \r
8224                                 t.onKeyUp.add(function(ed, e) {\r
8225                                         if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) {\r
8226                                                 t.undoManager.typing = 0;\r
8227                                                 t.undoManager.add();\r
8228                                         }\r
8229                                 });\r
8230 \r
8231                                 t.onKeyDown.add(function(ed, e) {\r
8232                                         // Is caracter positon keys\r
8233                                         if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) {\r
8234                                                 if (t.undoManager.typing) {\r
8235                                                         t.undoManager.add();\r
8236                                                         t.undoManager.typing = 0;\r
8237                                                 }\r
8238 \r
8239                                                 return;\r
8240                                         }\r
8241 \r
8242                                         if (!t.undoManager.typing) {\r
8243                                                 t.undoManager.add();\r
8244                                                 t.undoManager.typing = 1;\r
8245                                         }\r
8246                                 });\r
8247                         }\r
8248                 },\r
8249 \r
8250                 _convertInlineElements : function() {\r
8251                         var t = this, s = t.settings, dom = t.dom, v, e, na, st, sp;\r
8252 \r
8253                         function convert(ed, o) {\r
8254                                 if (!s.inline_styles)\r
8255                                         return;\r
8256 \r
8257                                 if (o.get) {\r
8258                                         each(t.dom.select('table,u,strike', o.node), function(n) {\r
8259                                                 switch (n.nodeName) {\r
8260                                                         case 'TABLE':\r
8261                                                                 if (v = dom.getAttrib(n, 'height')) {\r
8262                                                                         dom.setStyle(n, 'height', v);\r
8263                                                                         dom.setAttrib(n, 'height', '');\r
8264                                                                 }\r
8265                                                                 break;\r
8266 \r
8267                                                         case 'U':\r
8268                                                         case 'STRIKE':\r
8269                                                                 //sp = dom.create('span', {style : dom.getAttrib(n, 'style')});\r
8270                                                                 n.style.textDecoration = n.nodeName == 'U' ? 'underline' : 'line-through';\r
8271                                                                 dom.setAttrib(n, 'mce_style', '');\r
8272                                                                 dom.setAttrib(n, 'mce_name', 'span');\r
8273                                                                 break;\r
8274                                                 }\r
8275                                         });\r
8276                                 } else if (o.set) {\r
8277                                         each(t.dom.select('table,span', o.node).reverse(), function(n) {\r
8278                                                 if (n.nodeName == 'TABLE') {\r
8279                                                         if (v = dom.getStyle(n, 'height'))\r
8280                                                                 dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));\r
8281                                                 } else {\r
8282                                                         // Convert spans to elements\r
8283                                                         if (n.style.textDecoration == 'underline')\r
8284                                                                 na = 'u';\r
8285                                                         else if (n.style.textDecoration == 'line-through')\r
8286                                                                 na = 'strike';\r
8287                                                         else\r
8288                                                                 na = '';\r
8289 \r
8290                                                         if (na) {\r
8291                                                                 n.style.textDecoration = '';\r
8292                                                                 dom.setAttrib(n, 'mce_style', '');\r
8293 \r
8294                                                                 e = dom.create(na, {\r
8295                                                                         style : dom.getAttrib(n, 'style')\r
8296                                                                 });\r
8297 \r
8298                                                                 dom.replace(e, n, 1);\r
8299                                                         }\r
8300                                                 }\r
8301                                         });\r
8302                                 }\r
8303                         };\r
8304 \r
8305                         t.onPreProcess.add(convert);\r
8306 \r
8307                         if (!s.cleanup_on_startup) {\r
8308                                 t.onSetContent.add(function(ed, o) {\r
8309                                         if (o.initial)\r
8310                                                 convert(t, {node : t.getBody(), set : 1});\r
8311                                 });\r
8312                         }\r
8313                 },\r
8314 \r
8315                 _convertFonts : function() {\r
8316                         var t = this, s = t.settings, dom = t.dom, fz, fzn, sl, cl;\r
8317 \r
8318                         // No need\r
8319                         if (!s.inline_styles)\r
8320                                 return;\r
8321 \r
8322                         // Font pt values and font size names\r
8323                         fz = [8, 10, 12, 14, 18, 24, 36];\r
8324                         fzn = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large'];\r
8325 \r
8326                         if (sl = s.font_size_style_values)\r
8327                                 sl = explode(sl);\r
8328 \r
8329                         if (cl = s.font_size_classes)\r
8330                                 cl = explode(cl);\r
8331 \r
8332                         function convertToFonts(no) {\r
8333                                 var n, f, nl, x, i, v, st;\r
8334 \r
8335                                 // Convert spans to fonts on non WebKit browsers\r
8336                                 if (tinymce.isWebKit || !s.inline_styles)\r
8337                                         return;\r
8338 \r
8339                                 nl = t.dom.select('span', no);\r
8340                                 for (x = nl.length - 1; x >= 0; x--) {\r
8341                                         n = nl[x];\r
8342 \r
8343                                         f = dom.create('font', {\r
8344                                                 color : dom.toHex(dom.getStyle(n, 'color')),\r
8345                                                 face : dom.getStyle(n, 'fontFamily'),\r
8346                                                 style : dom.getAttrib(n, 'style'),\r
8347                                                 'class' : dom.getAttrib(n, 'class')\r
8348                                         });\r
8349 \r
8350                                         // Clear color and font family\r
8351                                         st = f.style;\r
8352                                         if (st.color || st.fontFamily) {\r
8353                                                 st.color = st.fontFamily = '';\r
8354                                                 dom.setAttrib(f, 'mce_style', ''); // Remove cached style data\r
8355                                         }\r
8356 \r
8357                                         if (sl) {\r
8358                                                 i = inArray(sl, dom.getStyle(n, 'fontSize'));\r
8359 \r
8360                                                 if (i != -1) {\r
8361                                                         dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
8362                                                         //f.style.fontSize = '';\r
8363                                                 }\r
8364                                         } else if (cl) {\r
8365                                                 i = inArray(cl, dom.getAttrib(n, 'class'));\r
8366                                                 v = dom.getStyle(n, 'fontSize');\r
8367 \r
8368                                                 if (i == -1 && v.indexOf('pt') > 0)\r
8369                                                         i = inArray(fz, parseInt(v));\r
8370 \r
8371                                                 if (i == -1)\r
8372                                                         i = inArray(fzn, v);\r
8373 \r
8374                                                 if (i != -1) {\r
8375                                                         dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
8376                                                         f.style.fontSize = '';\r
8377                                                 }\r
8378                                         }\r
8379 \r
8380                                         if (f.color || f.face || f.size) {\r
8381                                                 f.style.fontFamily = '';\r
8382                                                 dom.setAttrib(f, 'mce_style', '');\r
8383                                                 dom.replace(f, n, 1);\r
8384                                         }\r
8385 \r
8386                                         f = n = null;\r
8387                                 }\r
8388                         };\r
8389 \r
8390                         // Run on setup\r
8391                         t.onSetContent.add(function(ed, o) {\r
8392                                 convertToFonts(ed.getBody());\r
8393                         });\r
8394 \r
8395                         // Run on cleanup\r
8396                         t.onPreProcess.add(function(ed, o) {\r
8397                                 var n, sp, nl, x;\r
8398 \r
8399                                 // Keep unit tests happy\r
8400                                 if (!s.inline_styles)\r
8401                                         return;\r
8402 \r
8403                                 if (o.get) {\r
8404                                         nl = t.dom.select('font', o.node);\r
8405                                         for (x = nl.length - 1; x >= 0; x--) {\r
8406                                                 n = nl[x];\r
8407 \r
8408                                                 sp = dom.create('span', {\r
8409                                                         style : dom.getAttrib(n, 'style'),\r
8410                                                         'class' : dom.getAttrib(n, 'class')\r
8411                                                 });\r
8412 \r
8413                                                 dom.setStyles(sp, {\r
8414                                                         fontFamily : dom.getAttrib(n, 'face'),\r
8415                                                         color : dom.getAttrib(n, 'color'),\r
8416                                                         backgroundColor : n.style.backgroundColor\r
8417                                                 });\r
8418 \r
8419                                                 if (n.size) {\r
8420                                                         if (sl)\r
8421                                                                 dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]);\r
8422                                                         else\r
8423                                                                 dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);\r
8424                                                 }\r
8425 \r
8426                                                 dom.setAttrib(sp, 'mce_style', '');\r
8427                                                 dom.replace(sp, n, 1);\r
8428                                         }\r
8429                                 }\r
8430                         });\r
8431                 },\r
8432 \r
8433                 _isHidden : function() {\r
8434                         var s;\r
8435 \r
8436                         if (!isGecko)\r
8437                                 return 0;\r
8438 \r
8439                         // Weird, wheres that cursor selection?\r
8440                         s = this.selection.getSel();\r
8441                         return (!s || !s.rangeCount || s.rangeCount == 0);\r
8442                 },\r
8443 \r
8444                 // Fix for bug #1867292\r
8445                 _fixNesting : function(s) {\r
8446                         var d = [], i;\r
8447 \r
8448                         s = s.replace(/<(\/)?([^\s>]+)[^>]*?>/g, function(a, b, c) {\r
8449                                 var e;\r
8450 \r
8451                                 // Handle end element\r
8452                                 if (b === '/') {\r
8453                                         if (!d.length)\r
8454                                                 return '';\r
8455 \r
8456                                         if (c !== d[d.length - 1].tag) {\r
8457                                                 for (i=d.length - 1; i>=0; i--) {\r
8458                                                         if (d[i].tag === c) {\r
8459                                                                 d[i].close = 1;\r
8460                                                                 break;\r
8461                                                         }\r
8462                                                 }\r
8463 \r
8464                                                 return '';\r
8465                                         } else {\r
8466                                                 d.pop();\r
8467 \r
8468                                                 if (d.length && d[d.length - 1].close) {\r
8469                                                         a = a + '</' + d[d.length - 1].tag + '>';\r
8470                                                         d.pop();\r
8471                                                 }\r
8472                                         }\r
8473                                 } else {\r
8474                                         // Ignore these\r
8475                                         if (/^(br|hr|input|meta|img|link|param)$/i.test(c))\r
8476                                                 return a;\r
8477 \r
8478                                         // Ignore closed ones\r
8479                                         if (/\/>$/.test(a))\r
8480                                                 return a;\r
8481 \r
8482                                         d.push({tag : c}); // Push start element\r
8483                                 }\r
8484 \r
8485                                 return a;\r
8486                         });\r
8487 \r
8488                         // End all open tags\r
8489                         for (i=d.length - 1; i>=0; i--)\r
8490                                 s += '</' + d[i].tag + '>';\r
8491 \r
8492                         return s;\r
8493                 }\r
8494 \r
8495                 });\r
8496 })();\r
8497 \r
8498 /* file:jscripts/tiny_mce/classes/EditorCommands.js */\r
8499 \r
8500 (function() {\r
8501         var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;\r
8502 \r
8503         tinymce.create('tinymce.EditorCommands', {\r
8504                 EditorCommands : function(ed) {\r
8505                         this.editor = ed;\r
8506                 },\r
8507 \r
8508                 execCommand : function(cmd, ui, val) {\r
8509                         var t = this, ed = t.editor, f;\r
8510 \r
8511                         switch (cmd) {\r
8512                                 case 'Cut':\r
8513                                 case 'Copy':\r
8514                                 case 'Paste':\r
8515                                         try {\r
8516                                                 ed.getDoc().execCommand(cmd, ui, val);\r
8517                                         } catch (ex) {\r
8518                                                 if (isGecko) {\r
8519                                                         ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {\r
8520                                                                 if (s)\r
8521                                                                         window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');\r
8522                                                         });\r
8523                                                 } else\r
8524                                                         ed.windowManager.alert(ed.getLang('clipboard_no_support'));\r
8525                                         }\r
8526 \r
8527                                         return true;\r
8528 \r
8529                                 // Ignore these\r
8530                                 case 'mceResetDesignMode':\r
8531                                 case 'mceBeginUndoLevel':\r
8532                                         return true;\r
8533 \r
8534                                 // Ignore these\r
8535                                 case 'unlink':\r
8536                                         t.UnLink();\r
8537                                         return true;\r
8538 \r
8539                                 // Bundle these together\r
8540                                 case 'JustifyLeft':\r
8541                                 case 'JustifyCenter':\r
8542                                 case 'JustifyRight':\r
8543                                 case 'JustifyFull':\r
8544                                         t.mceJustify(cmd, cmd.substring(7).toLowerCase());\r
8545                                         return true;\r
8546 \r
8547                                 case 'mceEndUndoLevel':\r
8548                                 case 'mceAddUndoLevel':\r
8549                                         ed.undoManager.add();\r
8550                                         return true;\r
8551 \r
8552                                 default:\r
8553                                         f = this[cmd];\r
8554 \r
8555                                         if (f) {\r
8556                                                 f.call(this, ui, val);\r
8557                                                 return true;\r
8558                                         }\r
8559                         }\r
8560 \r
8561                         return false;\r
8562                 },\r
8563 \r
8564                 Indent : function() {\r
8565                         var ed = this.editor, d = ed.dom, s = ed.selection, e, iv, iu;\r
8566 \r
8567                         // Setup indent level\r
8568                         iv = ed.settings.indentation;\r
8569                         iu = /[a-z%]+$/i.exec(iv);\r
8570                         iv = parseInt(iv);\r
8571 \r
8572                         if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
8573                                 each(this._getSelectedBlocks(), function(e) {\r
8574                                         d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);\r
8575                                 });\r
8576 \r
8577                                 return;\r
8578                         }\r
8579 \r
8580                         ed.getDoc().execCommand('Indent', false, null);\r
8581 \r
8582                         if (isIE) {\r
8583                                 d.getParent(s.getNode(), function(n) {\r
8584                                         if (n.nodeName == 'BLOCKQUOTE') {\r
8585                                                 n.dir = n.style.cssText = '';\r
8586                                         }\r
8587                                 });\r
8588                         }\r
8589                 },\r
8590 \r
8591                 Outdent : function() {\r
8592                         var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu;\r
8593 \r
8594                         // Setup indent level\r
8595                         iv = ed.settings.indentation;\r
8596                         iu = /[a-z%]+$/i.exec(iv);\r
8597                         iv = parseInt(iv);\r
8598 \r
8599                         if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
8600                                 each(this._getSelectedBlocks(), function(e) {\r
8601                                         v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);\r
8602                                         d.setStyle(e, 'paddingLeft', v ? v + iu : '');\r
8603                                 });\r
8604 \r
8605                                 return;\r
8606                         }\r
8607 \r
8608                         ed.getDoc().execCommand('Outdent', false, null);\r
8609                 },\r
8610 \r
8611                 mceSetAttribute : function(u, v) {\r
8612                         var ed = this.editor, d = ed.dom, e;\r
8613 \r
8614                         if (e = d.getParent(ed.selection.getNode(), d.isBlock))\r
8615                                 d.setAttrib(e, v.name, v.value);\r
8616                 },\r
8617 \r
8618                 mceSetContent : function(u, v) {\r
8619                         this.editor.setContent(v);\r
8620                 },\r
8621 \r
8622                 mceToggleVisualAid : function() {\r
8623                         var ed = this.editor;\r
8624 \r
8625                         ed.hasVisual = !ed.hasVisual;\r
8626                         ed.addVisual();\r
8627                 },\r
8628 \r
8629                 mceReplaceContent : function(u, v) {\r
8630                         var s = this.editor.selection;\r
8631 \r
8632                         s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'})));\r
8633                 },\r
8634 \r
8635                 mceInsertLink : function(u, v) {\r
8636                         var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A');\r
8637 \r
8638                         if (tinymce.is(v, 'string'))\r
8639                                 v = {href : v};\r
8640 \r
8641                         function set(e) {\r
8642                                 each(v, function(v, k) {\r
8643                                         ed.dom.setAttrib(e, k, v);\r
8644                                 });\r
8645                         };\r
8646 \r
8647                         if (!e) {\r
8648                                 ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');\r
8649                                 each(ed.dom.select('a'), function(e) {\r
8650                                         if (e.href == 'javascript:mctmp(0);')\r
8651                                                 set(e);\r
8652                                 });\r
8653                         } else {\r
8654                                 if (v.href)\r
8655                                         set(e);\r
8656                                 else\r
8657                                         ed.dom.remove(e, 1);\r
8658                         }\r
8659                 },\r
8660 \r
8661                 UnLink : function() {\r
8662                         var ed = this.editor, s = ed.selection;\r
8663 \r
8664                         if (s.isCollapsed())\r
8665                                 s.select(s.getNode());\r
8666 \r
8667                         ed.getDoc().execCommand('unlink', false, null);\r
8668                         s.collapse(0);\r
8669                 },\r
8670 \r
8671                 FontName : function(u, v) {\r
8672                         var t = this, ed = t.editor, s = ed.selection, e;\r
8673 \r
8674                         if (!v) {\r
8675                                 if (s.isCollapsed())\r
8676                                         s.select(s.getNode());\r
8677 \r
8678                                 t.RemoveFormat();\r
8679                         } else\r
8680                                 ed.getDoc().execCommand('FontName', false, v);\r
8681                 },\r
8682 \r
8683                 FontSize : function(u, v) {\r
8684                         var ed = this.editor, s = ed.settings, fz = tinymce.explode(s.font_size_style_values), fzc = tinymce.explode(s.font_size_classes), h, bm;\r
8685 \r
8686                         // Remove style sizes\r
8687                         each(ed.dom.select('font'), function(e) {\r
8688                                 e.style.fontSize = '';\r
8689                         });\r
8690 \r
8691                         // Let the browser add new size it will remove unneded ones in some browsers\r
8692                         ed.getDoc().execCommand('FontSize', false, v);\r
8693 \r
8694                         // Add style values\r
8695                         if (s.inline_styles) {\r
8696                                 each(ed.dom.select('font'), function(e) {\r
8697                                         // Try remove redundant font elements\r
8698                                         if (e.parentNode.nodeName == 'FONT' && e.size == e.parentNode.size) {\r
8699                                                 if (!bm)\r
8700                                                         bm = ed.selection.getBookmark();\r
8701 \r
8702                                                 ed.dom.remove(e, 1);\r
8703                                                 return;\r
8704                                         }\r
8705 \r
8706                                         // Setup font size based on font size value\r
8707                                         if (v = e.size) {\r
8708                                                 if (fzc && fzc.length > 0)\r
8709                                                         ed.dom.setAttrib(e, 'class', fzc[parseInt(v) - 1]);\r
8710                                                 else\r
8711                                                         ed.dom.setStyle(e, 'fontSize', fz[parseInt(v) - 1]);\r
8712                                         }\r
8713                                 });\r
8714                         }\r
8715 \r
8716                         ed.selection.moveToBookmark(bm);\r
8717                 },\r
8718 \r
8719                 queryCommandValue : function(c) {\r
8720                         var f = this['queryValue' + c];\r
8721 \r
8722                         if (f)\r
8723                                 return f.call(this, c);\r
8724 \r
8725                         return false;\r
8726                 },\r
8727 \r
8728                 queryCommandState : function(cmd) {\r
8729                         var f;\r
8730 \r
8731                         switch (cmd) {\r
8732                                 // Bundle these together\r
8733                                 case 'JustifyLeft':\r
8734                                 case 'JustifyCenter':\r
8735                                 case 'JustifyRight':\r
8736                                 case 'JustifyFull':\r
8737                                         return this.queryStateJustify(cmd, cmd.substring(7).toLowerCase());\r
8738 \r
8739                                 default:\r
8740                                         if (f = this['queryState' + cmd])\r
8741                                                 return f.call(this, cmd);\r
8742                         }\r
8743 \r
8744                         return -1;\r
8745                 },\r
8746 \r
8747                 _queryState : function(c) {\r
8748                         try {\r
8749                                 return this.editor.getDoc().queryCommandState(c);\r
8750                         } catch (ex) {\r
8751                                 // Ignore exception\r
8752                         }\r
8753                 },\r
8754 \r
8755                 _queryVal : function(c) {\r
8756                         try {\r
8757                                 return this.editor.getDoc().queryCommandValue(c);\r
8758                         } catch (ex) {\r
8759                                 // Ignore exception\r
8760                         }\r
8761                 },\r
8762 \r
8763                 queryValueFontSize : function() {\r
8764                         var ed = this.editor, v = 0, p;\r
8765 \r
8766                         if (isOpera || isWebKit) {\r
8767                                 if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
8768                                         v = p.size;\r
8769 \r
8770                                 return v;\r
8771                         }\r
8772 \r
8773                         return this._queryVal('FontSize');\r
8774                 },\r
8775 \r
8776                 queryValueFontName : function() {\r
8777                         var ed = this.editor, v = 0, p;\r
8778 \r
8779                         if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
8780                                 v = p.face;\r
8781 \r
8782                         if (!v)\r
8783                                 v = this._queryVal('FontName');\r
8784 \r
8785                         return v;\r
8786                 },\r
8787 \r
8788                 mceJustify : function(c, v) {\r
8789                         var ed = this.editor, se = ed.selection, n = se.getNode(), nn = n.nodeName, bl, nb, dom = ed.dom, rm;\r
8790 \r
8791                         if (ed.settings.inline_styles && this.queryStateJustify(c, v))\r
8792                                 rm = 1;\r
8793 \r
8794                         bl = dom.getParent(n, ed.dom.isBlock);\r
8795 \r
8796                         if (nn == 'IMG') {\r
8797                                 if (v == 'full')\r
8798                                         return;\r
8799 \r
8800                                 if (rm) {\r
8801                                         if (v == 'center')\r
8802                                                 dom.setStyle(n.parentNode, 'textAlign', '');\r
8803 \r
8804                                         dom.setStyle(n, 'float', '');\r
8805                                         this.mceRepaint();\r
8806                                         return;\r
8807                                 }\r
8808 \r
8809                                 if (v == 'center') {\r
8810                                         // Do not change table elements\r
8811                                         if (/^(TD|TH)$/.test(bl.nodeName))\r
8812                                                 bl = 0;\r
8813 \r
8814                                         if (!bl || bl.childNodes.length > 1) {\r
8815                                                 nb = dom.create('p');\r
8816                                                 nb.appendChild(n.cloneNode(false));\r
8817 \r
8818                                                 if (bl)\r
8819                                                         dom.insertAfter(nb, bl);\r
8820                                                 else\r
8821                                                         dom.insertAfter(nb, n);\r
8822 \r
8823                                                 dom.remove(n);\r
8824                                                 n = nb.firstChild;\r
8825                                                 bl = nb;\r
8826                                         }\r
8827 \r
8828                                         dom.setStyle(bl, 'textAlign', v);\r
8829                                         dom.setStyle(n, 'float', '');\r
8830                                 } else {\r
8831                                         dom.setStyle(n, 'float', v);\r
8832                                         dom.setStyle(n.parentNode, 'textAlign', '');\r
8833                                 }\r
8834 \r
8835                                 this.mceRepaint();\r
8836                                 return;\r
8837                         }\r
8838 \r
8839                         // Handle the alignment outselfs, less quirks in all browsers\r
8840                         if (ed.settings.inline_styles && ed.settings.forced_root_block) {\r
8841                                 if (rm)\r
8842                                         v = '';\r
8843 \r
8844                                 each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {\r
8845                                         dom.setAttrib(e, 'align', '');\r
8846                                         dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);\r
8847                                 });\r
8848 \r
8849                                 return;\r
8850                         } else if (!rm)\r
8851                                 ed.getDoc().execCommand(c, false, null);\r
8852 \r
8853                         if (ed.settings.inline_styles) {\r
8854                                 if (rm) {\r
8855                                         dom.getParent(ed.selection.getNode(), function(n) {\r
8856                                                 if (n.style && n.style.textAlign)\r
8857                                                         dom.setStyle(n, 'textAlign', '');\r
8858                                         });\r
8859 \r
8860                                         return;\r
8861                                 }\r
8862 \r
8863                                 each(dom.select('*'), function(n) {\r
8864                                         var v = n.align;\r
8865 \r
8866                                         if (v) {\r
8867                                                 if (v == 'full')\r
8868                                                         v = 'justify';\r
8869 \r
8870                                                 dom.setStyle(n, 'textAlign', v);\r
8871                                                 dom.setAttrib(n, 'align', '');\r
8872                                         }\r
8873                                 });\r
8874                         }\r
8875                 },\r
8876 \r
8877                 mceSetCSSClass : function(u, v) {\r
8878                         this.mceSetStyleInfo(0, {command : 'setattrib', name : 'class', value : v});\r
8879                 },\r
8880 \r
8881                 getSelectedElement : function() {\r
8882                         var t = this, ed = t.editor, dom = ed.dom, se = ed.selection, r = se.getRng(), r1, r2, sc, ec, so, eo, e, sp, ep, re;\r
8883 \r
8884                         if (se.isCollapsed() || r.item)\r
8885                                 return se.getNode();\r
8886 \r
8887                         // Setup regexp\r
8888                         re = ed.settings.merge_styles_invalid_parents;\r
8889                         if (tinymce.is(re, 'string'))\r
8890                                 re = new RegExp(re, 'i');\r
8891 \r
8892                         if (isIE) {\r
8893                                 r1 = r.duplicate();\r
8894                                 r1.collapse(true);\r
8895                                 sc = r1.parentElement();\r
8896 \r
8897                                 r2 = r.duplicate();\r
8898                                 r2.collapse(false);\r
8899                                 ec = r2.parentElement();\r
8900 \r
8901                                 if (sc != ec) {\r
8902                                         r1.move('character', 1);\r
8903                                         sc = r1.parentElement();\r
8904                                 }\r
8905 \r
8906                                 if (sc == ec) {\r
8907                                         r1 = r.duplicate();\r
8908                                         r1.moveToElementText(sc);\r
8909 \r
8910                                         if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0)\r
8911                                                 return re && re.test(sc.nodeName) ? null : sc;\r
8912                                 }\r
8913                         } else {\r
8914                                 function getParent(n) {\r
8915                                         return dom.getParent(n, function(n) {return n.nodeType == 1;});\r
8916                                 };\r
8917 \r
8918                                 sc = r.startContainer;\r
8919                                 ec = r.endContainer;\r
8920                                 so = r.startOffset;\r
8921                                 eo = r.endOffset;\r
8922 \r
8923                                 if (!r.collapsed) {\r
8924                                         if (sc == ec) {\r
8925                                                 if (so - eo < 2) {\r
8926                                                         if (sc.hasChildNodes()) {\r
8927                                                                 sp = sc.childNodes[so];\r
8928                                                                 return re && re.test(sp.nodeName) ? null : sp;\r
8929                                                         }\r
8930                                                 }\r
8931                                         }\r
8932                                 }\r
8933 \r
8934                                 if (sc.nodeType != 3 || ec.nodeType != 3)\r
8935                                         return null;\r
8936 \r
8937                                 if (so == 0) {\r
8938                                         sp = getParent(sc);\r
8939 \r
8940                                         if (sp && sp.firstChild != sc)\r
8941                                                 sp = null;\r
8942                                 }\r
8943 \r
8944                                 if (so == sc.nodeValue.length) {\r
8945                                         e = sc.nextSibling;\r
8946 \r
8947                                         if (e && e.nodeType == 1)\r
8948                                                 sp = sc.nextSibling;\r
8949                                 }\r
8950 \r
8951                                 if (eo == 0) {\r
8952                                         e = ec.previousSibling;\r
8953 \r
8954                                         if (e && e.nodeType == 1)\r
8955                                                 ep = e;\r
8956                                 }\r
8957 \r
8958                                 if (eo == ec.nodeValue.length) {\r
8959                                         ep = getParent(ec);\r
8960 \r
8961                                         if (ep && ep.lastChild != ec)\r
8962                                                 ep = null;\r
8963                                 }\r
8964 \r
8965                                 // Same element\r
8966                                 if (sp == ep)\r
8967                                         return re && sp && re.test(sp.nodeName) ? null : sp;\r
8968                         }\r
8969 \r
8970                         return null;\r
8971                 },\r
8972 \r
8973                 InsertHorizontalRule : function() {\r
8974                         // Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");\r
8975                         if (isGecko || isIE)\r
8976                                 this.editor.selection.setContent('<hr />');\r
8977                         else\r
8978                                 this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');\r
8979                 },\r
8980 \r
8981                 RemoveFormat : function() {\r
8982                         var t = this, ed = t.editor, s = ed.selection, b;\r
8983 \r
8984                         // Safari breaks tables\r
8985                         if (isWebKit)\r
8986                                 s.setContent(s.getContent({format : 'raw'}).replace(/(<(span|b|i|strong|em|strike) [^>]+>|<(span|b|i|strong|em|strike)>|<\/(span|b|i|strong|em|strike)>|)/g, ''), {format : 'raw'});\r
8987                         else\r
8988                                 ed.getDoc().execCommand('RemoveFormat', false, null);\r
8989 \r
8990                         t.mceSetStyleInfo(0, {command : 'removeformat'});\r
8991                         ed.addVisual();\r
8992                 },\r
8993 \r
8994                 mceSetStyleInfo : function(u, v) {\r
8995                         var t = this, ed = t.editor, d = ed.getDoc(), dom = ed.dom, e, b, s = ed.selection, nn = v.wrapper || 'span', b = s.getBookmark(), re;\r
8996 \r
8997                         function set(n, e) {\r
8998                                 if (n.nodeType == 1) {\r
8999                                         switch (v.command) {\r
9000                                                 case 'setattrib':\r
9001                                                         return dom.setAttrib(n, v.name, v.value);\r
9002 \r
9003                                                 case 'setstyle':\r
9004                                                         return dom.setStyle(n, v.name, v.value);\r
9005 \r
9006                                                 case 'removeformat':\r
9007                                                         return dom.setAttrib(n, 'class', '');\r
9008                                         }\r
9009                                 }\r
9010                         };\r
9011 \r
9012                         // Setup regexp\r
9013                         re = ed.settings.merge_styles_invalid_parents;\r
9014                         if (tinymce.is(re, 'string'))\r
9015                                 re = new RegExp(re, 'i');\r
9016 \r
9017                         // Set style info on selected element\r
9018                         if (e = t.getSelectedElement())\r
9019                                 set(e, 1);\r
9020                         else {\r
9021                                 // Generate wrappers and set styles on them\r
9022                                 d.execCommand('FontName', false, '__');\r
9023                                 each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {\r
9024                                         var sp, e;\r
9025 \r
9026                                         if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {\r
9027                                                 sp = dom.create(nn, {mce_new : '1'});\r
9028 \r
9029                                                 set(sp);\r
9030 \r
9031                                                 each (n.childNodes, function(n) {\r
9032                                                         sp.appendChild(n.cloneNode(true));\r
9033                                                 });\r
9034 \r
9035                                                 dom.replace(sp, n);\r
9036                                         }\r
9037                                 });\r
9038                         }\r
9039 \r
9040                         // Remove wrappers inside new ones\r
9041                         each(dom.select(nn).reverse(), function(n) {\r
9042                                 var p = n.parentNode;\r
9043 \r
9044                                 // Check if it's an old span in a new wrapper\r
9045                                 if (!dom.getAttrib(n, 'mce_new')) {\r
9046                                         // Find new wrapper\r
9047                                         p = dom.getParent(n, function(n) {\r
9048                                                 return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');\r
9049                                         });\r
9050 \r
9051                                         if (p)\r
9052                                                 dom.remove(n, 1);\r
9053                                 }\r
9054                         });\r
9055 \r
9056                         // Merge wrappers with parent wrappers\r
9057                         each(dom.select(nn).reverse(), function(n) {\r
9058                                 var p = n.parentNode;\r
9059 \r
9060                                 if (!p || !dom.getAttrib(n, 'mce_new'))\r
9061                                         return;\r
9062 \r
9063                                 // Has parent of the same type and only child\r
9064                                 if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1)\r
9065                                         return dom.remove(p, 1);\r
9066 \r
9067                                 // Has parent that is more suitable to have the class and only child\r
9068                                 if (n.nodeType == 1 && (!re || !re.test(p.nodeName)) && p.childNodes.length == 1) {\r
9069                                         set(p); // Set style info on parent instead\r
9070                                         dom.setAttrib(n, 'class', '');\r
9071                                 }\r
9072                         });\r
9073 \r
9074                         // Remove empty wrappers\r
9075                         each(dom.select(nn).reverse(), function(n) {\r
9076                                 if (dom.getAttrib(n, 'mce_new') || (dom.getAttribs(n).length <= 1 && n.className === '')) {\r
9077                                         if (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style'))\r
9078                                                 return dom.remove(n, 1);\r
9079 \r
9080                                         dom.setAttrib(n, 'mce_new', ''); // Remove mce_new marker\r
9081                                 }\r
9082                         });\r
9083 \r
9084                         s.moveToBookmark(b);\r
9085                 },\r
9086 \r
9087                 queryStateJustify : function(c, v) {\r
9088                         var ed = this.editor, n = ed.selection.getNode(), dom = ed.dom;\r
9089 \r
9090                         if (n && n.nodeName == 'IMG') {\r
9091                                 if (dom.getStyle(n, 'float') == v)\r
9092                                         return 1;\r
9093 \r
9094                                 return n.parentNode.style.textAlign == v;\r
9095                         }\r
9096 \r
9097                         n = dom.getParent(ed.selection.getStart(), function(n) {\r
9098                                 return n.nodeType == 1 && n.style.textAlign;\r
9099                         });\r
9100 \r
9101                         if (v == 'full')\r
9102                                 v = 'justify';\r
9103 \r
9104                         if (ed.settings.inline_styles)\r
9105                                 return (n && n.style.textAlign == v);\r
9106 \r
9107                         return this._queryState(c);\r
9108                 },\r
9109 \r
9110                 HiliteColor : function(ui, val) {\r
9111                         var t = this, ed = t.editor, d = ed.getDoc();\r
9112 \r
9113                         function set(s) {\r
9114                                 if (!isGecko)\r
9115                                         return;\r
9116 \r
9117                                 try {\r
9118                                         // Try new Gecko method\r
9119                                         d.execCommand("styleWithCSS", 0, s);\r
9120                                 } catch (ex) {\r
9121                                         // Use old\r
9122                                         d.execCommand("useCSS", 0, !s);\r
9123                                 }\r
9124                         };\r
9125 \r
9126                         if (isGecko || isOpera) {\r
9127                                 set(true);\r
9128                                 d.execCommand('hilitecolor', false, val);\r
9129                                 set(false);\r
9130                         } else\r
9131                                 d.execCommand('BackColor', false, val);\r
9132                 },\r
9133 \r
9134                 Undo : function() {\r
9135                         var ed = this.editor;\r
9136 \r
9137                         if (ed.settings.custom_undo_redo) {\r
9138                                 ed.undoManager.undo();\r
9139                                 ed.nodeChanged();\r
9140                         } else\r
9141                                 ed.getDoc().execCommand('Undo', false, null);\r
9142                 },\r
9143 \r
9144                 Redo : function() {\r
9145                         var ed = this.editor;\r
9146 \r
9147                         if (ed.settings.custom_undo_redo) {\r
9148                                 ed.undoManager.redo();\r
9149                                 ed.nodeChanged();\r
9150                         } else\r
9151                                 ed.getDoc().execCommand('Redo', false, null);\r
9152                 },\r
9153 \r
9154                 FormatBlock : function(ui, val) {\r
9155                         var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b;\r
9156 \r
9157                         function isBlock(n) {\r
9158                                 return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName);\r
9159                         };\r
9160 \r
9161                         bl = dom.getParent(s.getNode(), function(n) {\r
9162                                 return isBlock(n);\r
9163                         });\r
9164 \r
9165                         // IE has an issue where it removes the parent div if you change format on the paragrah in <div><p>Content</p></div>\r
9166                         // FF and Opera doesn't change parent DIV elements if you switch format\r
9167                         if (bl) {\r
9168                                 if ((isIE && isBlock(bl.parentNode)) || bl.nodeName == 'DIV') {\r
9169                                         // Rename block element\r
9170                                         nb = ed.dom.create(val);\r
9171 \r
9172                                         each(dom.getAttribs(bl), function(v) {\r
9173                                                 dom.setAttrib(nb, v.nodeName, dom.getAttrib(bl, v.nodeName));\r
9174                                         });\r
9175 \r
9176                                         b = s.getBookmark();\r
9177                                         dom.replace(nb, bl, 1);\r
9178                                         s.moveToBookmark(b);\r
9179                                         ed.nodeChanged();\r
9180                                         return;\r
9181                                 }\r
9182                         }\r
9183 \r
9184                         val = ed.settings.forced_root_block ? (val || '<p>') : val;\r
9185 \r
9186                         if (val.indexOf('<') == -1)\r
9187                                 val = '<' + val + '>';\r
9188 \r
9189                         if (tinymce.isGecko)\r
9190                                 val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1');\r
9191 \r
9192                         ed.getDoc().execCommand('FormatBlock', false, val);\r
9193                 },\r
9194 \r
9195                 mceCleanup : function() {\r
9196                         var ed = this.editor, s = ed.selection, b = s.getBookmark();\r
9197                         ed.setContent(ed.getContent());\r
9198                         s.moveToBookmark(b);\r
9199                 },\r
9200 \r
9201                 mceRemoveNode : function(ui, val) {\r
9202                         var ed = this.editor, s = ed.selection, b, n = val || s.getNode();\r
9203 \r
9204                         // Make sure that the body node isn't removed\r
9205                         if (n == ed.getBody())\r
9206                                 return;\r
9207 \r
9208                         b = s.getBookmark();\r
9209                         ed.dom.remove(n, 1);\r
9210                         s.moveToBookmark(b);\r
9211                         ed.nodeChanged();\r
9212                 },\r
9213 \r
9214                 mceSelectNodeDepth : function(ui, val) {\r
9215                         var ed = this.editor, s = ed.selection, c = 0;\r
9216 \r
9217                         ed.dom.getParent(s.getNode(), function(n) {\r
9218                                 if (n.nodeType == 1 && c++ == val) {\r
9219                                         s.select(n);\r
9220                                         ed.nodeChanged();\r
9221                                         return false;\r
9222                                 }\r
9223                         }, ed.getBody());\r
9224                 },\r
9225 \r
9226                 mceSelectNode : function(u, v) {\r
9227                         this.editor.selection.select(v);\r
9228                 },\r
9229 \r
9230                 mceInsertContent : function(ui, val) {\r
9231                         this.editor.selection.setContent(val);\r
9232                 },\r
9233 \r
9234                 mceInsertRawHTML : function(ui, val) {\r
9235                         var ed = this.editor;\r
9236 \r
9237                         ed.selection.setContent('tiny_mce_marker');\r
9238                         ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val));\r
9239                 },\r
9240 \r
9241                 mceRepaint : function() {\r
9242                         var s, b, e = this.editor;\r
9243 \r
9244                         if (tinymce.isGecko) {\r
9245                                 try {\r
9246                                         s = e.selection;\r
9247                                         b = s.getBookmark(true);\r
9248 \r
9249                                         if (s.getSel())\r
9250                                                 s.getSel().selectAllChildren(e.getBody());\r
9251 \r
9252                                         s.collapse(true);\r
9253                                         s.moveToBookmark(b);\r
9254                                 } catch (ex) {\r
9255                                         // Ignore\r
9256                                 }\r
9257                         }\r
9258                 },\r
9259 \r
9260                 queryStateUnderline : function() {\r
9261                         var ed = this.editor, n = ed.selection.getNode();\r
9262 \r
9263                         if (n && n.nodeName == 'A')\r
9264                                 return false;\r
9265 \r
9266                         return this._queryState('Underline');\r
9267                 },\r
9268 \r
9269                 queryStateOutdent : function() {\r
9270                         var ed = this.editor, n;\r
9271 \r
9272                         if (ed.settings.inline_styles) {\r
9273                                 if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
9274                                         return true;\r
9275 \r
9276                                 if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
9277                                         return true;\r
9278                         } else\r
9279                                 return !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE');\r
9280 \r
9281                         return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList();\r
9282                 },\r
9283 \r
9284                 queryStateInsertUnorderedList : function() {\r
9285                         return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL');\r
9286                 },\r
9287 \r
9288                 queryStateInsertOrderedList : function() {\r
9289                         return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL');\r
9290                 },\r
9291 \r
9292                 queryStatemceBlockQuote : function() {\r
9293                         return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9294                 },\r
9295 \r
9296                 mceBlockQuote : function() {\r
9297                         var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;\r
9298 \r
9299                         function getBQ(e) {\r
9300                                 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9301                         };\r
9302 \r
9303                         // Get start/end block\r
9304                         sb = dom.getParent(s.getStart(), dom.isBlock);\r
9305                         eb = dom.getParent(s.getEnd(), dom.isBlock);\r
9306 \r
9307                         // Remove blockquote(s)\r
9308                         if (bq = getBQ(sb)) {\r
9309                                 if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
9310                                         bm = s.getBookmark();\r
9311 \r
9312                                 // Move all elements after the end block into new bq\r
9313                                 if (getBQ(eb)) {\r
9314                                         bq2 = bq.cloneNode(false);\r
9315 \r
9316                                         while (n = eb.nextSibling)\r
9317                                                 bq2.appendChild(n.parentNode.removeChild(n));\r
9318                                 }\r
9319 \r
9320                                 // Add new bq after\r
9321                                 if (bq2)\r
9322                                         dom.insertAfter(bq2, bq);\r
9323 \r
9324                                 // Move all selected blocks after the current bq\r
9325                                 nl = t._getSelectedBlocks(sb, eb);\r
9326                                 for (i = nl.length - 1; i >= 0; i--) {\r
9327                                         dom.insertAfter(nl[i], bq);\r
9328                                 }\r
9329 \r
9330                                 // Empty bq, then remove it\r
9331                                 if (/^\s*$/.test(bq.innerHTML))\r
9332                                         dom.remove(bq, 1); // Keep children so boomark restoration works correctly\r
9333 \r
9334                                 // Empty bq, then remote it\r
9335                                 if (bq2 && /^\s*$/.test(bq2.innerHTML))\r
9336                                         dom.remove(bq2, 1); // Keep children so boomark restoration works correctly\r
9337 \r
9338                                 if (!bm) {\r
9339                                         // Move caret inside empty block element\r
9340                                         if (!isIE) {\r
9341                                                 r = ed.getDoc().createRange();\r
9342                                                 r.setStart(sb, 0);\r
9343                                                 r.setEnd(sb, 0);\r
9344                                                 s.setRng(r);\r
9345                                         } else {\r
9346                                                 s.select(sb);\r
9347                                                 s.collapse(0);\r
9348 \r
9349                                                 // IE misses the empty block some times element so we must move back the caret\r
9350                                                 if (dom.getParent(s.getStart(), dom.isBlock) != sb) {\r
9351                                                         r = s.getRng();\r
9352                                                         r.move('character', -1);\r
9353                                                         r.select();\r
9354                                                 }\r
9355                                         }\r
9356                                 } else\r
9357                                         t.editor.selection.moveToBookmark(bm);\r
9358 \r
9359                                 return;\r
9360                         }\r
9361 \r
9362                         // Since IE can start with a totally empty document we need to add the first bq and paragraph\r
9363                         if (isIE && !sb && !eb) {\r
9364                                 t.editor.getDoc().execCommand('Indent');\r
9365                                 n = getBQ(s.getNode());\r
9366                                 n.style.margin = n.dir = ''; // IE adds margin and dir to bq\r
9367                                 return;\r
9368                         }\r
9369 \r
9370                         if (!sb || !eb)\r
9371                                 return;\r
9372 \r
9373                         // If empty paragraph node then do not use bookmark\r
9374                         if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
9375                                 bm = s.getBookmark();\r
9376 \r
9377                         // Move selected block elements into a bq\r
9378                         each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {\r
9379                                 // Found existing BQ add to this one\r
9380                                 if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
9381                                         bq = e;\r
9382                                         return;\r
9383                                 }\r
9384 \r
9385                                 // No BQ found, create one\r
9386                                 if (!bq) {\r
9387                                         bq = dom.create('blockquote');\r
9388                                         e.parentNode.insertBefore(bq, e);\r
9389                                 }\r
9390 \r
9391                                 // Add children from existing BQ\r
9392                                 if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
9393                                         n = e.firstChild;\r
9394 \r
9395                                         while (n) {\r
9396                                                 bq.appendChild(n.cloneNode(true));\r
9397                                                 n = n.nextSibling;\r
9398                                         }\r
9399 \r
9400                                         dom.remove(e);\r
9401                                         return;\r
9402                                 }\r
9403 \r
9404                                 // Add non BQ element to BQ\r
9405                                 bq.appendChild(dom.remove(e));\r
9406                         });\r
9407 \r
9408                         if (!bm) {\r
9409                                 // Move caret inside empty block element\r
9410                                 if (!isIE) {\r
9411                                         r = ed.getDoc().createRange();\r
9412                                         r.setStart(sb, 0);\r
9413                                         r.setEnd(sb, 0);\r
9414                                         s.setRng(r);\r
9415                                 } else {\r
9416                                         s.select(sb);\r
9417                                         s.collapse(1);\r
9418                                 }\r
9419                         } else\r
9420                                 s.moveToBookmark(bm);\r
9421                 },\r
9422 /*\r
9423                 _mceBlockQuote : function() {\r
9424                         var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;\r
9425 \r
9426                         function findBQ(e) {\r
9427                                 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9428                         };\r
9429 \r
9430                         // Remove blockquote(s)\r
9431                         if (findBQ(s.getStart())) {\r
9432                                 each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
9433                                         // Found BQ lets remove it\r
9434                                         if (e.nodeName == 'BLOCKQUOTE')\r
9435                                                 dom.remove(e, 1);\r
9436                                 });\r
9437 \r
9438                                 t.editor.selection.moveToBookmark(b);\r
9439                                 return;\r
9440                         }\r
9441 \r
9442                         each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
9443                                 var n;\r
9444 \r
9445                                 // Found existing BQ add to this one\r
9446                                 if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
9447                                         bq = e;\r
9448                                         return;\r
9449                                 }\r
9450 \r
9451                                 // No BQ found, create one\r
9452                                 if (!bq) {\r
9453                                         bq = dom.create('blockquote');\r
9454                                         e.parentNode.insertBefore(bq, e);\r
9455                                 }\r
9456 \r
9457                                 // Add children from existing BQ\r
9458                                 if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
9459                                         n = e.firstChild;\r
9460 \r
9461                                         while (n) {\r
9462                                                 bq.appendChild(n.cloneNode(true));\r
9463                                                 n = n.nextSibling;\r
9464                                         }\r
9465 \r
9466                                         dom.remove(e);\r
9467 \r
9468                                         return;\r
9469                                 }\r
9470 \r
9471                                 // Add non BQ element to BQ\r
9472                                 bq.appendChild(dom.remove(e));\r
9473                         });\r
9474 \r
9475                         t.editor.selection.moveToBookmark(b);\r
9476                 },\r
9477 */\r
9478                 _getSelectedBlocks : function(st, en) {\r
9479                         var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];\r
9480 \r
9481                         sb = dom.getParent(st || s.getStart(), dom.isBlock);\r
9482                         eb = dom.getParent(en || s.getEnd(), dom.isBlock);\r
9483 \r
9484                         if (sb)\r
9485                                 bl.push(sb);\r
9486 \r
9487                         if (sb && eb && sb != eb) {\r
9488                                 n = sb;\r
9489 \r
9490                                 while ((n = n.nextSibling) && n != eb) {\r
9491                                         if (dom.isBlock(n))\r
9492                                                 bl.push(n);\r
9493                                 }\r
9494                         }\r
9495 \r
9496                         if (eb && sb != eb)\r
9497                                 bl.push(eb);\r
9498 \r
9499                         return bl;\r
9500                 }\r
9501         });\r
9502 })();\r
9503 \r
9504 \r
9505 /* file:jscripts/tiny_mce/classes/UndoManager.js */\r
9506 \r
9507 tinymce.create('tinymce.UndoManager', {\r
9508         index : 0,\r
9509         data : null,\r
9510         typing : 0,\r
9511 \r
9512         UndoManager : function(ed) {\r
9513                 var t = this, Dispatcher = tinymce.util.Dispatcher;\r
9514 \r
9515                 t.editor = ed;\r
9516                 t.data = [];\r
9517                 t.onAdd = new Dispatcher(this);\r
9518                 t.onUndo = new Dispatcher(this);\r
9519                 t.onRedo = new Dispatcher(this);\r
9520         },\r
9521 \r
9522         add : function(l) {\r
9523                 var t = this, i, ed = t.editor, b, s = ed.settings, la;\r
9524 \r
9525                 l = l || {};\r
9526                 l.content = l.content || ed.getContent({format : 'raw', no_events : 1});\r
9527 \r
9528                 // Add undo level if needed\r
9529                 l.content = l.content.replace(/^\s*|\s*$/g, '');\r
9530                 la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];\r
9531                 if (!l.initial && la && l.content == la.content)\r
9532                         return null;\r
9533 \r
9534                 // Time to compress\r
9535                 if (s.custom_undo_redo_levels) {\r
9536                         if (t.data.length > s.custom_undo_redo_levels) {\r
9537                                 for (i = 0; i < t.data.length - 1; i++)\r
9538                                         t.data[i] = t.data[i + 1];\r
9539 \r
9540                                 t.data.length--;\r
9541                                 t.index = t.data.length;\r
9542                         }\r
9543                 }\r
9544 \r
9545                 if (s.custom_undo_redo_restore_selection && !l.initial)\r
9546                         l.bookmark = b = l.bookmark || ed.selection.getBookmark();\r
9547 \r
9548                 if (t.index < t.data.length)\r
9549                         t.index++;\r
9550 \r
9551                 // Only initial marked undo levels should be allowed as first item\r
9552                 // This to workaround a bug with Firefox and the blur event\r
9553                 if (t.data.length === 0 && !l.initial)\r
9554                         return null;\r
9555 \r
9556                 // Add level\r
9557                 t.data.length = t.index + 1;\r
9558                 t.data[t.index++] = l;\r
9559 \r
9560                 if (l.initial)\r
9561                         t.index = 0;\r
9562 \r
9563                 // Set initial bookmark use first real undo level\r
9564                 if (t.data.length == 2 && t.data[0].initial)\r
9565                         t.data[0].bookmark = b;\r
9566 \r
9567                 t.onAdd.dispatch(t, l);\r
9568                 ed.isNotDirty = 0;\r
9569 \r
9570                 //console.dir(t.data);\r
9571 \r
9572                 return l;\r
9573         },\r
9574 \r
9575         undo : function() {\r
9576                 var t = this, ed = t.editor, l = l, i;\r
9577 \r
9578                 if (t.typing) {\r
9579                         t.add();\r
9580                         t.typing = 0;\r
9581                 }\r
9582 \r
9583                 if (t.index > 0) {\r
9584                         // If undo on last index then take snapshot\r
9585                         if (t.index == t.data.length && t.index > 1) {\r
9586                                 i = t.index;\r
9587                                 t.typing = 0;\r
9588 \r
9589                                 if (!t.add())\r
9590                                         t.index = i;\r
9591 \r
9592                                 --t.index;\r
9593                         }\r
9594 \r
9595                         l = t.data[--t.index];\r
9596                         ed.setContent(l.content, {format : 'raw'});\r
9597                         ed.selection.moveToBookmark(l.bookmark);\r
9598 \r
9599                         t.onUndo.dispatch(t, l);\r
9600                 }\r
9601 \r
9602                 return l;\r
9603         },\r
9604 \r
9605         redo : function() {\r
9606                 var t = this, ed = t.editor, l = null;\r
9607 \r
9608                 if (t.index < t.data.length - 1) {\r
9609                         l = t.data[++t.index];\r
9610                         ed.setContent(l.content, {format : 'raw'});\r
9611                         ed.selection.moveToBookmark(l.bookmark);\r
9612 \r
9613                         t.onRedo.dispatch(t, l);\r
9614                 }\r
9615 \r
9616                 return l;\r
9617         },\r
9618 \r
9619         clear : function() {\r
9620                 var t = this;\r
9621 \r
9622                 t.data = [];\r
9623                 t.index = 0;\r
9624                 t.typing = 0;\r
9625                 t.add({initial : true});\r
9626         },\r
9627 \r
9628         hasUndo : function() {\r
9629                 return this.index != 0 || this.typing;\r
9630         },\r
9631 \r
9632         hasRedo : function() {\r
9633                 return this.index < this.data.length - 1;\r
9634         }\r
9635 \r
9636         });\r
9637 /* file:jscripts/tiny_mce/classes/ForceBlocks.js */\r
9638 \r
9639 (function() {\r
9640         // Shorten names\r
9641         var Event, isIE, isGecko, isOpera, each, extend;\r
9642 \r
9643         Event = tinymce.dom.Event;\r
9644         isIE = tinymce.isIE;\r
9645         isGecko = tinymce.isGecko;\r
9646         isOpera = tinymce.isOpera;\r
9647         each = tinymce.each;\r
9648         extend = tinymce.extend;\r
9649 \r
9650         tinymce.create('tinymce.ForceBlocks', {\r
9651                 ForceBlocks : function(ed) {\r
9652                         var t = this, s = ed.settings, elm;\r
9653 \r
9654                         t.editor = ed;\r
9655                         t.dom = ed.dom;\r
9656                         elm = (s.forced_root_block || 'p').toLowerCase();\r
9657                         s.element = elm.toUpperCase();\r
9658 \r
9659                         ed.onPreInit.add(t.setup, t);\r
9660 \r
9661                         t.reOpera = new RegExp('(\\u00a0|&#160;|&nbsp;)<\/' + elm + '>', 'gi');\r
9662                         t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');\r
9663                         t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');\r
9664                         t.reNbsp2BR2 = new RegExp('<p( )([^>]+)>(&nbsp;|&#160;)<\\\/p>|<p>(&nbsp;|&#160;)<\\\/p>'.replace(/p/g, elm), 'gi');\r
9665                         t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
9666                         t.reTrailBr = new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
9667 \r
9668                         function padd(ed, o) {\r
9669                                 if (isOpera)\r
9670                                         o.content = o.content.replace(t.reOpera, '</' + elm + '>');\r
9671 \r
9672                                 o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0</' + elm + '>');\r
9673 \r
9674                                 if (!isIE && !isOpera && o.set) {\r
9675                                         // Use &nbsp; instead of BR in padded paragraphs\r
9676                                         o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');\r
9677                                         o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');\r
9678                                 } else {\r
9679                                         o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');\r
9680                                         o.content = o.content.replace(t.reTrailBr, '</' + elm + '>');\r
9681                                 }\r
9682                         };\r
9683 \r
9684                         ed.onBeforeSetContent.add(padd);\r
9685                         ed.onPostProcess.add(padd);\r
9686 \r
9687                         if (s.forced_root_block) {\r
9688                                 ed.onInit.add(t.forceRoots, t);\r
9689                                 ed.onSetContent.add(t.forceRoots, t);\r
9690                                 ed.onBeforeGetContent.add(t.forceRoots, t);\r
9691                         }\r
9692                 },\r
9693 \r
9694                 setup : function() {\r
9695                         var t = this, ed = t.editor, s = ed.settings;\r
9696 \r
9697                         // Force root blocks when typing and when getting output\r
9698                         if (s.forced_root_block) {\r
9699                                 ed.onKeyUp.add(t.forceRoots, t);\r
9700                                 ed.onPreProcess.add(t.forceRoots, t);\r
9701                         }\r
9702 \r
9703                         if (s.force_br_newlines) {\r
9704                                 // Force IE to produce BRs on enter\r
9705                                 if (isIE) {\r
9706                                         ed.onKeyPress.add(function(ed, e) {\r
9707                                                 var n, s = ed.selection;\r
9708 \r
9709                                                 if (e.keyCode == 13 && s.getNode().nodeName != 'LI') {\r
9710                                                         s.setContent('<br id="__" /> ', {format : 'raw'});\r
9711                                                         n = ed.dom.get('__');\r
9712                                                         n.removeAttribute('id');\r
9713                                                         s.select(n);\r
9714                                                         s.collapse();\r
9715                                                         return Event.cancel(e);\r
9716                                                 }\r
9717                                         });\r
9718                                 }\r
9719 \r
9720                                 return;\r
9721                         }\r
9722 \r
9723                         if (!isIE && s.force_p_newlines) {\r
9724 /*                              ed.onPreProcess.add(function(ed, o) {\r
9725                                         each(ed.dom.select('br', o.node), function(n) {\r
9726                                                 var p = n.parentNode;\r
9727 \r
9728                                                 // Replace <p><br /></p> with <p>&nbsp;</p>\r
9729                                                 if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n)) {\r
9730                                                         p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n);\r
9731                                                 }\r
9732                                         });\r
9733                                 });*/\r
9734 \r
9735                                 ed.onKeyPress.add(function(ed, e) {\r
9736                                         if (e.keyCode == 13 && !e.shiftKey) {\r
9737                                                 if (!t.insertPara(e))\r
9738                                                         Event.cancel(e);\r
9739                                         }\r
9740                                 });\r
9741 \r
9742                                 if (isGecko) {\r
9743                                         ed.onKeyDown.add(function(ed, e) {\r
9744                                                 if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey)\r
9745                                                         t.backspaceDelete(e, e.keyCode == 8);\r
9746                                         });\r
9747                                 }\r
9748                         }\r
9749 \r
9750                         function ren(rn, na) {\r
9751                                 var ne = ed.dom.create(na);\r
9752 \r
9753                                 each(rn.attributes, function(a) {\r
9754                                         if (a.specified && a.nodeValue)\r
9755                                                 ne.setAttribute(a.nodeName.toLowerCase(), a.nodeValue);\r
9756                                 });\r
9757 \r
9758                                 each(rn.childNodes, function(n) {\r
9759                                         ne.appendChild(n.cloneNode(true));\r
9760                                 });\r
9761 \r
9762                                 rn.parentNode.replaceChild(ne, rn);\r
9763 \r
9764                                 return ne;\r
9765                         };\r
9766 \r
9767                         // Replaces IE:s auto generated paragraphs with the specified element name\r
9768                         if (isIE && s.element != 'P') {\r
9769                                 ed.onKeyPress.add(function(ed, e) {\r
9770                                         t.lastElm = ed.selection.getNode().nodeName;\r
9771                                 });\r
9772 \r
9773                                 ed.onKeyUp.add(function(ed, e) {\r
9774                                         var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();\r
9775 \r
9776                                         if (b.childNodes.length === 1 && n.nodeName == 'P') {\r
9777                                                 n = ren(n, s.element);\r
9778                                                 sel.select(n);\r
9779                                                 sel.collapse();\r
9780                                                 ed.nodeChanged();\r
9781                                         } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {\r
9782                                                 bl = ed.dom.getParent(n, 'P');\r
9783 \r
9784                                                 if (bl) {\r
9785                                                         ren(bl, s.element);\r
9786                                                         ed.nodeChanged();\r
9787                                                 }\r
9788                                         }\r
9789                                 });\r
9790                         }\r
9791                 },\r
9792 \r
9793                 find : function(n, t, s) {\r
9794                         var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1;\r
9795 \r
9796                         while (n = w.nextNode()) {\r
9797                                 c++;\r
9798 \r
9799                                 // Index by node\r
9800                                 if (t == 0 && n == s)\r
9801                                         return c;\r
9802 \r
9803                                 // Node by index\r
9804                                 if (t == 1 && c == s)\r
9805                                         return n;\r
9806                         }\r
9807 \r
9808                         return -1;\r
9809                 },\r
9810 \r
9811                 forceRoots : function(ed, e) {\r
9812                         var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF;\r
9813                         var nx, bl, bp, sp, le, nl = b.childNodes, i;\r
9814 \r
9815                         // Fix for bug #1863847\r
9816                         if (e && e.keyCode == 13)\r
9817                                 return true;\r
9818 \r
9819                         // Wrap non blocks into blocks\r
9820                         for (i = nl.length - 1; i >= 0; i--) {\r
9821                                 nx = nl[i];\r
9822 \r
9823                                 // Is text or non block element\r
9824                                 if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) {\r
9825                                         if (!bl) {\r
9826                                                 // Create new block but ignore whitespace\r
9827                                                 if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {\r
9828                                                         // Store selection\r
9829                                                         if (si == -2 && r) {\r
9830                                                                 if (!isIE) {\r
9831                                                                         // If element is inside body, might not be the case in contentEdiable mode\r
9832                                                                         if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) {\r
9833                                                                                 so = r.startOffset;\r
9834                                                                                 eo = r.endOffset;\r
9835                                                                                 si = t.find(b, 0, r.startContainer);\r
9836                                                                                 ei = t.find(b, 0, r.endContainer);\r
9837                                                                         }\r
9838                                                                 } else {\r
9839                                                                         tr = d.body.createTextRange();\r
9840                                                                         tr.moveToElementText(b);\r
9841                                                                         tr.collapse(1);\r
9842                                                                         bp = tr.move('character', c) * -1;\r
9843 \r
9844                                                                         tr = r.duplicate();\r
9845                                                                         tr.collapse(1);\r
9846                                                                         sp = tr.move('character', c) * -1;\r
9847 \r
9848                                                                         tr = r.duplicate();\r
9849                                                                         tr.collapse(0);\r
9850                                                                         le = (tr.move('character', c) * -1) - sp;\r
9851 \r
9852                                                                         si = sp - bp;\r
9853                                                                         ei = le;\r
9854                                                                 }\r
9855                                                         }\r
9856 \r
9857                                                         bl = ed.dom.create(ed.settings.forced_root_block);\r
9858                                                         bl.appendChild(nx.cloneNode(1));\r
9859                                                         nx.parentNode.replaceChild(bl, nx);\r
9860                                                 }\r
9861                                         } else {\r
9862                                                 if (bl.hasChildNodes())\r
9863                                                         bl.insertBefore(nx, bl.firstChild);\r
9864                                                 else\r
9865                                                         bl.appendChild(nx);\r
9866                                         }\r
9867                                 } else\r
9868                                         bl = null; // Time to create new block\r
9869                         }\r
9870 \r
9871                         // Restore selection\r
9872                         if (si != -2) {\r
9873                                 if (!isIE) {\r
9874                                         bl = b.getElementsByTagName(ed.settings.element)[0];\r
9875                                         r = d.createRange();\r
9876 \r
9877                                         // Select last location or generated block\r
9878                                         if (si != -1)\r
9879                                                 r.setStart(t.find(b, 1, si), so);\r
9880                                         else\r
9881                                                 r.setStart(bl, 0);\r
9882 \r
9883                                         // Select last location or generated block\r
9884                                         if (ei != -1)\r
9885                                                 r.setEnd(t.find(b, 1, ei), eo);\r
9886                                         else\r
9887                                                 r.setEnd(bl, 0);\r
9888 \r
9889                                         if (s) {\r
9890                                                 s.removeAllRanges();\r
9891                                                 s.addRange(r);\r
9892                                         }\r
9893                                 } else {\r
9894                                         try {\r
9895                                                 r = s.createRange();\r
9896                                                 r.moveToElementText(b);\r
9897                                                 r.collapse(1);\r
9898                                                 r.moveStart('character', si);\r
9899                                                 r.moveEnd('character', ei);\r
9900                                                 r.select();\r
9901                                         } catch (ex) {\r
9902                                                 // Ignore\r
9903                                         }\r
9904                                 }\r
9905                         }\r
9906                 },\r
9907 \r
9908                 getParentBlock : function(n) {\r
9909                         var d = this.dom;\r
9910 \r
9911                         return d.getParent(n, d.isBlock);\r
9912                 },\r
9913 \r
9914                 insertPara : function(e) {\r
9915                         var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;\r
9916                         var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch;\r
9917 \r
9918                         function isEmpty(n) {\r
9919                                 n = n.innerHTML;\r
9920                                 n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars\r
9921                                 n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
9922 \r
9923                                 return n.replace(/[ \t\r\n]+/g, '') == '';\r
9924                         };\r
9925 \r
9926                         // If root blocks are forced then use Operas default behavior since it's really good\r
9927 // Removed due to bug: #1853816\r
9928 //                      if (se.forced_root_block && isOpera)\r
9929 //                              return true;\r
9930 \r
9931                         // Setup before range\r
9932                         rb = d.createRange();\r
9933 \r
9934                         // If is before the first block element and in body, then move it into first block element\r
9935                         rb.setStart(s.anchorNode, s.anchorOffset);\r
9936                         rb.collapse(true);\r
9937 \r
9938                         // Setup after range\r
9939                         ra = d.createRange();\r
9940 \r
9941                         // If is before the first block element and in body, then move it into first block element\r
9942                         ra.setStart(s.focusNode, s.focusOffset);\r
9943                         ra.collapse(true);\r
9944 \r
9945                         // Setup start/end points\r
9946                         dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0;\r
9947                         sn = dir ? s.anchorNode : s.focusNode;\r
9948                         so = dir ? s.anchorOffset : s.focusOffset;\r
9949                         en = dir ? s.focusNode : s.anchorNode;\r
9950                         eo = dir ? s.focusOffset : s.anchorOffset;\r
9951 \r
9952                         // If selection is in empty table cell\r
9953                         if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) {\r
9954                                 dom.remove(sn.firstChild); // Remove BR\r
9955 \r
9956                                 // Create two new block elements\r
9957                                 ed.dom.add(sn, se.element, null, '<br />');\r
9958                                 aft = ed.dom.add(sn, se.element, null, '<br />');\r
9959 \r
9960                                 // Move caret into the last one\r
9961                                 r = d.createRange();\r
9962                                 r.selectNodeContents(aft);\r
9963                                 r.collapse(1);\r
9964                                 ed.selection.setRng(r);\r
9965 \r
9966                                 return false;\r
9967                         }\r
9968 \r
9969                         // If the caret is in an invalid location in FF we need to move it into the first block\r
9970                         if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) {\r
9971                                 sn = en = sn.firstChild;\r
9972                                 so = eo = 0;\r
9973                                 rb = d.createRange();\r
9974                                 rb.setStart(sn, 0);\r
9975                                 ra = d.createRange();\r
9976                                 ra.setStart(en, 0);\r
9977                         }\r
9978 \r
9979                         // Never use body as start or end node\r
9980                         sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes\r
9981                         sn = sn.nodeName == "BODY" ? sn.firstChild : sn;\r
9982                         en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes\r
9983                         en = en.nodeName == "BODY" ? en.firstChild : en;\r
9984 \r
9985                         // Get start and end blocks\r
9986                         sb = t.getParentBlock(sn);\r
9987                         eb = t.getParentBlock(en);\r
9988                         bn = sb ? sb.nodeName : se.element; // Get block name to create\r
9989 \r
9990                         // Return inside list use default browser behavior\r
9991                         if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))\r
9992                                 return true;\r
9993 \r
9994                         // If caption or absolute layers then always generate new blocks within\r
9995                         if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {\r
9996                                 bn = se.element;\r
9997                                 sb = null;\r
9998                         }\r
9999 \r
10000                         // If caption or absolute layers then always generate new blocks within\r
10001                         if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {\r
10002                                 bn = se.element;\r
10003                                 eb = null;\r
10004                         }\r
10005 \r
10006                         // Use P instead\r
10007                         if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {\r
10008                                 bn = se.element;\r
10009                                 sb = eb = null;\r
10010                         }\r
10011 \r
10012                         // Setup new before and after blocks\r
10013                         bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn);\r
10014                         aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn);\r
10015 \r
10016                         // Remove id from after clone\r
10017                         aft.removeAttribute('id');\r
10018 \r
10019                         // Is header and cursor is at the end, then force paragraph under\r
10020                         if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)\r
10021                                 aft = ed.dom.create(se.element);\r
10022 \r
10023                         // Find start chop node\r
10024                         n = sc = sn;\r
10025                         do {\r
10026                                 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))\r
10027                                         break;\r
10028 \r
10029                                 sc = n;\r
10030                         } while ((n = n.previousSibling ? n.previousSibling : n.parentNode));\r
10031 \r
10032                         // Find end chop node\r
10033                         n = ec = en;\r
10034                         do {\r
10035                                 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))\r
10036                                         break;\r
10037 \r
10038                                 ec = n;\r
10039                         } while ((n = n.nextSibling ? n.nextSibling : n.parentNode));\r
10040 \r
10041                         // Place first chop part into before block element\r
10042                         if (sc.nodeName == bn)\r
10043                                 rb.setStart(sc, 0);\r
10044                         else\r
10045                                 rb.setStartBefore(sc);\r
10046 \r
10047                         rb.setEnd(sn, so);\r
10048                         bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari\r
10049 \r
10050                         // Place secnd chop part within new block element\r
10051                         try {\r
10052                                 ra.setEndAfter(ec);\r
10053                         } catch(ex) {\r
10054                                 //console.debug(s.focusNode, s.focusOffset);\r
10055                         }\r
10056 \r
10057                         ra.setStart(en, eo);\r
10058                         aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari\r
10059 \r
10060                         // Create range around everything\r
10061                         r = d.createRange();\r
10062                         if (!sc.previousSibling && sc.parentNode.nodeName == bn) {\r
10063                                 r.setStartBefore(sc.parentNode);\r
10064                         } else {\r
10065                                 if (rb.startContainer.nodeName == bn && rb.startOffset == 0)\r
10066                                         r.setStartBefore(rb.startContainer);\r
10067                                 else\r
10068                                         r.setStart(rb.startContainer, rb.startOffset);\r
10069                         }\r
10070 \r
10071                         if (!ec.nextSibling && ec.parentNode.nodeName == bn)\r
10072                                 r.setEndAfter(ec.parentNode);\r
10073                         else\r
10074                                 r.setEnd(ra.endContainer, ra.endOffset);\r
10075 \r
10076                         // Delete and replace it with new block elements\r
10077                         r.deleteContents();\r
10078 \r
10079                         if (isOpera)\r
10080                                 ed.getWin().scrollTo(0, vp.y);\r
10081 \r
10082                         // Never wrap blocks in blocks\r
10083                         if (bef.firstChild && bef.firstChild.nodeName == bn)\r
10084                                 bef.innerHTML = bef.firstChild.innerHTML;\r
10085 \r
10086                         if (aft.firstChild && aft.firstChild.nodeName == bn)\r
10087                                 aft.innerHTML = aft.firstChild.innerHTML;\r
10088 \r
10089                         // Padd empty blocks\r
10090                         if (isEmpty(bef))\r
10091                                 bef.innerHTML = '<br />';\r
10092 \r
10093                         if (isEmpty(aft))\r
10094                                 aft.innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there\r
10095 \r
10096                         // Opera needs this one backwards for older versions\r
10097                         if (isOpera && parseFloat(opera.version()) < 9.5) {\r
10098                                 r.insertNode(bef);\r
10099                                 r.insertNode(aft);\r
10100                         } else {\r
10101                                 r.insertNode(aft);\r
10102                                 r.insertNode(bef);\r
10103                         }\r
10104 \r
10105                         // Normalize\r
10106                         aft.normalize();\r
10107                         bef.normalize();\r
10108 \r
10109                         function first(n) {\r
10110                                 return d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() || n;\r
10111                         };\r
10112 \r
10113                         // Move cursor and scroll into view\r
10114                         r = d.createRange();\r
10115                         r.selectNodeContents(isGecko ? first(aft) : aft);\r
10116                         r.collapse(1);\r
10117                         s.removeAllRanges();\r
10118                         s.addRange(r);\r
10119 \r
10120                         // scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs\r
10121                         y = ed.dom.getPos(aft).y;\r
10122                         ch = aft.clientHeight;\r
10123 \r
10124                         // Is element within viewport\r
10125                         if (y < vp.y || y + ch > vp.y + vp.h) {\r
10126                                 ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + ch);\r
10127                                 //console.debug('SCROLL!', 'vp.y: ' + vp.y, 'y' + y, 'vp.h' + vp.h, 'clientHeight' + aft.clientHeight, 'yyy: ' + (y < vp.y ? y : y - vp.h + aft.clientHeight));\r
10128                         }\r
10129 \r
10130                         return false;\r
10131                 },\r
10132 \r
10133                 backspaceDelete : function(e, bs) {\r
10134                         var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;\r
10135 \r
10136                         // The caret sometimes gets stuck in Gecko if you delete empty paragraphs\r
10137                         // This workaround removes the element by hand and moves the caret to the previous element\r
10138                         if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) {\r
10139                                 if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) {\r
10140                                         // Find previous block element\r
10141                                         n = sc;\r
10142                                         while ((n = n.previousSibling) && !ed.dom.isBlock(n)) ;\r
10143 \r
10144                                         if (n) {\r
10145                                                 if (sc != b.firstChild) {\r
10146                                                         // Find last text node\r
10147                                                         w = ed.dom.doc.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
10148                                                         while (tn = w.nextNode())\r
10149                                                                 n = tn;\r
10150 \r
10151                                                         // Place caret at the end of last text node\r
10152                                                         r = ed.getDoc().createRange();\r
10153                                                         r.setStart(n, n.nodeValue ? n.nodeValue.length : 0);\r
10154                                                         r.setEnd(n, n.nodeValue ? n.nodeValue.length : 0);\r
10155                                                         se.setRng(r);\r
10156 \r
10157                                                         // Remove the target container\r
10158                                                         ed.dom.remove(sc);\r
10159                                                 }\r
10160 \r
10161                                                 return Event.cancel(e);\r
10162                                         }\r
10163                                 }\r
10164                         }\r
10165 \r
10166                         // Gecko generates BR elements here and there, we don't like those so lets remove them\r
10167                         function handler(e) {\r
10168                                 e = e.target;\r
10169 \r
10170                                 // A new BR was created in a block element, remove it\r
10171                                 if (e && e.parentNode && e.nodeName == 'BR' && (n = t.getParentBlock(e))) {\r
10172                                         Event.remove(b, 'DOMNodeInserted', handler);\r
10173 \r
10174                                         // Only remove BR elements that got inserted in the middle of the text\r
10175                                         if (e.previousSibling || e.nextSibling)\r
10176                                                 ed.dom.remove(e);\r
10177                                 }\r
10178                         };\r
10179 \r
10180                         // Listen for new nodes\r
10181                         Event._add(b, 'DOMNodeInserted', handler);\r
10182 \r
10183                         // Remove listener\r
10184                         window.setTimeout(function() {\r
10185                                 Event._remove(b, 'DOMNodeInserted', handler);\r
10186                         }, 1);\r
10187                 }\r
10188         });\r
10189 })();\r
10190 \r
10191 /* file:jscripts/tiny_mce/classes/ControlManager.js */\r
10192 \r
10193 (function() {\r
10194         // Shorten names\r
10195         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;\r
10196 \r
10197         tinymce.create('tinymce.ControlManager', {\r
10198                 ControlManager : function(ed, s) {\r
10199                         var t = this, i;\r
10200 \r
10201                         s = s || {};\r
10202                         t.editor = ed;\r
10203                         t.controls = {};\r
10204                         t.onAdd = new tinymce.util.Dispatcher(t);\r
10205                         t.onPostRender = new tinymce.util.Dispatcher(t);\r
10206                         t.prefix = s.prefix || ed.id + '_';\r
10207                         t._cls = {};\r
10208 \r
10209                         t.onPostRender.add(function() {\r
10210                                 each(t.controls, function(c) {\r
10211                                         c.postRender();\r
10212                                 });\r
10213                         });\r
10214                 },\r
10215 \r
10216                 get : function(id) {\r
10217                         return this.controls[this.prefix + id] || this.controls[id];\r
10218                 },\r
10219 \r
10220                 setActive : function(id, s) {\r
10221                         var c = null;\r
10222 \r
10223                         if (c = this.get(id))\r
10224                                 c.setActive(s);\r
10225 \r
10226                         return c;\r
10227                 },\r
10228 \r
10229                 setDisabled : function(id, s) {\r
10230                         var c = null;\r
10231 \r
10232                         if (c = this.get(id))\r
10233                                 c.setDisabled(s);\r
10234 \r
10235                         return c;\r
10236                 },\r
10237 \r
10238                 add : function(c) {\r
10239                         var t = this;\r
10240 \r
10241                         if (c) {\r
10242                                 t.controls[c.id] = c;\r
10243                                 t.onAdd.dispatch(c, t);\r
10244                         }\r
10245 \r
10246                         return c;\r
10247                 },\r
10248 \r
10249                 createControl : function(n) {\r
10250                         var c, t = this, ed = t.editor;\r
10251 \r
10252                         each(ed.plugins, function(p) {\r
10253                                 if (p.createControl) {\r
10254                                         c = p.createControl(n, t);\r
10255 \r
10256                                         if (c)\r
10257                                                 return false;\r
10258                                 }\r
10259                         });\r
10260 \r
10261                         switch (n) {\r
10262                                 case "|":\r
10263                                 case "separator":\r
10264                                         return t.createSeparator();\r
10265                         }\r
10266 \r
10267                         if (!c && ed.buttons && (c = ed.buttons[n]))\r
10268                                 return t.createButton(n, c);\r
10269 \r
10270                         return t.add(c);\r
10271                 },\r
10272 \r
10273                 createDropMenu : function(id, s, cc) {\r
10274                         var t = this, ed = t.editor, c, bm, v, cls;\r
10275 \r
10276                         s = extend({\r
10277                                 'class' : 'mceDropDown',\r
10278                                 constrain : ed.settings.constrain_menus\r
10279                         }, s);\r
10280 \r
10281                         s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';\r
10282                         if (v = ed.getParam('skin_variant'))\r
10283                                 s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);\r
10284 \r
10285                         id = t.prefix + id;\r
10286                         cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;\r
10287                         c = t.controls[id] = new cls(id, s);\r
10288                         c.onAddItem.add(function(c, o) {\r
10289                                 var s = o.settings;\r
10290 \r
10291                                 s.title = ed.getLang(s.title, s.title);\r
10292 \r
10293                                 if (!s.onclick) {\r
10294                                         s.onclick = function(v) {\r
10295                                                 ed.execCommand(s.cmd, s.ui || false, s.value);\r
10296                                         };\r
10297                                 }\r
10298                         });\r
10299 \r
10300                         ed.onRemove.add(function() {\r
10301                                 c.destroy();\r
10302                         });\r
10303 \r
10304                         // Fix for bug #1897785, #1898007\r
10305                         if (tinymce.isIE) {\r
10306                                 c.onShowMenu.add(function() {\r
10307                                         bm = ed.selection.getBookmark(1);\r
10308                                 });\r
10309 \r
10310                                 c.onHideMenu.add(function() {\r
10311                                         if (bm)\r
10312                                                 ed.selection.moveToBookmark(bm);\r
10313                                 });\r
10314                         }\r
10315 \r
10316                         return t.add(c);\r
10317                 },\r
10318 \r
10319                 createListBox : function(id, s, cc) {\r
10320                         var t = this, ed = t.editor, cmd, c, cls;\r
10321 \r
10322                         if (t.get(id))\r
10323                                 return null;\r
10324 \r
10325                         s.title = ed.translate(s.title);\r
10326                         s.scope = s.scope || ed;\r
10327 \r
10328                         if (!s.onselect) {\r
10329                                 s.onselect = function(v) {\r
10330                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10331                                 };\r
10332                         }\r
10333 \r
10334                         s = extend({\r
10335                                 title : s.title,\r
10336                                 'class' : 'mce_' + id,\r
10337                                 scope : s.scope,\r
10338                                 control_manager : t\r
10339                         }, s);\r
10340 \r
10341                         id = t.prefix + id;\r
10342 \r
10343                         if (ed.settings.use_native_selects)\r
10344                                 c = new tinymce.ui.NativeListBox(id, s);\r
10345                         else {\r
10346                                 cls = cc || t._cls.listbox || tinymce.ui.ListBox;\r
10347                                 c = new cls(id, s);\r
10348                         }\r
10349 \r
10350                         t.controls[id] = c;\r
10351 \r
10352                         // Fix focus problem in Safari\r
10353                         if (tinymce.isWebKit) {\r
10354                                 c.onPostRender.add(function(c, n) {\r
10355                                         // Store bookmark on mousedown\r
10356                                         Event.add(n, 'mousedown', function() {\r
10357                                                 ed.bookmark = ed.selection.getBookmark('simple');\r
10358                                         });\r
10359 \r
10360                                         // Restore on focus, since it might be lost\r
10361                                         Event.add(n, 'focus', function() {\r
10362                                                 ed.selection.moveToBookmark(ed.bookmark);\r
10363                                                 ed.bookmark = null;\r
10364                                         });\r
10365                                 });\r
10366                         }\r
10367 \r
10368                         if (c.hideMenu)\r
10369                                 ed.onMouseDown.add(c.hideMenu, c);\r
10370 \r
10371                         return t.add(c);\r
10372                 },\r
10373 \r
10374                 createButton : function(id, s, cc) {\r
10375                         var t = this, ed = t.editor, o, c, cls;\r
10376 \r
10377                         if (t.get(id))\r
10378                                 return null;\r
10379 \r
10380                         s.title = ed.translate(s.title);\r
10381                         s.label = ed.translate(s.label);\r
10382                         s.scope = s.scope || ed;\r
10383 \r
10384                         if (!s.onclick && !s.menu_button) {\r
10385                                 s.onclick = function() {\r
10386                                         ed.execCommand(s.cmd, s.ui || false, s.value);\r
10387                                 };\r
10388                         }\r
10389 \r
10390                         s = extend({\r
10391                                 title : s.title,\r
10392                                 'class' : 'mce_' + id,\r
10393                                 unavailable_prefix : ed.getLang('unavailable', ''),\r
10394                                 scope : s.scope,\r
10395                                 control_manager : t\r
10396                         }, s);\r
10397 \r
10398                         id = t.prefix + id;\r
10399 \r
10400                         if (s.menu_button) {\r
10401                                 cls = cc || t._cls.menubutton || tinymce.ui.MenuButton;\r
10402                                 c = new cls(id, s);\r
10403                                 ed.onMouseDown.add(c.hideMenu, c);\r
10404                         } else {\r
10405                                 cls = t._cls.button || tinymce.ui.Button;\r
10406                                 c = new cls(id, s);\r
10407                         }\r
10408 \r
10409                         return t.add(c);\r
10410                 },\r
10411 \r
10412                 createMenuButton : function(id, s) {\r
10413                         s = s || {};\r
10414                         s.menu_button = 1;\r
10415 \r
10416                         return this.createButton(id, s);\r
10417                 },\r
10418 \r
10419                 createSplitButton : function(id, s, cc) {\r
10420                         var t = this, ed = t.editor, cmd, c, cls;\r
10421 \r
10422                         if (t.get(id))\r
10423                                 return null;\r
10424 \r
10425                         s.title = ed.translate(s.title);\r
10426                         s.scope = s.scope || ed;\r
10427 \r
10428                         if (!s.onclick) {\r
10429                                 s.onclick = function(v) {\r
10430                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10431                                 };\r
10432                         }\r
10433 \r
10434                         if (!s.onselect) {\r
10435                                 s.onselect = function(v) {\r
10436                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10437                                 };\r
10438                         }\r
10439 \r
10440                         s = extend({\r
10441                                 title : s.title,\r
10442                                 'class' : 'mce_' + id,\r
10443                                 scope : s.scope,\r
10444                                 control_manager : t\r
10445                         }, s);\r
10446 \r
10447                         id = t.prefix + id;\r
10448                         cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton;\r
10449                         c = t.add(new cls(id, s));\r
10450                         ed.onMouseDown.add(c.hideMenu, c);\r
10451 \r
10452                         return c;\r
10453                 },\r
10454 \r
10455                 createColorSplitButton : function(id, s, cc) {\r
10456                         var t = this, ed = t.editor, cmd, c, cls, bm;\r
10457 \r
10458                         if (t.get(id))\r
10459                                 return null;\r
10460 \r
10461                         s.title = ed.translate(s.title);\r
10462                         s.scope = s.scope || ed;\r
10463 \r
10464                         if (!s.onclick) {\r
10465                                 s.onclick = function(v) {\r
10466                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10467                                 };\r
10468                         }\r
10469 \r
10470                         if (!s.onselect) {\r
10471                                 s.onselect = function(v) {\r
10472                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10473                                 };\r
10474                         }\r
10475 \r
10476                         s = extend({\r
10477                                 title : s.title,\r
10478                                 'class' : 'mce_' + id,\r
10479                                 'menu_class' : ed.getParam('skin') + 'Skin',\r
10480                                 scope : s.scope,\r
10481                                 more_colors_title : ed.getLang('more_colors')\r
10482                         }, s);\r
10483 \r
10484                         id = t.prefix + id;\r
10485                         cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton;\r
10486                         c = new cls(id, s);\r
10487                         ed.onMouseDown.add(c.hideMenu, c);\r
10488 \r
10489                         // Remove the menu element when the editor is removed\r
10490                         ed.onRemove.add(function() {\r
10491                                 c.destroy();\r
10492                         });\r
10493 \r
10494                         // Fix for bug #1897785, #1898007\r
10495                         if (tinymce.isIE) {\r
10496                                 c.onShowMenu.add(function() {\r
10497                                         bm = ed.selection.getBookmark(1);\r
10498                                 });\r
10499 \r
10500                                 c.onHideMenu.add(function() {\r
10501                                         if (bm) {\r
10502                                                 ed.selection.moveToBookmark(bm);\r
10503                                                 bm = 0;\r
10504                                         }\r
10505                                 });\r
10506                         }\r
10507 \r
10508                         return t.add(c);\r
10509                 },\r
10510 \r
10511                 createToolbar : function(id, s, cc) {\r
10512                         var c, t = this, cls;\r
10513 \r
10514                         id = t.prefix + id;\r
10515                         cls = cc || t._cls.toolbar || tinymce.ui.Toolbar;\r
10516                         c = new cls(id, s);\r
10517 \r
10518                         if (t.get(id))\r
10519                                 return null;\r
10520 \r
10521                         return t.add(c);\r
10522                 },\r
10523 \r
10524                 createSeparator : function(cc) {\r
10525                         var cls = cc || this._cls.separator || tinymce.ui.Separator;\r
10526 \r
10527                         return new cls();\r
10528                 },\r
10529 \r
10530                 setControlType : function(n, c) {\r
10531                         return this._cls[n.toLowerCase()] = c;\r
10532                 },\r
10533 \r
10534                 destroy : function() {\r
10535                         each(this.controls, function(c) {\r
10536                                 c.destroy();\r
10537                         });\r
10538 \r
10539                         this.controls = null;\r
10540                 }\r
10541 \r
10542                 });\r
10543 })();\r
10544 \r
10545 /* file:jscripts/tiny_mce/classes/WindowManager.js */\r
10546 \r
10547 (function() {\r
10548         var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;\r
10549 \r
10550         tinymce.create('tinymce.WindowManager', {\r
10551                 WindowManager : function(ed) {\r
10552                         var t = this;\r
10553 \r
10554                         t.editor = ed;\r
10555                         t.onOpen = new Dispatcher(t);\r
10556                         t.onClose = new Dispatcher(t);\r
10557                         t.params = {};\r
10558                         t.features = {};\r
10559                 },\r
10560 \r
10561                 open : function(s, p) {\r
10562                         var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort(), u;\r
10563 \r
10564                         // Default some options\r
10565                         s = s || {};\r
10566                         p = p || {};\r
10567                         sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window\r
10568                         sh = isOpera ? vp.h : screen.height;\r
10569                         s.name = s.name || 'mc_' + new Date().getTime();\r
10570                         s.width = parseInt(s.width || 320);\r
10571                         s.height = parseInt(s.height || 240);\r
10572                         s.resizable = true;\r
10573                         s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0);\r
10574                         s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0);\r
10575                         p.inline = false;\r
10576                         p.mce_width = s.width;\r
10577                         p.mce_height = s.height;\r
10578                         p.mce_auto_focus = s.auto_focus;\r
10579 \r
10580                         if (mo) {\r
10581                                 if (isIE) {\r
10582                                         s.center = true;\r
10583                                         s.help = false;\r
10584                                         s.dialogWidth = s.width + 'px';\r
10585                                         s.dialogHeight = s.height + 'px';\r
10586                                         s.scroll = s.scrollbars || false;\r
10587                                 }\r
10588                         }\r
10589 \r
10590                         // Build features string\r
10591                         each(s, function(v, k) {\r
10592                                 if (tinymce.is(v, 'boolean'))\r
10593                                         v = v ? 'yes' : 'no';\r
10594 \r
10595                                 if (!/^(name|url)$/.test(k)) {\r
10596                                         if (isIE && mo)\r
10597                                                 f += (f ? ';' : '') + k + ':' + v;\r
10598                                         else\r
10599                                                 f += (f ? ',' : '') + k + '=' + v;\r
10600                                 }\r
10601                         });\r
10602 \r
10603                         t.features = s;\r
10604                         t.params = p;\r
10605                         t.onOpen.dispatch(t, s, p);\r
10606 \r
10607                         u = s.url || s.file;\r
10608                         if (tinymce.relaxedDomain)\r
10609                                 u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;\r
10610 \r
10611                         u = tinymce._addVer(u);\r
10612 \r
10613                         try {\r
10614                                 if (isIE && mo) {\r
10615                                         w = 1;\r
10616                                         window.showModalDialog(u, window, f);\r
10617                                 } else\r
10618                                         w = window.open(u, s.name, f);\r
10619                         } catch (ex) {\r
10620                                 // Ignore\r
10621                         }\r
10622 \r
10623                         if (!w)\r
10624                                 alert(t.editor.getLang('popup_blocked'));\r
10625                 },\r
10626 \r
10627                 close : function(w) {\r
10628                         w.close();\r
10629                         this.onClose.dispatch(this);\r
10630                 },\r
10631 \r
10632                 createInstance : function(cl, a, b, c, d, e) {\r
10633                         var f = tinymce.resolve(cl);\r
10634 \r
10635                         return new f(a, b, c, d, e);\r
10636                 },\r
10637 \r
10638                 confirm : function(t, cb, s) {\r
10639                         cb.call(s || this, confirm(this._decode(this.editor.getLang(t, t))));\r
10640                 },\r
10641 \r
10642                 alert : function(tx, cb, s) {\r
10643                         var t = this;\r
10644         \r
10645                         alert(t._decode(t.editor.getLang(tx, tx)));\r
10646 \r
10647                         if (cb)\r
10648                                 cb.call(s || t);\r
10649                 },\r
10650 \r
10651                 // Internal functions\r
10652 \r
10653                 _decode : function(s) {\r
10654                         return tinymce.DOM.decode(s).replace(/\\n/g, '\n');\r
10655                 }\r
10656 \r
10657                 });\r
10658 }());