Added name column to all role lists.
[Melange.git] / app / tiny_mce / tiny_mce_src.js
blobd1a9b1f71b780585027365adb94a985a207a0902
1 \r
2 /* file:jscripts/tiny_mce/classes/tinymce.js */\r
3 \r
4 var tinymce = {\r
5         majorVersion : '3',\r
6         minorVersion : '1.1',\r
7         releaseDate : '2008-08-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
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
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
29                 // Get suffix and base\r
30                 t.suffix = '';\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
40                                 base = v ? v.match(/.*\//)[0] : ''; // Get only directory\r
41                         }\r
42                 }\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
49                                 if ((p = n.src.indexOf('?')) != -1)\r
50                                         t.query = n.src.substring(p + 1);\r
52                                 t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));\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
58                                 return t.baseURL;\r
59                         }\r
61                         return null;\r
62                 };\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
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
81                 return;\r
82         },\r
84         is : function(o, t) {\r
85                 var n = typeof(o);\r
87                 if (!t)\r
88                         return n != 'undefined';\r
90                 if (t == 'array' && (o instanceof Array))\r
91                         return true;\r
93                 return n == t;\r
94         },\r
96         // #if !jquery\r
98         each : function(o, cb, s) {\r
99                 var n, l;\r
101                 if (!o)\r
102                         return 0;\r
104                 s = s || o;\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
122                 return 1;\r
123         },\r
125         map : function(a, f) {\r
126                 var o = [];\r
128                 tinymce.each(a, function(v) {\r
129                         o.push(f(v));\r
130                 });\r
132                 return o;\r
133         },\r
135         grep : function(a, f) {\r
136                 var o = [];\r
138                 tinymce.each(a, function(v) {\r
139                         if (!f || f(v))\r
140                                 o.push(v);\r
141                 });\r
143                 return o;\r
144         },\r
146         inArray : function(a, v) {\r
147                 var i, l;\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
156                 return -1;\r
157         },\r
159         extend : function(o, e) {\r
160                 var i, a = arguments;\r
162                 for (i=1; i<a.length; i++) {\r
163                         e = a[i];\r
165                         tinymce.each(e, function(v, n) {\r
166                                 if (typeof(v) !== 'undefined')\r
167                                         o[n] = v;\r
168                         });\r
169                 }\r
171                 return o;\r
172         },\r
174         trim : function(s) {\r
175                 return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');\r
176         },\r
178         // #endif\r
180         create : function(s, p) {\r
181                 var t = this, sp, ns, cn, scn, c, de = 0;\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
187                 // Create namespace for new class\r
188                 ns = t.createNS(s[3].replace(/\.\w+$/, ''));\r
190                 // Class already exists\r
191                 if (ns[cn])\r
192                         return;\r
194                 // Make pure static class\r
195                 if (s[2] == 'static') {\r
196                         ns[cn] = p;\r
198                         if (this.onCreate)\r
199                                 this.onCreate(s[2], s[3], ns[cn]);\r
201                         return;\r
202                 }\r
204                 // Create default constructor\r
205                 if (!p[cn]) {\r
206                         p[cn] = function() {};\r
207                         de = 1;\r
208                 }\r
210                 // Add constructor and methods\r
211                 ns[cn] = p[cn];\r
212                 t.extend(ns[cn].prototype, p);\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
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
235                         // Add super methods\r
236                         t.each(sp, function(f, n) {\r
237                                 ns[cn].prototype[n] = sp[n];\r
238                         });\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
255                 // Add static methods\r
256                 t.each(p['static'], function(f, n) {\r
257                         ns[cn][n] = f;\r
258                 });\r
260                 if (this.onCreate)\r
261                         this.onCreate(s[2], s[3], ns[cn].prototype);\r
262         },\r
264         walk : function(o, f, n, s) {\r
265                 s = s || this;\r
267                 if (o) {\r
268                         if (n)\r
269                                 o = o[n];\r
271                         tinymce.each(o, function(o, i) {\r
272                                 if (f.call(s, o, i, n) === false)\r
273                                         return false;\r
275                                 tinymce.walk(o, f, n, s);\r
276                         });\r
277                 }\r
278         },\r
280         createNS : function(n, o) {\r
281                 var i, v;\r
283                 o = o || window;\r
285                 n = n.split('.');\r
286                 for (i=0; i<n.length; i++) {\r
287                         v = n[i];\r
289                         if (!o[v])\r
290                                 o[v] = {};\r
292                         o = o[v];\r
293                 }\r
295                 return o;\r
296         },\r
298         resolve : function(n, o) {\r
299                 var i, l;\r
301                 o = o || window;\r
303                 n = n.split('.');\r
304                 for (i=0, l = n.length; i<l; i++) {\r
305                         o = o[n[i]];\r
307                         if (!o)\r
308                                 break;\r
309                 }\r
311                 return o;\r
312         },\r
314         addUnload : function(f, s) {\r
315                 var t = this, w = window;\r
317                 f = {func : f, scope : s || this};\r
319                 if (!t.unloads) {\r
320                         function unload() {\r
321                                 var li = t.unloads, o, n;\r
323                                 if (li) {\r
324                                         // Call unload handlers\r
325                                         for (n in li) {\r
326                                                 o = li[n];\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
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
339                                         // Destroy references\r
340                                         t.unloads = o = li = w = unload = null;\r
342                                         // Run garbarge collector on IE\r
343                                         if (window.CollectGarbage)\r
344                                                 window.CollectGarbage();\r
345                                 }\r
346                         };\r
348                         function fakeUnload() {\r
349                                 var d = document;\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
357                                                 // Call unload handler\r
358                                                 unload();\r
360                                                 d = null;\r
361                                         };\r
363                                         // Fire unload when the currently loading page is stopped\r
364                                         d.attachEvent('onstop', stop);\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
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
382                         // Setup initial unload handler array\r
383                         t.unloads = [f];\r
384                 } else\r
385                         t.unloads.push(f);\r
387                 return f;\r
388         },\r
390         removeUnload : function(f) {\r
391                 var u = this.unloads, r = null;\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
401                 return r;\r
402         },\r
404         explode : function(s, d) {\r
405                 return s ? tinymce.map(s.split(d || ','), tinymce.trim) : s;\r
406         },\r
408         _addVer : function(u) {\r
409                 var v;\r
411                 if (!this.query)\r
412                         return u;\r
414                 v = (u.indexOf('?') == -1 ? '?' : '&') + this.query;\r
416                 if (u.indexOf('#') == -1)\r
417                         return u + v;\r
419                 return u.replace('#', v + '#');\r
420         }\r
422         };\r
424 // Required for GZip AJAX loading\r
425 window.tinymce = tinymce;\r
427 // Initialize the API\r
428 tinymce._init();\r
430 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */\r
433 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */\r
436 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */\r
438 tinymce.create('tinymce.util.Dispatcher', {\r
439         scope : null,\r
440         listeners : null,\r
442         Dispatcher : function(s) {\r
443                 this.scope = s || this;\r
444                 this.listeners = [];\r
445         },\r
447         add : function(cb, s) {\r
448                 this.listeners.push({cb : cb, scope : s || this.scope});\r
450                 return cb;\r
451         },\r
453         addToTop : function(cb, s) {\r
454                 this.listeners.unshift({cb : cb, scope : s || this.scope});\r
456                 return cb;\r
457         },\r
459         remove : function(cb) {\r
460                 var l = this.listeners, o = null;\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
470                 return o;\r
471         },\r
473         dispatch : function() {\r
474                 var s, a = arguments, i, li = this.listeners, c;\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
482                         if (s === false)\r
483                                 break;\r
484                 }\r
486                 return s;\r
487         }\r
489         });\r
491 /* file:jscripts/tiny_mce/classes/util/URI.js */\r
493 (function() {\r
494         var each = tinymce.each;\r
496         tinymce.create('tinymce.util.URI', {\r
497                 URI : function(u, s) {\r
498                         var t = this, o, a, b;\r
500                         // Default settings\r
501                         s = t.settings = s || {};\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
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
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
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
523                                 // Zope 3 workaround, they use @@something\r
524                                 if (s)\r
525                                         s = s.replace(/\(mce_at\)/g, '@@');\r
527                                 t[v] = s;\r
528                         });\r
530                         if (b = s.base_uri) {\r
531                                 if (!t.protocol)\r
532                                         t.protocol = b.protocol;\r
534                                 if (!t.userInfo)\r
535                                         t.userInfo = b.userInfo;\r
537                                 if (!t.port && t.host == 'mce_host')\r
538                                         t.port = b.port;\r
540                                 if (!t.host || t.host == 'mce_host')\r
541                                         t.host = b.host;\r
543                                 t.source = '';\r
544                         }\r
546                         //t.path = t.path || '/';\r
547                 },\r
549                 setPath : function(p) {\r
550                         var t = this;\r
552                         p = /^(.*?)\/?(\w+)?$/.exec(p);\r
554                         // Update path parts\r
555                         t.path = p[0];\r
556                         t.directory = p[1];\r
557                         t.file = p[2];\r
559                         // Rebuild source\r
560                         t.source = '';\r
561                         t.getURI();\r
562                 },\r
564                 toRelative : function(u) {\r
565                         var t = this, o;\r
567                         u = new tinymce.util.URI(u, {base_uri : t});\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
573                         o = t.toRelPath(t.path, u.path);\r
575                         // Add query\r
576                         if (u.query)\r
577                                 o += '?' + u.query;\r
579                         // Add anchor\r
580                         if (u.anchor)\r
581                                 o += '#' + u.anchor;\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
589                         return u.getURI(this.host == u.host ? nh : 0);\r
590                 },\r
592                 toRelPath : function(base, path) {\r
593                         var items, bp = 0, out = '', i;\r
595                         // Split the paths\r
596                         base = base.substring(0, base.lastIndexOf('/'));\r
597                         base = base.split('/');\r
598                         items = path.split('/');\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
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
618                         if (bp == 1)\r
619                                 return path;\r
621                         for (i = 0; i < base.length - (bp - 1); i++)\r
622                                 out += "../";\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
631                         return out;\r
632                 },\r
634                 toAbsPath : function(base, path) {\r
635                         var i, nb = 0, o = [];\r
637                         // Split paths\r
638                         base = base.split('/');\r
639                         path = path.split('/');\r
641                         // Remove empty chunks\r
642                         each(base, function(k) {\r
643                                 if (k)\r
644                                         o.push(k);\r
645                         });\r
647                         base = o;\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
655                                 // Is parent\r
656                                 if (path[i] == '..') {\r
657                                         nb++;\r
658                                         continue;\r
659                                 }\r
661                                 // Move up\r
662                                 if (nb > 0) {\r
663                                         nb--;\r
664                                         continue;\r
665                                 }\r
667                                 o.push(path[i]);\r
668                         }\r
670                         i = base.length - nb;\r
672                         // If /a/b/c or /\r
673                         if (i <= 0)\r
674                                 return '/' + o.reverse().join('/');\r
676                         return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');\r
677                 },\r
679                 getURI : function(nh) {\r
680                         var s, t = this;\r
682                         // Rebuild source\r
683                         if (!t.source || nh) {\r
684                                 s = '';\r
686                                 if (!nh) {\r
687                                         if (t.protocol)\r
688                                                 s += t.protocol + '://';\r
690                                         if (t.userInfo)\r
691                                                 s += t.userInfo + '@';\r
693                                         if (t.host)\r
694                                                 s += t.host;\r
696                                         if (t.port)\r
697                                                 s += ':' + t.port;\r
698                                 }\r
700                                 if (t.path)\r
701                                         s += t.path;\r
703                                 if (t.query)\r
704                                         s += '?' + t.query;\r
706                                 if (t.anchor)\r
707                                         s += '#' + t.anchor;\r
709                                 t.source = s;\r
710                         }\r
712                         return t.source;\r
713                 }\r
715                 });\r
716 })();\r
718 /* file:jscripts/tiny_mce/classes/util/Cookie.js */\r
720 (function() {\r
721         var each = tinymce.each;\r
723         tinymce.create('static tinymce.util.Cookie', {\r
724                 getHash : function(n) {\r
725                         var v = this.get(n), h;\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
735                         return h;\r
736                 },\r
738                 setHash : function(n, v, e, p, d, s) {\r
739                         var o = '';\r
741                         each(v, function(v, k) {\r
742                                 o += (!o ? '' : '&') + escape(k) + '=' + escape(v);\r
743                         });\r
745                         this.set(n, o, e, p, d, s);\r
746                 },\r
748                 get : function(n) {\r
749                         var c = document.cookie, e, p = n + "=", b;\r
751                         // Strict mode\r
752                         if (!c)\r
753                                 return;\r
755                         b = c.indexOf("; " + p);\r
757                         if (b == -1) {\r
758                                 b = c.indexOf(p);\r
760                                 if (b != 0)\r
761                                         return null;\r
762                         } else\r
763                                 b += 2;\r
765                         e = c.indexOf(";", b);\r
767                         if (e == -1)\r
768                                 e = c.length;\r
770                         return unescape(c.substring(b + p.length, e));\r
771                 },\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
781                 remove : function(n, p) {\r
782                         var d = new Date();\r
784                         d.setTime(d.getTime() - 1000);\r
786                         this.set(n, '', d, p, d);\r
787                 }\r
789                 });\r
790 })();\r
792 /* file:jscripts/tiny_mce/classes/util/JSON.js */\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
798                 if (o == null)\r
799                         return 'null';\r
801                 t = typeof o;\r
803                 if (t == 'string') {\r
804                         v = '\bb\tt\nn\ff\rr\""\'\'\\\\';\r
806                         return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g, function(a, b) {\r
807                                 i = v.indexOf(b);\r
809                                 if (i + 1)\r
810                                         return '\\' + v.charAt(i + 1);\r
812                                 a = b.charCodeAt().toString(16);\r
814                                 return '\\u' + '0000'.substring(a.length) + a;\r
815                         }) + '"';\r
816                 }\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
823                                         return v + ']';\r
824                                 }\r
826                                 v = '{';\r
828                                 for (i in o)\r
829                                         v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';\r
831                                 return v + '}';\r
832                 }\r
834                 return '' + o;\r
835         },\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
845         });\r
847 /* file:jscripts/tiny_mce/classes/util/XHR.js */\r
849 tinymce.create('static tinymce.util.XHR', {\r
850         send : function(o) {\r
851                 var x, t, w = window, c = 0;\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
860                 function get(s) {\r
861                         x = 0;\r
863                         try {\r
864                                 x = new ActiveXObject(s);\r
865                         } catch (ex) {\r
866                         }\r
868                         return x;\r
869                 };\r
871                 x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');\r
873                 if (x) {\r
874                         if (x.overrideMimeType)\r
875                                 x.overrideMimeType(o.content_type);\r
877                         x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);\r
879                         if (o.content_type)\r
880                                 x.setRequestHeader('Content-Type', o.content_type);\r
882                         x.send(o.data);\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
891                                         x = null;\r
892                                 } else\r
893                                         w.setTimeout(ready, 10);\r
894                         };\r
896                         // Syncronous request\r
897                         if (!o.async)\r
898                                 return ready();\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
904                 }\r
905 });\r
907 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */\r
909 (function() {\r
910         var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;\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
919                 send : function(o) {\r
920                         var ecb = o.error, scb = o.success;\r
922                         o = extend(this.settings, o);\r
924                         o.success = function(c, x) {\r
925                                 c = JSON.parse(c);\r
927                                 if (typeof(c) == 'undefined') {\r
928                                         c = {\r
929                                                 error : 'JSON Parse error.'\r
930                                         };\r
931                                 }\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
939                         o.error = function(ty, x) {\r
940                                 ecb.call(o.error_scope || o.scope, ty, x);\r
941                         };\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
949                         // JSON content type for Ruby on rails. Bug: #1883287\r
950                         o.content_type = 'application/json';\r
952                         XHR.send(o);\r
953                 },\r
955                 'static' : {\r
956                         sendRPC : function(o) {\r
957                                 return new tinymce.util.JSONRequest().send(o);\r
958                         }\r
959                 }\r
961                 });\r
962 }());\r
963 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */\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
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                 props : {\r
981                         "for" : "htmlFor",\r
982                         "class" : "className",\r
983                         className : "className",\r
984                         checked : "checked",\r
985                         disabled : "disabled",\r
986                         maxlength : "maxLength",\r
987                         readonly : "readOnly",\r
988                         selected : "selected",\r
989                         value : "value"\r
990                 },\r
992                 DOMUtils : function(d, s) {\r
993                         var t = this;\r
995                         t.doc = d;\r
996                         t.win = window;\r
997                         t.files = {};\r
998                         t.cssFlicker = false;\r
999                         t.counter = 0;\r
1000                         t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; \r
1001                         t.stdMode = d.documentMode === 8;\r
1003                         this.settings = s = tinymce.extend({\r
1004                                 keep_values : false,\r
1005                                 hex_colors : 1,\r
1006                                 process_html : 1\r
1007                         }, s);\r
1009                         // Fix IE6SP2 flicker and check it failed for pre SP2\r
1010                         if (tinymce.isIE6) {\r
1011                                 try {\r
1012                                         d.execCommand('BackgroundImageCache', false, true);\r
1013                                 } catch (e) {\r
1014                                         t.cssFlicker = true;\r
1015                                 }\r
1016                         }\r
1018                         tinymce.addUnload(t.destroy, t);\r
1019                 },\r
1021                 getRoot : function() {\r
1022                         var t = this, s = t.settings;\r
1024                         return (s && t.get(s.root_element)) || t.doc.body;\r
1025                 },\r
1027                 getViewPort : function(w) {\r
1028                         var d, b;\r
1030                         w = !w ? this.win : w;\r
1031                         d = w.document;\r
1032                         b = this.boxModel ? d.documentElement : d.body;\r
1034                         // Returns viewport size excluding scrollbars\r
1035                         return {\r
1036                                 x : w.pageXOffset || b.scrollLeft,\r
1037                                 y : w.pageYOffset || b.scrollTop,\r
1038                                 w : w.innerWidth || b.clientWidth,\r
1039                                 h : w.innerHeight || b.clientHeight\r
1040                         };\r
1041                 },\r
1043                 getRect : function(e) {\r
1044                         var p, t = this, sr;\r
1046                         e = t.get(e);\r
1047                         p = t.getPos(e);\r
1048                         sr = t.getSize(e);\r
1050                         return {\r
1051                                 x : p.x,\r
1052                                 y : p.y,\r
1053                                 w : sr.w,\r
1054                                 h : sr.h\r
1055                         };\r
1056                 },\r
1058                 getSize : function(e) {\r
1059                         var t = this, w, h;\r
1061                         e = t.get(e);\r
1062                         w = t.getStyle(e, 'width');\r
1063                         h = t.getStyle(e, 'height');\r
1065                         // Non pixel value, then force offset/clientWidth\r
1066                         if (w.indexOf('px') === -1)\r
1067                                 w = 0;\r
1069                         // Non pixel value, then force offset/clientWidth\r
1070                         if (h.indexOf('px') === -1)\r
1071                                 h = 0;\r
1073                         return {\r
1074                                 w : parseInt(w) || e.offsetWidth || e.clientWidth,\r
1075                                 h : parseInt(h) || e.offsetHeight || e.clientHeight\r
1076                         };\r
1077                 },\r
1079                 getParent : function(n, f, r) {\r
1080                         var na, se = this.settings;\r
1082                         n = this.get(n);\r
1084                         if (se.strict_root)\r
1085                                 r = r || this.getRoot();\r
1087                         // Wrap node name as func\r
1088                         if (is(f, 'string')) {\r
1089                                 na = f.toUpperCase();\r
1091                                 f = function(n) {\r
1092                                         var s = false;\r
1094                                         // Any element\r
1095                                         if (n.nodeType == 1 && na === '*') {\r
1096                                                 s = true;\r
1097                                                 return false;\r
1098                                         }\r
1100                                         each(na.split(','), function(v) {\r
1101                                                 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName.toUpperCase() == v)) {\r
1102                                                         s = true;\r
1103                                                         return false; // Break loop\r
1104                                                 }\r
1105                                         });\r
1107                                         return s;\r
1108                                 };\r
1109                         }\r
1111                         while (n) {\r
1112                                 if (n == r)\r
1113                                         return null;\r
1115                                 if (f(n))\r
1116                                         return n;\r
1118                                 n = n.parentNode;\r
1119                         }\r
1121                         return null;\r
1122                 },\r
1124                 get : function(e) {\r
1125                         var n;\r
1127                         if (e && this.doc && typeof(e) == 'string') {\r
1128                                 n = e;\r
1129                                 e = this.doc.getElementById(e);\r
1131                                 // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick\r
1132                                 if (e && e.id !== n)\r
1133                                         return this.doc.getElementsByName(n)[1];\r
1134                         }\r
1136                         return e;\r
1137                 },\r
1139                 // #if !jquery\r
1141                 select : function(pa, s) {\r
1142                         var t = this, cs, c, pl, o = [], x, i, l, n;\r
1144                         s = t.get(s) || t.doc;\r
1146                         // Look for native support and use that if it's found\r
1147                         if (s.querySelectorAll) {\r
1148                                 // Element scope then use temp id\r
1149                                 // We need to do this to be compatible with other implementations\r
1150                                 // See bug report: http://bugs.webkit.org/show_bug.cgi?id=17461\r
1151                                 if (s != t.doc) {\r
1152                                         i = s.id;\r
1153                                         s.id = '_mc_tmp';\r
1154                                         pa = '#_mc_tmp ' + pa;\r
1155                                 }\r
1157                                 // Select elements\r
1158                                 l = tinymce.grep(s.querySelectorAll(pa));\r
1160                                 // Restore old id\r
1161                                 s.id = i;\r
1163                                 return l;\r
1164                         }\r
1166                         if (t.settings.strict) {\r
1167                                 function get(s, n) {\r
1168                                         return s.getElementsByTagName(n.toLowerCase());\r
1169                                 };\r
1170                         } else {\r
1171                                 function get(s, n) {\r
1172                                         return s.getElementsByTagName(n);\r
1173                                 };\r
1174                         }\r
1176                         // Simple element pattern. For example: "p" or "*"\r
1177                         if (t.elmPattern.test(pa)) {\r
1178                                 x = get(s, pa);\r
1180                                 for (i = 0, l = x.length; i<l; i++)\r
1181                                         o.push(x[i]);\r
1183                                 return o;\r
1184                         }\r
1186                         // Simple class pattern. For example: "p.class" or ".class"\r
1187                         if (t.elmClassPattern.test(pa)) {\r
1188                                 pl = t.elmClassPattern.exec(pa);\r
1189                                 x = get(s, pl[1] || '*');\r
1190                                 c = ' ' + pl[2] + ' ';\r
1192                                 for (i = 0, l = x.length; i<l; i++) {\r
1193                                         n = x[i];\r
1195                                         if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1)\r
1196                                                 o.push(n);\r
1197                                 }\r
1199                                 return o;\r
1200                         }\r
1202                         function collect(n) {\r
1203                                 if (!n.mce_save) {\r
1204                                         n.mce_save = 1;\r
1205                                         o.push(n);\r
1206                                 }\r
1207                         };\r
1209                         function collectIE(n) {\r
1210                                 if (!n.getAttribute('mce_save')) {\r
1211                                         n.setAttribute('mce_save', '1');\r
1212                                         o.push(n);\r
1213                                 }\r
1214                         };\r
1216                         function find(n, f, r) {\r
1217                                 var i, l, nl = get(r, n);\r
1219                                 for (i = 0, l = nl.length; i < l; i++)\r
1220                                         f(nl[i]);\r
1221                         };\r
1223                         each(pa.split(','), function(v, i) {\r
1224                                 v = tinymce.trim(v);\r
1226                                 // Simple element pattern, most common in TinyMCE\r
1227                                 if (t.elmPattern.test(v)) {\r
1228                                         each(get(s, v), function(n) {\r
1229                                                 collect(n);\r
1230                                         });\r
1232                                         return;\r
1233                                 }\r
1235                                 // Simple element pattern with class, fairly common in TinyMCE\r
1236                                 if (t.elmClassPattern.test(v)) {\r
1237                                         x = t.elmClassPattern.exec(v);\r
1239                                         each(get(s, x[1]), function(n) {\r
1240                                                 if (t.hasClass(n, x[2]))\r
1241                                                         collect(n);\r
1242                                         });\r
1244                                         return;\r
1245                                 }\r
1247                                 if (!(cs = t.cache[pa])) {\r
1248                                         cs = 'x=(function(cf, s) {';\r
1249                                         pl = v.split(' ');\r
1251                                         each(pl, function(v) {\r
1252                                                 var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v);\r
1254                                                 // Find elements\r
1255                                                 p[1] = p[1] || '*';\r
1256                                                 cs += 'find("' + p[1] + '", function(n) {';\r
1258                                                 // Check id\r
1259                                                 if (p[2])\r
1260                                                         cs += 'if (n.id !== "' + p[2] + '") return;';\r
1262                                                 // Check classes\r
1263                                                 if (p[3]) {\r
1264                                                         cs += 'var c = " " + n.className + " ";';\r
1265                                                         cs += 'if (';\r
1266                                                         c = '';\r
1267                                                         each(p[3].split('.'), function(v) {\r
1268                                                                 if (v)\r
1269                                                                         c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1';\r
1270                                                         });\r
1271                                                         cs += c + ') return;';\r
1272                                                 }\r
1273                                         });\r
1275                                         cs += 'cf(n);';\r
1277                                         for (i = pl.length - 1; i >= 0; i--)\r
1278                                                 cs += '}, ' + (i ? 'n' : 's') + ');';\r
1280                                         cs += '})';\r
1282                                         // Compile CSS pattern function\r
1283                                         t.cache[pa] = cs = eval(cs);\r
1284                                 }\r
1286                                 // Run selector function\r
1287                                 cs(isIE ? collectIE : collect, s);\r
1288                         });\r
1290                         // Cleanup\r
1291                         each(o, function(n) {\r
1292                                 if (isIE)\r
1293                                         n.removeAttribute('mce_save');\r
1294                                 else\r
1295                                         delete n.mce_save;\r
1296                         });\r
1298                         return o;\r
1299                 },\r
1301                 // #endif\r
1303                 add : function(p, n, a, h, c) {\r
1304                         var t = this;\r
1306                         return this.run(p, function(p) {\r
1307                                 var e, k;\r
1309                                 e = is(n, 'string') ? t.doc.createElement(n) : n;\r
1311                                 if (a) {\r
1312                                         for (k in a) {\r
1313                                                 if (a.hasOwnProperty(k) && !is(a[k], 'object'))\r
1314                                                         t.setAttrib(e, k, '' + a[k]);\r
1315                                         }\r
1317                                         if (a.style && !is(a.style, 'string')) {\r
1318                                                 each(a.style, function(v, n) {\r
1319                                                         t.setStyle(e, n, v);\r
1320                                                 });\r
1321                                         }\r
1322                                 }\r
1324                                 if (h) {\r
1325                                         if (h.nodeType)\r
1326                                                 e.appendChild(h);\r
1327                                         else\r
1328                                                 t.setHTML(e, h);\r
1329                                 }\r
1331                                 return !c ? p.appendChild(e) : e;\r
1332                         });\r
1333                 },\r
1335                 create : function(n, a, h) {\r
1336                         return this.add(this.doc.createElement(n), n, a, h, 1);\r
1337                 },\r
1339                 createHTML : function(n, a, h) {\r
1340                         var o = '', t = this, k;\r
1342                         o += '<' + n;\r
1344                         for (k in a) {\r
1345                                 if (a.hasOwnProperty(k))\r
1346                                         o += ' ' + k + '="' + t.encode(a[k]) + '"';\r
1347                         }\r
1349                         if (tinymce.is(h))\r
1350                                 return o + '>' + h + '</' + n + '>';\r
1352                         return o + ' />';\r
1353                 },\r
1355                 remove : function(n, k) {\r
1356                         return this.run(n, function(n) {\r
1357                                 var p, g;\r
1359                                 p = n.parentNode;\r
1361                                 if (!p)\r
1362                                         return null;\r
1364                                 if (k) {\r
1365                                         each (n.childNodes, function(c) {\r
1366                                                 p.insertBefore(c.cloneNode(true), n);\r
1367                                         });\r
1368                                 }\r
1370                                 // Fix IE psuedo leak\r
1371                 /*              if (isIE) {\r
1372                                         p = n.cloneNode(true);\r
1373                                         n.outerHTML = '';\r
1375                                         return p;\r
1376                                 }*/\r
1378                                 return p.removeChild(n);\r
1379                         });\r
1380                 },\r
1382                 // #if !jquery\r
1384                 setStyle : function(n, na, v) {\r
1385                         var t = this;\r
1387                         return t.run(n, function(e) {\r
1388                                 var s, i;\r
1390                                 s = e.style;\r
1392                                 // Camelcase it, if needed\r
1393                                 na = na.replace(/-(\D)/g, function(a, b){\r
1394                                         return b.toUpperCase();\r
1395                                 });\r
1397                                 // Default px suffix on these\r
1398                                 if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))\r
1399                                         v += 'px';\r
1401                                 switch (na) {\r
1402                                         case 'opacity':\r
1403                                                 // IE specific opacity\r
1404                                                 if (isIE) {\r
1405                                                         s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";\r
1407                                                         if (!n.currentStyle || !n.currentStyle.hasLayout)\r
1408                                                                 s.display = 'inline-block';\r
1409                                                 }\r
1411                                                 // Fix for older browsers\r
1412                                                 s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || '';\r
1413                                                 break;\r
1415                                         case 'float':\r
1416                                                 isIE ? s.styleFloat = v : s.cssFloat = v;\r
1417                                                 break;\r
1418                                         \r
1419                                         default:\r
1420                                                 s[na] = v || '';\r
1421                                 }\r
1423                                 // Force update of the style data\r
1424                                 if (t.settings.update_styles)\r
1425                                         t.setAttrib(e, 'mce_style');\r
1426                         });\r
1427                 },\r
1429                 getStyle : function(n, na, c) {\r
1430                         n = this.get(n);\r
1432                         if (!n)\r
1433                                 return false;\r
1435                         // Gecko\r
1436                         if (this.doc.defaultView && c) {\r
1437                                 // Remove camelcase\r
1438                                 na = na.replace(/[A-Z]/g, function(a){\r
1439                                         return '-' + a;\r
1440                                 });\r
1442                                 try {\r
1443                                         return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);\r
1444                                 } catch (ex) {\r
1445                                         // Old safari might fail\r
1446                                         return null;\r
1447                                 }\r
1448                         }\r
1450                         // Camelcase it, if needed\r
1451                         na = na.replace(/-(\D)/g, function(a, b){\r
1452                                 return b.toUpperCase();\r
1453                         });\r
1455                         if (na == 'float')\r
1456                                 na = isIE ? 'styleFloat' : 'cssFloat';\r
1458                         // IE & Opera\r
1459                         if (n.currentStyle && c)\r
1460                                 return n.currentStyle[na];\r
1462                         return n.style[na];\r
1463                 },\r
1465                 setStyles : function(e, o) {\r
1466                         var t = this, s = t.settings, ol;\r
1468                         ol = s.update_styles;\r
1469                         s.update_styles = 0;\r
1471                         each(o, function(v, n) {\r
1472                                 t.setStyle(e, n, v);\r
1473                         });\r
1475                         // Update style info\r
1476                         s.update_styles = ol;\r
1477                         if (s.update_styles)\r
1478                                 t.setAttrib(e, s.cssText);\r
1479                 },\r
1481                 setAttrib : function(e, n, v) {\r
1482                         var t = this;\r
1484                         // Whats the point\r
1485                         if (!e || !n)\r
1486                                 return;\r
1488                         // Strict XML mode\r
1489                         if (t.settings.strict)\r
1490                                 n = n.toLowerCase();\r
1492                         return this.run(e, function(e) {\r
1493                                 var s = t.settings;\r
1495                                 switch (n) {\r
1496                                         case "style":\r
1497                                                 // No mce_style for elements with these since they might get resized by the user\r
1498                                                 if (s.keep_values) {\r
1499                                                         if (v && !t._isRes(v))\r
1500                                                                 e.setAttribute('mce_style', v, 2);\r
1501                                                         else\r
1502                                                                 e.removeAttribute('mce_style', 2);\r
1503                                                 }\r
1505                                                 e.style.cssText = v;\r
1506                                                 break;\r
1508                                         case "class":\r
1509                                                 e.className = v || ''; // Fix IE null bug\r
1510                                                 break;\r
1512                                         case "src":\r
1513                                         case "href":\r
1514                                                 if (s.keep_values) {\r
1515                                                         if (s.url_converter)\r
1516                                                                 v = s.url_converter.call(s.url_converter_scope || t, v, n, e);\r
1518                                                         t.setAttrib(e, 'mce_' + n, v, 2);\r
1519                                                 }\r
1521                                                 break;\r
1522                                         \r
1523                                         case "shape":\r
1524                                                 e.setAttribute('mce_style', v);\r
1525                                                 break;\r
1526                                 }\r
1528                                 if (is(v) && v !== null && v.length !== 0)\r
1529                                         e.setAttribute(n, '' + v, 2);\r
1530                                 else\r
1531                                         e.removeAttribute(n, 2);\r
1532                         });\r
1533                 },\r
1535                 setAttribs : function(e, o) {\r
1536                         var t = this;\r
1538                         return this.run(e, function(e) {\r
1539                                 each(o, function(v, n) {\r
1540                                         t.setAttrib(e, n, v);\r
1541                                 });\r
1542                         });\r
1543                 },\r
1545                 // #endif\r
1547                 getAttrib : function(e, n, dv) {\r
1548                         var v, t = this;\r
1550                         e = t.get(e);\r
1552                         if (!e || e.nodeType !== 1)\r
1553                                 return false;\r
1555                         if (!is(dv))\r
1556                                 dv = '';\r
1558                         // Try the mce variant for these\r
1559                         if (/^(src|href|style|coords|shape)$/.test(n)) {\r
1560                                 v = e.getAttribute("mce_" + n);\r
1562                                 if (v)\r
1563                                         return v;\r
1564                         }\r
1566                         if (isIE && t.props[n]) {\r
1567                                 v = e[t.props[n]];\r
1568                                 v = v && v.nodeValue ? v.nodeValue : v;\r
1569                         }\r
1571                         if (!v)\r
1572                                 v = e.getAttribute(n, 2);\r
1574                         if (n === 'style') {\r
1575                                 v = v || e.style.cssText;\r
1577                                 if (v) {\r
1578                                         v = t.serializeStyle(t.parseStyle(v));\r
1580                                         if (t.settings.keep_values && !t._isRes(v))\r
1581                                                 e.setAttribute('mce_style', v);\r
1582                                 }\r
1583                         }\r
1585                         // Remove Apple and WebKit stuff\r
1586                         if (isWebKit && n === "class" && v)\r
1587                                 v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');\r
1589                         // Handle IE issues\r
1590                         if (isIE) {\r
1591                                 switch (n) {\r
1592                                         case 'rowspan':\r
1593                                         case 'colspan':\r
1594                                                 // IE returns 1 as default value\r
1595                                                 if (v === 1)\r
1596                                                         v = '';\r
1598                                                 break;\r
1600                                         case 'size':\r
1601                                                 // IE returns +0 as default value for size\r
1602                                                 if (v === '+0' || v === 20)\r
1603                                                         v = '';\r
1605                                                 break;\r
1607                                         case 'width':\r
1608                                         case 'height':\r
1609                                         case 'vspace':\r
1610                                                 if (v === 0)\r
1611                                                         v = '';\r
1613                                                 break;\r
1615                                         case 'hspace':\r
1616                                                 // IE returns -1 as default value\r
1617                                                 if (v === -1)\r
1618                                                         v = '';\r
1620                                                 break;\r
1622                                         case 'maxlength':\r
1623                                         case 'tabindex':\r
1624                                                 // IE returns default value\r
1625                                                 if (v === 32768 || v === 2147483647)\r
1626                                                         v = '';\r
1628                                                 break;\r
1630                                         case 'compact':\r
1631                                         case 'noshade':\r
1632                                                 if (v === 65535)\r
1633                                                         return n;\r
1635                                                 return dv;\r
1637                                         case 'shape':\r
1638                                                 v = v.toLowerCase();\r
1639                                                 break;\r
1641                                         default:\r
1642                                                 // IE has odd anonymous function for event attributes\r
1643                                                 if (n.indexOf('on') === 0 && v)\r
1644                                                         v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');\r
1645                                 }\r
1646                         }\r
1648                         return (v !== undefined && v !== null && v !== '') ? '' + v : dv;\r
1649                 },\r
1651                 getPos : function(n) {\r
1652                         var t = this, x = 0, y = 0, e, d = t.doc, r;\r
1654                         n = t.get(n);\r
1656                         // Use getBoundingClientRect on IE, Opera has it but it's not perfect\r
1657                         if (n && isIE) {\r
1658                                 n = n.getBoundingClientRect();\r
1659                                 e = t.boxModel ? d.documentElement : d.body;\r
1660                                 x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border\r
1661                                 x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;\r
1662                                 n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset\r
1664                                 return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
1665                         }\r
1667                         r = n;\r
1668                         while (r) {\r
1669                                 x += r.offsetLeft || 0;\r
1670                                 y += r.offsetTop || 0;\r
1671                                 r = r.offsetParent;\r
1672                         }\r
1674                         r = n;\r
1675                         while (r) {\r
1676                                 // Opera 9.25 bug fix, fixed in 9.50\r
1677                                 if (!/^table-row|inline.*/i.test(t.getStyle(r, "display", 1))) {\r
1678                                         x -= r.scrollLeft || 0;\r
1679                                         y -= r.scrollTop || 0;\r
1680                                 }\r
1682                                 r = r.parentNode;\r
1684                                 if (r == d.body)\r
1685                                         break;\r
1686                         }\r
1688                         return {x : x, y : y};\r
1689                 },\r
1691                 parseStyle : function(st) {\r
1692                         var t = this, s = t.settings, o = {};\r
1694                         if (!st)\r
1695                                 return o;\r
1697                         function compress(p, s, ot) {\r
1698                                 var t, r, b, l;\r
1700                                 // Get values and check it it needs compressing\r
1701                                 t = o[p + '-top' + s];\r
1702                                 if (!t)\r
1703                                         return;\r
1705                                 r = o[p + '-right' + s];\r
1706                                 if (t != r)\r
1707                                         return;\r
1709                                 b = o[p + '-bottom' + s];\r
1710                                 if (r != b)\r
1711                                         return;\r
1713                                 l = o[p + '-left' + s];\r
1714                                 if (b != l)\r
1715                                         return;\r
1717                                 // Compress\r
1718                                 o[ot] = l;\r
1719                                 delete o[p + '-top' + s];\r
1720                                 delete o[p + '-right' + s];\r
1721                                 delete o[p + '-bottom' + s];\r
1722                                 delete o[p + '-left' + s];\r
1723                         };\r
1725                         function compress2(ta, a, b, c) {\r
1726                                 var t;\r
1728                                 t = o[a];\r
1729                                 if (!t)\r
1730                                         return;\r
1732                                 t = o[b];\r
1733                                 if (!t)\r
1734                                         return;\r
1736                                 t = o[c];\r
1737                                 if (!t)\r
1738                                         return;\r
1740                                 // Compress\r
1741                                 o[ta] = o[a] + ' ' + o[b] + ' ' + o[c];\r
1742                                 delete o[a];\r
1743                                 delete o[b];\r
1744                                 delete o[c];\r
1745                         };\r
1747                         st = st.replace(/&(#?[a-z0-9]+);/g, '&$1_MCE_SEMI_'); // Protect entities\r
1749                         each(st.split(';'), function(v) {\r
1750                                 var sv, ur = [];\r
1752                                 if (v) {\r
1753                                         v = v.replace(/_MCE_SEMI_/g, ';'); // Restore entities\r
1754                                         v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';});\r
1755                                         v = v.split(':');\r
1756                                         sv = tinymce.trim(v[1]);\r
1757                                         sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];});\r
1759                                         sv = sv.replace(/rgb\([^\)]+\)/g, function(v) {\r
1760                                                 return t.toHex(v);\r
1761                                         });\r
1763                                         if (s.url_converter) {\r
1764                                                 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) {\r
1765                                                         return 'url(' + s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null) + ')';\r
1766                                                 });\r
1767                                         }\r
1769                                         o[tinymce.trim(v[0]).toLowerCase()] = sv;\r
1770                                 }\r
1771                         });\r
1773                         compress("border", "", "border");\r
1774                         compress("border", "-width", "border-width");\r
1775                         compress("border", "-color", "border-color");\r
1776                         compress("border", "-style", "border-style");\r
1777                         compress("padding", "", "padding");\r
1778                         compress("margin", "", "margin");\r
1779                         compress2('border', 'border-width', 'border-style', 'border-color');\r
1781                         if (isIE) {\r
1782                                 // Remove pointless border\r
1783                                 if (o.border == 'medium none')\r
1784                                         o.border = '';\r
1785                         }\r
1787                         return o;\r
1788                 },\r
1790                 serializeStyle : function(o) {\r
1791                         var s = '';\r
1793                         each(o, function(v, k) {\r
1794                                 if (k && v) {\r
1795                                         if (tinymce.isGecko && k.indexOf('-moz-') === 0)\r
1796                                                 return;\r
1798                                         switch (k) {\r
1799                                                 case 'color':\r
1800                                                 case 'background-color':\r
1801                                                         v = v.toLowerCase();\r
1802                                                         break;\r
1803                                         }\r
1805                                         s += (s ? ' ' : '') + k + ': ' + v + ';';\r
1806                                 }\r
1807                         });\r
1809                         return s;\r
1810                 },\r
1812                 loadCSS : function(u) {\r
1813                         var t = this, d = t.doc;\r
1815                         if (!u)\r
1816                                 u = '';\r
1818                         each(u.split(','), function(u) {\r
1819                                 if (t.files[u])\r
1820                                         return;\r
1822                                 t.files[u] = true;\r
1823                                 t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : tinymce._addVer(u)});\r
1824                         });\r
1825                 },\r
1827                 // #if !jquery\r
1829                 addClass : function(e, c) {\r
1830                         return this.run(e, function(e) {\r
1831                                 var o;\r
1833                                 if (!c)\r
1834                                         return 0;\r
1836                                 if (this.hasClass(e, c))\r
1837                                         return e.className;\r
1839                                 o = this.removeClass(e, c);\r
1841                                 return e.className = (o != '' ? (o + ' ') : '') + c;\r
1842                         });\r
1843                 },\r
1845                 removeClass : function(e, c) {\r
1846                         var t = this, re;\r
1848                         return t.run(e, function(e) {\r
1849                                 var v;\r
1851                                 if (t.hasClass(e, c)) {\r
1852                                         if (!re)\r
1853                                                 re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");\r
1855                                         v = e.className.replace(re, ' ');\r
1857                                         return e.className = tinymce.trim(v != ' ' ? v : '');\r
1858                                 }\r
1860                                 return e.className;\r
1861                         });\r
1862                 },\r
1864                 hasClass : function(n, c) {\r
1865                         n = this.get(n);\r
1867                         if (!n || !c)\r
1868                                 return false;\r
1870                         return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;\r
1871                 },\r
1873                 show : function(e) {\r
1874                         return this.setStyle(e, 'display', 'block');\r
1875                 },\r
1877                 hide : function(e) {\r
1878                         return this.setStyle(e, 'display', 'none');\r
1879                 },\r
1881                 isHidden : function(e) {\r
1882                         e = this.get(e);\r
1884                         return e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
1885                 },\r
1887                 // #endif\r
1889                 uniqueId : function(p) {\r
1890                         return (!p ? 'mce_' : p) + (this.counter++);\r
1891                 },\r
1893                 setHTML : function(e, h) {\r
1894                         var t = this;\r
1896                         return this.run(e, function(e) {\r
1897                                 var x, i, nl, n, p, x;\r
1899                                 h = t.processHTML(h);\r
1901                                 if (isIE) {\r
1902                                         function set() {\r
1903                                                 try {\r
1904                                                         // IE will remove comments from the beginning\r
1905                                                         // unless you padd the contents with something\r
1906                                                         e.innerHTML = '<br />' + h;\r
1907                                                         e.removeChild(e.firstChild);\r
1908                                                 } catch (ex) {\r
1909                                                         // 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
1910                                                         // This seems to fix this problem\r
1912                                                         // Remove all child nodes\r
1913                                                         while (e.firstChild)\r
1914                                                                 e.firstChild.removeNode();\r
1916                                                         // Create new div with HTML contents and a BR infront to keep comments\r
1917                                                         x = t.create('div');\r
1918                                                         x.innerHTML = '<br />' + h;\r
1920                                                         // Add all children from div to target\r
1921                                                         each (x.childNodes, function(n, i) {\r
1922                                                                 // Skip br element\r
1923                                                                 if (i)\r
1924                                                                         e.appendChild(n);\r
1925                                                         });\r
1926                                                 }\r
1927                                         };\r
1929                                         // IE has a serious bug when it comes to paragraphs it can produce an invalid\r
1930                                         // DOM tree if contents like this <p><ul><li>Item 1</li></ul></p> is inserted\r
1931                                         // It seems to be that IE doesn't like a root block element placed inside another root block element\r
1932                                         if (t.settings.fix_ie_paragraphs)\r
1933                                                 h = h.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi, '<p$1 mce_keep="true">&nbsp;</p>');\r
1935                                         set();\r
1937                                         if (t.settings.fix_ie_paragraphs) {\r
1938                                                 // Check for odd paragraphs this is a sign of a broken DOM\r
1939                                                 nl = e.getElementsByTagName("p");\r
1940                                                 for (i = nl.length - 1, x = 0; i >= 0; i--) {\r
1941                                                         n = nl[i];\r
1943                                                         if (!n.hasChildNodes()) {\r
1944                                                                 if (!n.mce_keep) {\r
1945                                                                         x = 1; // Is broken\r
1946                                                                         break;\r
1947                                                                 }\r
1949                                                                 n.removeAttribute('mce_keep');\r
1950                                                         }\r
1951                                                 }\r
1952                                         }\r
1954                                         // Time to fix the madness IE left us\r
1955                                         if (x) {\r
1956                                                 // So if we replace the p elements with divs and mark them and then replace them back to paragraphs\r
1957                                                 // after we use innerHTML we can fix the DOM tree\r
1958                                                 h = h.replace(/<p([^>]+)>|<p>/g, '<div$1 mce_tmp="1">');\r
1959                                                 h = h.replace(/<\/p>/g, '</div>');\r
1961                                                 // Set the new HTML with DIVs\r
1962                                                 set();\r
1964                                                 // Replace all DIV elements with he mce_tmp attibute back to paragraphs\r
1965                                                 // This is needed since IE has a annoying bug see above for details\r
1966                                                 // This is a slow process but it has to be done. :(\r
1967                                                 if (t.settings.fix_ie_paragraphs) {\r
1968                                                         nl = e.getElementsByTagName("DIV");\r
1969                                                         for (i = nl.length - 1; i >= 0; i--) {\r
1970                                                                 n = nl[i];\r
1972                                                                 // Is it a temp div\r
1973                                                                 if (n.mce_tmp) {\r
1974                                                                         // Create new paragraph\r
1975                                                                         p = t.doc.createElement('p');\r
1977                                                                         // Copy all attributes\r
1978                                                                         n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) {\r
1979                                                                                 var v;\r
1981                                                                                 if (b !== 'mce_tmp') {\r
1982                                                                                         v = n.getAttribute(b);\r
1984                                                                                         if (!v && b === 'class')\r
1985                                                                                                 v = n.className;\r
1987                                                                                         p.setAttribute(b, v);\r
1988                                                                                 }\r
1989                                                                         });\r
1991                                                                         // Append all children to new paragraph\r
1992                                                                         for (x = 0; x<n.childNodes.length; x++)\r
1993                                                                                 p.appendChild(n.childNodes[x].cloneNode(true));\r
1995                                                                         // Replace div with new paragraph\r
1996                                                                         n.swapNode(p);\r
1997                                                                 }\r
1998                                                         }\r
1999                                                 }\r
2000                                         }\r
2001                                 } else\r
2002                                         e.innerHTML = h;\r
2004                                 return h;\r
2005                         });\r
2006                 },\r
2008                 processHTML : function(h) {\r
2009                         var t = this, s = t.settings;\r
2011                         if (!s.process_html)\r
2012                                 return h;\r
2014                         // Convert strong and em to b and i in FF since it can't handle them\r
2015                         if (tinymce.isGecko) {\r
2016                                 h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');\r
2017                                 h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');\r
2018                         } else if (isIE)\r
2019                                 h = h.replace(/&apos;/g, '&#39;'); // IE can't handle apos\r
2021                         // Fix some issues\r
2022                         h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open\r
2024                         // Store away src and href in mce_src and mce_href since browsers mess them up\r
2025                         if (s.keep_values) {\r
2026                                 h = h.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g, '<!--[CDATA[$1]]-->');\r
2028                                 // Wrap scripts and styles in comments for serialization purposes\r
2029                                 if (/<script|style/.test(h)) {\r
2030                                         function trim(s) {\r
2031                                                 // Remove prefix and suffix code for element\r
2032                                                 s = s.replace(/^[\r\n]*|[\r\n]*$/g, '');\r
2033                                                 s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<\[CDATA\[|<!--|<\[CDATA\[)[\r\n]*/g, '');\r
2034                                                 s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->)\s*$/g, '');\r
2036                                                 return s;\r
2037                                         };\r
2039                                         // Preserve script elements\r
2040                                         h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g, function(v, a, b) {\r
2041                                                 // Remove prefix and suffix code for script element\r
2042                                                 b = trim(b);\r
2044                                                 // Force type attribute\r
2045                                                 if (!a)\r
2046                                                         a = ' type="text/javascript"';\r
2048                                                 // Wrap contents in a comment\r
2049                                                 if (b)\r
2050                                                         b = '<!--\n' + b + '\n// -->';\r
2052                                                 // Output fake element\r
2053                                                 return '<mce:script' + a + '>' + b + '</mce:script>';\r
2054                                         });\r
2056                                         // Preserve style elements\r
2057                                         h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g, function(v, a, b) {\r
2058                                                 b = trim(b);\r
2059                                                 return '<mce:style' + a + '><!--\n' + b + '\n--></mce:style><style' + a + ' mce_bogus="1">' + b + '</style>';\r
2060                                         });\r
2061                                 }\r
2063                                 // Process all tags with src, href or style\r
2064                                 h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) {\r
2065                                         function handle(m, b, c) {\r
2066                                                 var u = c;\r
2068                                                 // Tag already got a mce_ version\r
2069                                                 if (a.indexOf('mce_' + b) != -1)\r
2070                                                         return m;\r
2072                                                 if (b == 'style') {\r
2073                                                         // Why did I need this one?\r
2074                                                         //if (isIE)\r
2075                                                         //      u = t.serializeStyle(t.parseStyle(u));\r
2077                                                         // No mce_style for elements with these since they might get resized by the user\r
2078                                                         if (t._isRes(c))\r
2079                                                                 return m;\r
2081                                                         if (s.hex_colors) {\r
2082                                                                 u = u.replace(/rgb\([^\)]+\)/g, function(v) {\r
2083                                                                         return t.toHex(v);\r
2084                                                                 });\r
2085                                                         }\r
2087                                                         if (s.url_converter) {\r
2088                                                                 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {\r
2089                                                                         return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';\r
2090                                                                 });\r
2091                                                         }\r
2092                                                 } else if (b != 'coords' && b != 'shape') {\r
2093                                                         if (s.url_converter)\r
2094                                                                 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));\r
2095                                                 }\r
2097                                                 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"';\r
2098                                         };\r
2100                                         a = a.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi, handle); // W3C\r
2101                                         a = a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi, handle); // W3C\r
2103                                         return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi, handle); // IE\r
2104                                 });\r
2105                         }\r
2107                         return h;\r
2108                 },\r
2110                 getOuterHTML : function(e) {\r
2111                         var d;\r
2113                         e = this.get(e);\r
2115                         if (!e)\r
2116                                 return null;\r
2118                         if (isIE)\r
2119                                 return e.outerHTML;\r
2121                         d = (e.ownerDocument || this.doc).createElement("body");\r
2122                         d.appendChild(e.cloneNode(true));\r
2124                         return d.innerHTML;\r
2125                 },\r
2127                 setOuterHTML : function(e, h, d) {\r
2128                         var t = this;\r
2130                         return this.run(e, function(e) {\r
2131                                 var n, tp;\r
2133                                 e = t.get(e);\r
2134                                 d = d || e.ownerDocument || t.doc;\r
2136                                 if (isIE && e.nodeType == 1)\r
2137                                         e.outerHTML = h;\r
2138                                 else {\r
2139                                         tp = d.createElement("body");\r
2140                                         tp.innerHTML = h;\r
2142                                         n = tp.lastChild;\r
2143                                         while (n) {\r
2144                                                 t.insertAfter(n.cloneNode(true), e);\r
2145                                                 n = n.previousSibling;\r
2146                                         }\r
2148                                         t.remove(e);\r
2149                                 }\r
2150                         });\r
2151                 },\r
2153                 decode : function(s) {\r
2154                         var e;\r
2156                         // Look for entities to decode\r
2157                         if (/&[^;]+;/.test(s)) {\r
2158                                 // Decode the entities using a div element not super efficient but less code\r
2159                                 e = this.doc.createElement("div");\r
2160                                 e.innerHTML = s;\r
2162                                 return !e.firstChild ? s : e.firstChild.nodeValue;\r
2163                         }\r
2165                         return s;\r
2166                 },\r
2168                 encode : function(s) {\r
2169                         return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) {\r
2170                                 switch (c) {\r
2171                                         case '&':\r
2172                                                 return '&amp;';\r
2174                                         case '"':\r
2175                                                 return '&quot;';\r
2177                                         case '<':\r
2178                                                 return '&lt;';\r
2180                                         case '>':\r
2181                                                 return '&gt;';\r
2182                                 }\r
2184                                 return c;\r
2185                         }) : s;\r
2186                 },\r
2188                 // #if !jquery\r
2190                 insertAfter : function(n, r) {\r
2191                         var t = this;\r
2193                         r = t.get(r);\r
2195                         return this.run(n, function(n) {\r
2196                                 var p, ns;\r
2198                                 p = r.parentNode;\r
2199                                 ns = r.nextSibling;\r
2201                                 if (ns)\r
2202                                         p.insertBefore(n, ns);\r
2203                                 else\r
2204                                         p.appendChild(n);\r
2206                                 return n;\r
2207                         });\r
2208                 },\r
2210                 // #endif\r
2212                 isBlock : function(n) {\r
2213                         if (n.nodeType && n.nodeType !== 1)\r
2214                                 return false;\r
2216                         n = n.nodeName || n;\r
2218                         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
2219                 },\r
2221                 // #if !jquery\r
2223                 replace : function(n, o, k) {\r
2224                         if (is(o, 'array'))\r
2225                                 n = n.cloneNode(true);\r
2227                         return this.run(o, function(o) {\r
2228                                 if (k) {\r
2229                                         each(o.childNodes, function(c) {\r
2230                                                 n.appendChild(c.cloneNode(true));\r
2231                                         });\r
2232                                 }\r
2234                                 // Fix IE psuedo leak for elements since replacing elements if fairly common\r
2235                                 // Will break parentNode for some unknown reason\r
2236         /*                      if (isIE && o.nodeType === 1) {\r
2237                                         o.parentNode.insertBefore(n, o);\r
2238                                         o.outerHTML = '';\r
2239                                         return n;\r
2240                                 }*/\r
2242                                 return o.parentNode.replaceChild(n, o);\r
2243                         });\r
2244                 },\r
2246                 // #endif\r
2248                 toHex : function(s) {\r
2249                         var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);\r
2251                         function hex(s) {\r
2252                                 s = parseInt(s).toString(16);\r
2254                                 return s.length > 1 ? s : '0' + s; // 0 -> 00\r
2255                         };\r
2257                         if (c) {\r
2258                                 s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]);\r
2260                                 return s;\r
2261                         }\r
2263                         return s;\r
2264                 },\r
2266                 getClasses : function() {\r
2267                         var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov;\r
2269                         if (t.classes)\r
2270                                 return t.classes;\r
2272                         function addClasses(s) {\r
2273                                 // IE style imports\r
2274                                 each(s.imports, function(r) {\r
2275                                         addClasses(r);\r
2276                                 });\r
2278                                 each(s.cssRules || s.rules, function(r) {\r
2279                                         // Real type or fake it on IE\r
2280                                         switch (r.type || 1) {\r
2281                                                 // Rule\r
2282                                                 case 1:\r
2283                                                         if (r.selectorText) {\r
2284                                                                 each(r.selectorText.split(','), function(v) {\r
2285                                                                         v = v.replace(/^\s*|\s*$|^\s\./g, "");\r
2287                                                                         // Is internal or it doesn't contain a class\r
2288                                                                         if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v))\r
2289                                                                                 return;\r
2291                                                                         // Remove everything but class name\r
2292                                                                         ov = v;\r
2293                                                                         v = v.replace(/.*\.([a-z0-9_\-]+).*/i, '$1');\r
2295                                                                         // Filter classes\r
2296                                                                         if (f && !(v = f(v, ov)))\r
2297                                                                                 return;\r
2299                                                                         if (!lo[v]) {\r
2300                                                                                 cl.push({'class' : v});\r
2301                                                                                 lo[v] = 1;\r
2302                                                                         }\r
2303                                                                 });\r
2304                                                         }\r
2305                                                         break;\r
2307                                                 // Import\r
2308                                                 case 3:\r
2309                                                         addClasses(r.styleSheet);\r
2310                                                         break;\r
2311                                         }\r
2312                                 });\r
2313                         };\r
2315                         try {\r
2316                                 each(t.doc.styleSheets, addClasses);\r
2317                         } catch (ex) {\r
2318                                 // Ignore\r
2319                         }\r
2321                         if (cl.length > 0)\r
2322                                 t.classes = cl;\r
2324                         return cl;\r
2325                 },\r
2327                 run : function(e, f, s) {\r
2328                         var t = this, o;\r
2330                         if (t.doc && typeof(e) === 'string')\r
2331                                 e = t.doc.getElementById(e);\r
2333                         if (!e)\r
2334                                 return false;\r
2336                         s = s || this;\r
2337                         if (!e.nodeType && (e.length || e.length === 0)) {\r
2338                                 o = [];\r
2340                                 each(e, function(e, i) {\r
2341                                         if (e) {\r
2342                                                 if (typeof(e) == 'string')\r
2343                                                         e = t.doc.getElementById(e);\r
2345                                                 o.push(f.call(s, e, i));\r
2346                                         }\r
2347                                 });\r
2349                                 return o;\r
2350                         }\r
2352                         return f.call(s, e);\r
2353                 },\r
2355                 getAttribs : function(n) {\r
2356                         var o;\r
2358                         n = this.get(n);\r
2360                         if (!n)\r
2361                                 return [];\r
2363                         if (isIE) {\r
2364                                 o = [];\r
2366                                 // Object will throw exception in IE\r
2367                                 if (n.nodeName == 'OBJECT')\r
2368                                         return n.attributes;\r
2370                                 // It's crazy that this is faster in IE but it's because it returns all attributes all the time\r
2371                                 n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
2372                                         o.push({specified : 1, nodeName : b});\r
2373                                 });\r
2375                                 return o;\r
2376                         }\r
2378                         return n.attributes;\r
2379                 },\r
2381                 destroy : function(s) {\r
2382                         var t = this;\r
2384                         t.win = t.doc = t.root = null;\r
2386                         // Manual destroy then remove unload handler\r
2387                         if (!s)\r
2388                                 tinymce.removeUnload(t.destroy);\r
2389                 },\r
2391                 _isRes : function(c) {\r
2392                         // Is live resizble element\r
2393                         return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c);\r
2394                 }\r
2396                 /*\r
2397                 walk : function(n, f, s) {\r
2398                         var d = this.doc, w;\r
2400                         if (d.createTreeWalker) {\r
2401                                 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
2403                                 while ((n = w.nextNode()) != null)\r
2404                                         f.call(s || this, n);\r
2405                         } else\r
2406                                 tinymce.walk(n, f, 'childNodes', s);\r
2407                 }\r
2408                 */\r
2410                 /*\r
2411                 toRGB : function(s) {\r
2412                         var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s);\r
2414                         if (c) {\r
2415                                 // #FFF -> #FFFFFF\r
2416                                 if (!is(c[3]))\r
2417                                         c[3] = c[2] = c[1];\r
2419                                 return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")";\r
2420                         }\r
2422                         return s;\r
2423                 }\r
2424                 */\r
2426                 });\r
2428         // Setup page DOM\r
2429         tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});\r
2430 })();\r
2432 /* file:jscripts/tiny_mce/classes/dom/Event.js */\r
2434 (function() {\r
2435         // Shorten names\r
2436         var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
2438         tinymce.create('static tinymce.dom.Event', {\r
2439                 inits : [],\r
2440                 events : [],\r
2442                 // #if !jquery\r
2444                 add : function(o, n, f, s) {\r
2445                         var cb, t = this, el = t.events, r;\r
2447                         // Handle array\r
2448                         if (o && o instanceof Array) {\r
2449                                 r = [];\r
2451                                 each(o, function(o) {\r
2452                                         o = DOM.get(o);\r
2453                                         r.push(t.add(o, n, f, s));\r
2454                                 });\r
2456                                 return r;\r
2457                         }\r
2459                         o = DOM.get(o);\r
2461                         if (!o)\r
2462                                 return;\r
2464                         // Setup event callback\r
2465                         cb = function(e) {\r
2466                                 e = e || window.event;\r
2468                                 // Patch in target in IE it's W3C valid\r
2469                                 if (e && !e.target && isIE)\r
2470                                         e.target = e.srcElement;\r
2472                                 if (!s)\r
2473                                         return f(e);\r
2475                                 return f.call(s, e);\r
2476                         };\r
2478                         if (n == 'unload') {\r
2479                                 tinymce.unloads.unshift({func : cb});\r
2480                                 return cb;\r
2481                         }\r
2483                         if (n == 'init') {\r
2484                                 if (t.domLoaded)\r
2485                                         cb();\r
2486                                 else\r
2487                                         t.inits.push(cb);\r
2489                                 return cb;\r
2490                         }\r
2492                         // Store away listener reference\r
2493                         el.push({\r
2494                                 obj : o,\r
2495                                 name : n,\r
2496                                 func : f,\r
2497                                 cfunc : cb,\r
2498                                 scope : s\r
2499                         });\r
2501                         t._add(o, n, cb);\r
2503                         return f;\r
2504                 },\r
2506                 remove : function(o, n, f) {\r
2507                         var t = this, a = t.events, s = false, r;\r
2509                         // Handle array\r
2510                         if (o && o instanceof Array) {\r
2511                                 r = [];\r
2513                                 each(o, function(o) {\r
2514                                         o = DOM.get(o);\r
2515                                         r.push(t.remove(o, n, f));\r
2516                                 });\r
2518                                 return r;\r
2519                         }\r
2521                         o = DOM.get(o);\r
2523                         each(a, function(e, i) {\r
2524                                 if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {\r
2525                                         a.splice(i, 1);\r
2526                                         t._remove(o, n, e.cfunc);\r
2527                                         s = true;\r
2528                                         return false;\r
2529                                 }\r
2530                         });\r
2532                         return s;\r
2533                 },\r
2535                 clear : function(o) {\r
2536                         var t = this, a = t.events, i, e;\r
2538                         if (o) {\r
2539                                 o = DOM.get(o);\r
2541                                 for (i = a.length - 1; i >= 0; i--) {\r
2542                                         e = a[i];\r
2544                                         if (e.obj === o) {\r
2545                                                 t._remove(e.obj, e.name, e.cfunc);\r
2546                                                 e.obj = e.cfunc = null;\r
2547                                                 a.splice(i, 1);\r
2548                                         }\r
2549                                 }\r
2550                         }\r
2551                 },\r
2553                 // #endif\r
2555                 cancel : function(e) {\r
2556                         if (!e)\r
2557                                 return false;\r
2559                         this.stop(e);\r
2560                         return this.prevent(e);\r
2561                 },\r
2563                 stop : function(e) {\r
2564                         if (e.stopPropagation)\r
2565                                 e.stopPropagation();\r
2566                         else\r
2567                                 e.cancelBubble = true;\r
2569                         return false;\r
2570                 },\r
2572                 prevent : function(e) {\r
2573                         if (e.preventDefault)\r
2574                                 e.preventDefault();\r
2575                         else\r
2576                                 e.returnValue = false;\r
2578                         return false;\r
2579                 },\r
2581                 _unload : function() {\r
2582                         var t = Event;\r
2584                         each(t.events, function(e, i) {\r
2585                                 t._remove(e.obj, e.name, e.cfunc);\r
2586                                 e.obj = e.cfunc = null;\r
2587                         });\r
2589                         t.events = [];\r
2590                         t = null;\r
2591                 },\r
2593                 _add : function(o, n, f) {\r
2594                         if (o.attachEvent)\r
2595                                 o.attachEvent('on' + n, f);\r
2596                         else if (o.addEventListener)\r
2597                                 o.addEventListener(n, f, false);\r
2598                         else\r
2599                                 o['on' + n] = f;\r
2600                 },\r
2602                 _remove : function(o, n, f) {\r
2603                         if (o) {\r
2604                                 try {\r
2605                                         if (o.detachEvent)\r
2606                                                 o.detachEvent('on' + n, f);\r
2607                                         else if (o.removeEventListener)\r
2608                                                 o.removeEventListener(n, f, false);\r
2609                                         else\r
2610                                                 o['on' + n] = null;\r
2611                                 } catch (ex) {\r
2612                                         // Might fail with permission denined on IE so we just ignore that\r
2613                                 }\r
2614                         }\r
2615                 },\r
2617                 _pageInit : function() {\r
2618                         var e = Event;\r
2620                         e._remove(window, 'DOMContentLoaded', e._pageInit);\r
2621                         e.domLoaded = true;\r
2623                         each(e.inits, function(c) {\r
2624                                 c();\r
2625                         });\r
2627                         e.inits = [];\r
2628                 },\r
2630                 _wait : function() {\r
2631                         var t;\r
2633                         // No need since the document is already loaded\r
2634                         if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) {\r
2635                                 Event.domLoaded = 1;\r
2636                                 return;\r
2637                         }\r
2639                         if (isIE && document.location.protocol != 'https:') {\r
2640                                 // Fake DOMContentLoaded on IE\r
2641                                 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');\r
2642                                 DOM.get("__ie_onload").onreadystatechange = function() {\r
2643                                         if (this.readyState == "complete") {\r
2644                                                 Event._pageInit();\r
2645                                                 DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak\r
2646                                         }\r
2647                                 };\r
2648                         } else {\r
2649                                 Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);\r
2651                                 if (isIE || isWebKit) {\r
2652                                         t = setInterval(function() {\r
2653                                                 if (/loaded|complete/.test(document.readyState)) {\r
2654                                                         clearInterval(t);\r
2655                                                         Event._pageInit();\r
2656                                                 }\r
2657                                         }, 10);\r
2658                                 }\r
2659                         }\r
2660                 }\r
2662                 });\r
2664         // Shorten name\r
2665         Event = tinymce.dom.Event;\r
2667         // Dispatch DOM content loaded event for IE and Safari\r
2668         Event._wait();\r
2669         tinymce.addUnload(Event._unload);\r
2670 })();\r
2672 /* file:jscripts/tiny_mce/classes/dom/Element.js */\r
2674 (function() {\r
2675         var each = tinymce.each;\r
2677         tinymce.create('tinymce.dom.Element', {\r
2678                 Element : function(id, s) {\r
2679                         var t = this, dom, el;\r
2681                         s = s || {};\r
2682                         t.id = id;\r
2683                         t.dom = dom = s.dom || tinymce.DOM;\r
2684                         t.settings = s;\r
2686                         // Only IE leaks DOM references, this is a lot faster\r
2687                         if (!tinymce.isIE)\r
2688                                 el = t.dom.get(t.id);\r
2690                         each([\r
2691                                 'getPos',\r
2692                                 'getRect',\r
2693                                 'getParent',\r
2694                                 'add',\r
2695                                 'setStyle',\r
2696                                 'getStyle',\r
2697                                 'setStyles',\r
2698                                 'setAttrib',\r
2699                                 'setAttribs',\r
2700                                 'getAttrib',\r
2701                                 'addClass',\r
2702                                 'removeClass',\r
2703                                 'hasClass',\r
2704                                 'getOuterHTML',\r
2705                                 'setOuterHTML',\r
2706                                 'remove',\r
2707                                 'show',\r
2708                                 'hide',\r
2709                                 'isHidden',\r
2710                                 'setHTML',\r
2711                                 'get'\r
2712                         ], function(k) {\r
2713                                 t[k] = function() {\r
2714                                         var a = arguments, o;\r
2716                                         // Opera fails\r
2717                                         if (tinymce.isOpera) {\r
2718                                                 a = [id];\r
2720                                                 each(arguments, function(v) {\r
2721                                                         a.push(v);\r
2722                                                 });\r
2723                                         } else\r
2724                                                 Array.prototype.unshift.call(a, el || id);\r
2726                                         o = dom[k].apply(dom, a);\r
2727                                         t.update(k);\r
2729                                         return o;\r
2730                                 };\r
2731                         });\r
2732                 },\r
2734                 on : function(n, f, s) {\r
2735                         return tinymce.dom.Event.add(this.id, n, f, s);\r
2736                 },\r
2738                 getXY : function() {\r
2739                         return {\r
2740                                 x : parseInt(this.getStyle('left')),\r
2741                                 y : parseInt(this.getStyle('top'))\r
2742                         };\r
2743                 },\r
2745                 getSize : function() {\r
2746                         var n = this.dom.get(this.id);\r
2748                         return {\r
2749                                 w : parseInt(this.getStyle('width') || n.clientWidth),\r
2750                                 h : parseInt(this.getStyle('height') || n.clientHeight)\r
2751                         };\r
2752                 },\r
2754                 moveTo : function(x, y) {\r
2755                         this.setStyles({left : x, top : y});\r
2756                 },\r
2758                 moveBy : function(x, y) {\r
2759                         var p = this.getXY();\r
2761                         this.moveTo(p.x + x, p.y + y);\r
2762                 },\r
2764                 resizeTo : function(w, h) {\r
2765                         this.setStyles({width : w, height : h});\r
2766                 },\r
2768                 resizeBy : function(w, h) {\r
2769                         var s = this.getSize();\r
2771                         this.resizeTo(s.w + w, s.h + h);\r
2772                 },\r
2774                 update : function(k) {\r
2775                         var t = this, b, dom = t.dom;\r
2777                         if (tinymce.isIE6 && t.settings.blocker) {\r
2778                                 k = k || '';\r
2780                                 // Ignore getters\r
2781                                 if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0)\r
2782                                         return;\r
2784                                 // Remove blocker on remove\r
2785                                 if (k == 'remove') {\r
2786                                         dom.remove(t.blocker);\r
2787                                         return;\r
2788                                 }\r
2790                                 if (!t.blocker) {\r
2791                                         t.blocker = dom.uniqueId();\r
2792                                         b = dom.add(t.settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'});\r
2793                                         dom.setStyle(b, 'opacity', 0);\r
2794                                 } else\r
2795                                         b = dom.get(t.blocker);\r
2797                                 dom.setStyle(b, 'left', t.getStyle('left', 1));\r
2798                                 dom.setStyle(b, 'top', t.getStyle('top', 1));\r
2799                                 dom.setStyle(b, 'width', t.getStyle('width', 1));\r
2800                                 dom.setStyle(b, 'height', t.getStyle('height', 1));\r
2801                                 dom.setStyle(b, 'display', t.getStyle('display', 1));\r
2802                                 dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);\r
2803                         }\r
2804                 }\r
2806                 });\r
2807 })();\r
2809 /* file:jscripts/tiny_mce/classes/dom/Selection.js */\r
2811 (function() {\r
2812         function trimNl(s) {\r
2813                 return s.replace(/[\n\r]+/g, '');\r
2814         };\r
2816         // Shorten names\r
2817         var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;\r
2819         tinymce.create('tinymce.dom.Selection', {\r
2820                 Selection : function(dom, win, serializer) {\r
2821                         var t = this;\r
2823                         t.dom = dom;\r
2824                         t.win = win;\r
2825                         t.serializer = serializer;\r
2827                         // Prevent leaks\r
2828                         tinymce.addUnload(t.destroy, t);\r
2829                 },\r
2831                 getContent : function(s) {\r
2832                         var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;\r
2834                         s = s || {};\r
2835                         wb = wa = '';\r
2836                         s.get = true;\r
2837                         s.format = s.format || 'html';\r
2839                         if (s.format == 'text')\r
2840                                 return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));\r
2842                         if (r.cloneContents) {\r
2843                                 n = r.cloneContents();\r
2845                                 if (n)\r
2846                                         e.appendChild(n);\r
2847                         } else if (is(r.item) || is(r.htmlText))\r
2848                                 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;\r
2849                         else\r
2850                                 e.innerHTML = r.toString();\r
2852                         // Keep whitespace before and after\r
2853                         if (/^\s/.test(e.innerHTML))\r
2854                                 wb = ' ';\r
2856                         if (/\s+$/.test(e.innerHTML))\r
2857                                 wa = ' ';\r
2859                         s.getInner = true;\r
2861                         return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
2862                 },\r
2864                 setContent : function(h, s) {\r
2865                         var t = this, r = t.getRng(), c, d = t.win.document;\r
2867                         s = s || {format : 'html'};\r
2868                         s.set = true;\r
2869                         h = t.dom.processHTML(h);\r
2871                         if (r.insertNode) {\r
2872                                 // Make caret marker since insertNode places the caret in the beginning of text after insert\r
2873                                 h += '<span id="__caret">_</span>';\r
2875                                 // Delete and insert new node\r
2876                                 r.deleteContents();\r
2877                                 r.insertNode(t.getRng().createContextualFragment(h));\r
2879                                 // Move to caret marker\r
2880                                 c = t.dom.get('__caret');\r
2882                                 // Make sure we wrap it compleatly, Opera fails with a simple select call\r
2883                                 r = d.createRange();\r
2884                                 r.setStartBefore(c);\r
2885                                 r.setEndAfter(c);\r
2886                                 t.setRng(r);\r
2888                                 // Delete the marker, and hopefully the caret gets placed in the right location\r
2889                                 d.execCommand('Delete', false, null);\r
2891                                 // In case it's still there\r
2892                                 t.dom.remove('__caret');\r
2893                         } else {\r
2894                                 if (r.item) {\r
2895                                         // Delete content and get caret text selection\r
2896                                         d.execCommand('Delete', false, null);\r
2897                                         r = t.getRng();\r
2898                                 }\r
2900                                 r.pasteHTML(h);\r
2901                         }\r
2902                 },\r
2904                 getStart : function() {\r
2905                         var t = this, r = t.getRng(), e;\r
2907                         if (isIE) {\r
2908                                 if (r.item)\r
2909                                         return r.item(0);\r
2911                                 r = r.duplicate();\r
2912                                 r.collapse(1);\r
2913                                 e = r.parentElement();\r
2915                                 if (e && e.nodeName == 'BODY')\r
2916                                         return e.firstChild;\r
2918                                 return e;\r
2919                         } else {\r
2920                                 e = r.startContainer;\r
2922                                 if (e.nodeName == 'BODY')\r
2923                                         return e.firstChild;\r
2925                                 return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
2926                         }\r
2927                 },\r
2929                 getEnd : function() {\r
2930                         var t = this, r = t.getRng(), e;\r
2932                         if (isIE) {\r
2933                                 if (r.item)\r
2934                                         return r.item(0);\r
2936                                 r = r.duplicate();\r
2937                                 r.collapse(0);\r
2938                                 e = r.parentElement();\r
2940                                 if (e && e.nodeName == 'BODY')\r
2941                                         return e.lastChild;\r
2943                                 return e;\r
2944                         } else {\r
2945                                 e = r.endContainer;\r
2947                                 if (e.nodeName == 'BODY')\r
2948                                         return e.lastChild;\r
2950                                 return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
2951                         }\r
2952                 },\r
2954                 getBookmark : function(si) {\r
2955                         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
2956                         sx = vp.x;\r
2957                         sy = vp.y;\r
2959                         // Simple bookmark fast but not as persistent\r
2960                         if (si == 'simple')\r
2961                                 return {rng : r, scrollX : sx, scrollY : sy};\r
2963                         // Handle IE\r
2964                         if (isIE) {\r
2965                                 // Control selection\r
2966                                 if (r.item) {\r
2967                                         e = r.item(0);\r
2969                                         each(t.dom.select(e.nodeName), function(n, i) {\r
2970                                                 if (e == n) {\r
2971                                                         sp = i;\r
2972                                                         return false;\r
2973                                                 }\r
2974                                         });\r
2976                                         return {\r
2977                                                 tag : e.nodeName,\r
2978                                                 index : sp,\r
2979                                                 scrollX : sx,\r
2980                                                 scrollY : sy\r
2981                                         };\r
2982                                 }\r
2984                                 // Text selection\r
2985                                 tr = t.dom.doc.body.createTextRange();\r
2986                                 tr.moveToElementText(ro);\r
2987                                 tr.collapse(true);\r
2988                                 bp = Math.abs(tr.move('character', c));\r
2990                                 tr = r.duplicate();\r
2991                                 tr.collapse(true);\r
2992                                 sp = Math.abs(tr.move('character', c));\r
2994                                 tr = r.duplicate();\r
2995                                 tr.collapse(false);\r
2996                                 le = Math.abs(tr.move('character', c)) - sp;\r
2998                                 return {\r
2999                                         start : sp - bp,\r
3000                                         length : le,\r
3001                                         scrollX : sx,\r
3002                                         scrollY : sy\r
3003                                 };\r
3004                         }\r
3006                         // Handle W3C\r
3007                         e = t.getNode();\r
3008                         s = t.getSel();\r
3010                         if (!s)\r
3011                                 return null;\r
3013                         // Image selection\r
3014                         if (e && e.nodeName == 'IMG') {\r
3015                                 return {\r
3016                                         scrollX : sx,\r
3017                                         scrollY : sy\r
3018                                 };\r
3019                         }\r
3021                         // Text selection\r
3023                         function getPos(r, sn, en) {\r
3024                                 var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};\r
3026                                 while ((n = w.nextNode()) != null) {\r
3027                                         if (n == sn)\r
3028                                                 d.start = p;\r
3030                                         if (n == en) {\r
3031                                                 d.end = p;\r
3032                                                 return d;\r
3033                                         }\r
3035                                         p += trimNl(n.nodeValue || '').length;\r
3036                                 }\r
3038                                 return null;\r
3039                         };\r
3041                         // Caret or selection\r
3042                         if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) {\r
3043                                 e = getPos(ro, s.anchorNode, s.focusNode);\r
3045                                 if (!e)\r
3046                                         return {scrollX : sx, scrollY : sy};\r
3048                                 // Count whitespace before\r
3049                                 trimNl(s.anchorNode.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;});\r
3051                                 return {\r
3052                                         start : Math.max(e.start + s.anchorOffset - wb, 0),\r
3053                                         end : Math.max(e.end + s.focusOffset - wb, 0),\r
3054                                         scrollX : sx,\r
3055                                         scrollY : sy,\r
3056                                         beg : s.anchorOffset - wb == 0\r
3057                                 };\r
3058                         } else {\r
3059                                 e = getPos(ro, r.startContainer, r.endContainer);\r
3061                                 // Count whitespace before start and end container\r
3062                                 //(r.startContainer.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;});\r
3063                                 //(r.endContainer.nodeValue || '').replace(/^\s+/, function(a) {wa = a.length;});\r
3065                                 if (!e)\r
3066                                         return {scrollX : sx, scrollY : sy};\r
3068                                 return {\r
3069                                         start : Math.max(e.start + r.startOffset - wb, 0),\r
3070                                         end : Math.max(e.end + r.endOffset - wa, 0),\r
3071                                         scrollX : sx,\r
3072                                         scrollY : sy,\r
3073                                         beg : r.startOffset - wb == 0\r
3074                                 };\r
3075                         }\r
3076                 },\r
3078                 moveToBookmark : function(b) {\r
3079                         var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd, nvl, nv;\r
3081                         function getPos(r, sp, ep) {\r
3082                                 var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}, o, v, wa, wb;\r
3084                                 while ((n = w.nextNode()) != null) {\r
3085                                         wa = wb = 0;\r
3087                                         nv = n.nodeValue || '';\r
3088                                         //nv.replace(/^\s+[^\s]/, function(a) {wb = a.length - 1;});\r
3089                                         //nv.replace(/[^\s]\s+$/, function(a) {wa = a.length - 1;});\r
3091                                         nvl = trimNl(nv).length;\r
3092                                         p += nvl;\r
3094                                         if (p >= sp && !d.startNode) {\r
3095                                                 o = sp - (p - nvl);\r
3097                                                 // Fix for odd quirk in FF\r
3098                                                 if (b.beg && o >= nvl)\r
3099                                                         continue;\r
3101                                                 d.startNode = n;\r
3102                                                 d.startOffset = o + wb;\r
3103                                         }\r
3105                                         if (p >= ep) {\r
3106                                                 d.endNode = n;\r
3107                                                 d.endOffset = ep - (p - nvl) + wb;\r
3108                                                 return d;\r
3109                                         }\r
3110                                 }\r
3112                                 return null;\r
3113                         };\r
3115                         if (!b)\r
3116                                 return false;\r
3118                         t.win.scrollTo(b.scrollX, b.scrollY);\r
3120                         // Handle explorer\r
3121                         if (isIE) {\r
3122                                 // Handle simple\r
3123                                 if (r = b.rng) {\r
3124                                         try {\r
3125                                                 r.select();\r
3126                                         } catch (ex) {\r
3127                                                 // Ignore\r
3128                                         }\r
3130                                         return true;\r
3131                                 }\r
3133                                 t.win.focus();\r
3135                                 // Handle control bookmark\r
3136                                 if (b.tag) {\r
3137                                         r = ro.createControlRange();\r
3139                                         each(t.dom.select(b.tag), function(n, i) {\r
3140                                                 if (i == b.index)\r
3141                                                         r.addElement(n);\r
3142                                         });\r
3143                                 } else {\r
3144                                         // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs\r
3145                                         try {\r
3146                                                 // Incorrect bookmark\r
3147                                                 if (b.start < 0)\r
3148                                                         return true;\r
3150                                                 r = s.createRange();\r
3151                                                 r.moveToElementText(ro);\r
3152                                                 r.collapse(true);\r
3153                                                 r.moveStart('character', b.start);\r
3154                                                 r.moveEnd('character', b.length);\r
3155                                         } catch (ex2) {\r
3156                                                 return true;\r
3157                                         }\r
3158                                 }\r
3160                                 try {\r
3161                                         r.select();\r
3162                                 } catch (ex) {\r
3163                                         // Needed for some odd IE bug #1843306\r
3164                                 }\r
3166                                 return true;\r
3167                         }\r
3169                         // Handle W3C\r
3170                         if (!s)\r
3171                                 return false;\r
3173                         // Handle simple\r
3174                         if (b.rng) {\r
3175                                 s.removeAllRanges();\r
3176                                 s.addRange(b.rng);\r
3177                         } else {\r
3178                                 if (is(b.start) && is(b.end)) {\r
3179                                         try {\r
3180                                                 sd = getPos(ro, b.start, b.end);\r
3182                                                 if (sd) {\r
3183                                                         r = t.dom.doc.createRange();\r
3184                                                         r.setStart(sd.startNode, sd.startOffset);\r
3185                                                         r.setEnd(sd.endNode, sd.endOffset);\r
3186                                                         s.removeAllRanges();\r
3187                                                         s.addRange(r);\r
3188                                                 }\r
3190                                                 if (!tinymce.isOpera)\r
3191                                                         t.win.focus();\r
3192                                         } catch (ex) {\r
3193                                                 // Ignore\r
3194                                         }\r
3195                                 }\r
3196                         }\r
3197                 },\r
3199                 select : function(n, c) {\r
3200                         var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;\r
3202                         function first(n) {\r
3203                                 return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;\r
3204                         };\r
3206                         function last(n) {\r
3207                                 var c, o, w;\r
3209                                 if (!n)\r
3210                                         return null;\r
3212                                 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
3213                                 while (c = w.nextNode())\r
3214                                         o = c;\r
3216                                 return o;\r
3217                         };\r
3219                         if (isIE) {\r
3220                                 try {\r
3221                                         b = d.body;\r
3223                                         if (/^(IMG|TABLE)$/.test(n.nodeName)) {\r
3224                                                 r = b.createControlRange();\r
3225                                                 r.addElement(n);\r
3226                                         } else {\r
3227                                                 r = b.createTextRange();\r
3228                                                 r.moveToElementText(n);\r
3229                                         }\r
3231                                         r.select();\r
3232                                 } catch (ex) {\r
3233                                         // Throws illigal agrument in IE some times\r
3234                                 }\r
3235                         } else {\r
3236                                 if (c) {\r
3237                                         fn = first(n);\r
3238                                         ln = last(n);\r
3240                                         if (fn && ln) {\r
3241                                                 //console.debug(fn, ln);\r
3242                                                 r = d.createRange();\r
3243                                                 r.setStart(fn, 0);\r
3244                                                 r.setEnd(ln, ln.nodeValue.length);\r
3245                                         } else\r
3246                                                 r.selectNode(n);\r
3247                                 } else\r
3248                                         r.selectNode(n);\r
3250                                 t.setRng(r);\r
3251                         }\r
3253                         return n;\r
3254                 },\r
3256                 isCollapsed : function() {\r
3257                         var t = this, r = t.getRng(), s = t.getSel();\r
3259                         if (!r || r.item)\r
3260                                 return false;\r
3262                         return !s || r.boundingWidth == 0 || r.collapsed;\r
3263                 },\r
3265                 collapse : function(b) {\r
3266                         var t = this, r = t.getRng(), n;\r
3268                         // Control range on IE\r
3269                         if (r.item) {\r
3270                                 n = r.item(0);\r
3271                                 r = this.win.document.body.createTextRange();\r
3272                                 r.moveToElementText(n);\r
3273                         }\r
3275                         r.collapse(!!b);\r
3276                         t.setRng(r);\r
3277                 },\r
3279                 getSel : function() {\r
3280                         var t = this, w = this.win;\r
3282                         return w.getSelection ? w.getSelection() : w.document.selection;\r
3283                 },\r
3285                 getRng : function() {\r
3286                         var t = this, s = t.getSel(), r;\r
3288                         try {\r
3289                                 if (s)\r
3290                                         r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());\r
3291                         } catch (ex) {\r
3292                                 // IE throws unspecified error here if TinyMCE is placed in a frame/iframe\r
3293                         }\r
3295                         // No range found then create an empty one\r
3296                         // This can occur when the editor is placed in a hidden container element on Gecko\r
3297                         // Or on IE when there was an exception\r
3298                         if (!r)\r
3299                                 r = isIE ? t.win.document.body.createTextRange() : t.win.document.createRange();\r
3301                         return r;\r
3302                 },\r
3304                 setRng : function(r) {\r
3305                         var s;\r
3307                         if (!isIE) {\r
3308                                 s = this.getSel();\r
3310                                 if (s) {\r
3311                                         s.removeAllRanges();\r
3312                                         s.addRange(r);\r
3313                                 }\r
3314                         } else {\r
3315                                 try {\r
3316                                         r.select();\r
3317                                 } catch (ex) {\r
3318                                         // Needed for some odd IE bug #1843306\r
3319                                 }\r
3320                         }\r
3321                 },\r
3323                 setNode : function(n) {\r
3324                         var t = this;\r
3326                         t.setContent(t.dom.getOuterHTML(n));\r
3328                         return n;\r
3329                 },\r
3331                 getNode : function() {\r
3332                         var t = this, r = t.getRng(), s = t.getSel(), e;\r
3334                         if (!isIE) {\r
3335                                 // Range maybe lost after the editor is made visible again\r
3336                                 if (!r)\r
3337                                         return t.dom.getRoot();\r
3339                                 e = r.commonAncestorContainer;\r
3341                                 // Handle selection a image or other control like element such as anchors\r
3342                                 if (!r.collapsed) {\r
3343                                         // If the anchor node is a element instead of a text node then return this element\r
3344                                         if (tinymce.isWebKit && s.anchorNode && s.anchorNode.nodeType == 1) \r
3345                                                 return s.anchorNode.childNodes[s.anchorOffset]; \r
3347                                         if (r.startContainer == r.endContainer) {\r
3348                                                 if (r.startOffset - r.endOffset < 2) {\r
3349                                                         if (r.startContainer.hasChildNodes())\r
3350                                                                 e = r.startContainer.childNodes[r.startOffset];\r
3351                                                 }\r
3352                                         }\r
3353                                 }\r
3355                                 return t.dom.getParent(e, function(n) {\r
3356                                         return n.nodeType == 1;\r
3357                                 });\r
3358                         }\r
3360                         return r.item ? r.item(0) : r.parentElement();\r
3361                 },\r
3363                 destroy : function(s) {\r
3364                         var t = this;\r
3366                         t.win = null;\r
3368                         // Manual destroy then remove unload handler\r
3369                         if (!s)\r
3370                                 tinymce.removeUnload(t.destroy);\r
3371                 }\r
3373                 });\r
3374 })();\r
3376 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */\r
3378 (function() {\r
3379         tinymce.create('tinymce.dom.XMLWriter', {\r
3380                 node : null,\r
3382                 XMLWriter : function(s) {\r
3383                         // Get XML document\r
3384                         function getXML() {\r
3385                                 var i = document.implementation;\r
3387                                 if (!i || !i.createDocument) {\r
3388                                         // Try IE objects\r
3389                                         try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {}\r
3390                                         try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {}\r
3391                                 } else\r
3392                                         return i.createDocument('', '', null);\r
3393                         };\r
3395                         this.doc = getXML();\r
3396                         \r
3397                         // Since Opera and WebKit doesn't escape > into &gt; we need to do it our self to normalize the output for all browsers\r
3398                         this.valid = tinymce.isOpera || tinymce.isWebKit;\r
3400                         this.reset();\r
3401                 },\r
3403                 reset : function() {\r
3404                         var t = this, d = t.doc;\r
3406                         if (d.firstChild)\r
3407                                 d.removeChild(d.firstChild);\r
3409                         t.node = d.appendChild(d.createElement("html"));\r
3410                 },\r
3412                 writeStartElement : function(n) {\r
3413                         var t = this;\r
3415                         t.node = t.node.appendChild(t.doc.createElement(n));\r
3416                 },\r
3418                 writeAttribute : function(n, v) {\r
3419                         if (this.valid)\r
3420                                 v = v.replace(/>/g, '%MCGT%');\r
3422                         this.node.setAttribute(n, v);\r
3423                 },\r
3425                 writeEndElement : function() {\r
3426                         this.node = this.node.parentNode;\r
3427                 },\r
3429                 writeFullEndElement : function() {\r
3430                         var t = this, n = t.node;\r
3432                         n.appendChild(t.doc.createTextNode(""));\r
3433                         t.node = n.parentNode;\r
3434                 },\r
3436                 writeText : function(v) {\r
3437                         if (this.valid)\r
3438                                 v = v.replace(/>/g, '%MCGT%');\r
3440                         this.node.appendChild(this.doc.createTextNode(v));\r
3441                 },\r
3443                 writeCDATA : function(v) {\r
3444                         this.node.appendChild(this.doc.createCDATA(v));\r
3445                 },\r
3447                 writeComment : function(v) {\r
3448                         this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' ')));\r
3449                 },\r
3451                 getContent : function() {\r
3452                         var h;\r
3454                         h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);\r
3455                         h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, '');\r
3456                         h = h.replace(/ ?\/>/g, ' />');\r
3458                         if (this.valid)\r
3459                                 h = h.replace(/\%MCGT%/g, '&gt;');\r
3461                         return h;\r
3462                 }\r
3464                 });\r
3465 })();\r
3467 /* file:jscripts/tiny_mce/classes/dom/StringWriter.js */\r
3469 (function() {\r
3470         tinymce.create('tinymce.dom.StringWriter', {\r
3471                 str : null,\r
3472                 tags : null,\r
3473                 count : 0,\r
3474                 settings : null,\r
3475                 indent : null,\r
3477                 StringWriter : function(s) {\r
3478                         this.settings = tinymce.extend({\r
3479                                 indent_char : ' ',\r
3480                                 indentation : 1\r
3481                         }, s);\r
3483                         this.reset();\r
3484                 },\r
3486                 reset : function() {\r
3487                         this.indent = '';\r
3488                         this.str = "";\r
3489                         this.tags = [];\r
3490                         this.count = 0;\r
3491                 },\r
3493                 writeStartElement : function(n) {\r
3494                         this._writeAttributesEnd();\r
3495                         this.writeRaw('<' + n);\r
3496                         this.tags.push(n);\r
3497                         this.inAttr = true;\r
3498                         this.count++;\r
3499                         this.elementCount = this.count;\r
3500                 },\r
3502                 writeAttribute : function(n, v) {\r
3503                         var t = this;\r
3505                         t.writeRaw(" " + t.encode(n) + '="' + t.encode(v) + '"');\r
3506                 },\r
3508                 writeEndElement : function() {\r
3509                         var n;\r
3511                         if (this.tags.length > 0) {\r
3512                                 n = this.tags.pop();\r
3514                                 if (this._writeAttributesEnd(1))\r
3515                                         this.writeRaw('</' + n + '>');\r
3517                                 if (this.settings.indentation > 0)\r
3518                                         this.writeRaw('\n');\r
3519                         }\r
3520                 },\r
3522                 writeFullEndElement : function() {\r
3523                         if (this.tags.length > 0) {\r
3524                                 this._writeAttributesEnd();\r
3525                                 this.writeRaw('</' + this.tags.pop() + '>');\r
3527                                 if (this.settings.indentation > 0)\r
3528                                         this.writeRaw('\n');\r
3529                         }\r
3530                 },\r
3532                 writeText : function(v) {\r
3533                         this._writeAttributesEnd();\r
3534                         this.writeRaw(this.encode(v));\r
3535                         this.count++;\r
3536                 },\r
3538                 writeCDATA : function(v) {\r
3539                         this._writeAttributesEnd();\r
3540                         this.writeRaw('<![CDATA[' + v + ']]>');\r
3541                         this.count++;\r
3542                 },\r
3544                 writeComment : function(v) {\r
3545                         this._writeAttributesEnd();\r
3546                         this.writeRaw('<!-- ' + v + '-->');\r
3547                         this.count++;\r
3548                 },\r
3550                 writeRaw : function(v) {\r
3551                         this.str += v;\r
3552                 },\r
3554                 encode : function(s) {\r
3555                         return s.replace(/[<>&"]/g, function(v) {\r
3556                                 switch (v) {\r
3557                                         case '<':\r
3558                                                 return '&lt;';\r
3560                                         case '>':\r
3561                                                 return '&gt;';\r
3563                                         case '&':\r
3564                                                 return '&amp;';\r
3566                                         case '"':\r
3567                                                 return '&quot;';\r
3568                                 }\r
3570                                 return v;\r
3571                         });\r
3572                 },\r
3574                 getContent : function() {\r
3575                         return this.str;\r
3576                 },\r
3578                 _writeAttributesEnd : function(s) {\r
3579                         if (!this.inAttr)\r
3580                                 return;\r
3582                         this.inAttr = false;\r
3584                         if (s && this.elementCount == this.count) {\r
3585                                 this.writeRaw(' />');\r
3586                                 return false;\r
3587                         }\r
3589                         this.writeRaw('>');\r
3591                         return true;\r
3592                 }\r
3594                 });\r
3595 })();\r
3597 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */\r
3599 (function() {\r
3600         // Shorten names\r
3601         var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;\r
3603         // Returns only attribites that have values not all attributes in IE\r
3604         function getIEAtts(n) {\r
3605                 var o = [];\r
3607                 // Object will throw exception in IE\r
3608                 if (n.nodeName == 'OBJECT')\r
3609                         return n.attributes;\r
3611                 n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
3612                         o.push({specified : 1, nodeName : b});\r
3613                 });\r
3615                 return o;\r
3616         };\r
3618         function wildcardToRE(s) {\r
3619                 return s.replace(/([?+*])/g, '.$1');\r
3620         };\r
3622         tinymce.create('tinymce.dom.Serializer', {\r
3623                 Serializer : function(s) {\r
3624                         var t = this;\r
3626                         t.key = 0;\r
3627                         t.onPreProcess = new Dispatcher(t);\r
3628                         t.onPostProcess = new Dispatcher(t);\r
3630                         if (tinymce.relaxedDomain && tinymce.isGecko) {\r
3631                                 // Gecko has a bug where we can't create a new XML document if domain relaxing is used\r
3632                                 t.writer = new tinymce.dom.StringWriter();\r
3633                         } else {\r
3634                                 try {\r
3635                                         t.writer = new tinymce.dom.XMLWriter();\r
3636                                 } catch (ex) {\r
3637                                         // IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter\r
3638                                         t.writer = new tinymce.dom.StringWriter();\r
3639                                 }\r
3640                         }\r
3642                         // Default settings\r
3643                         t.settings = s = extend({\r
3644                                 dom : tinymce.DOM,\r
3645                                 valid_nodes : 0,\r
3646                                 node_filter : 0,\r
3647                                 attr_filter : 0,\r
3648                                 invalid_attrs : /^(mce_|_moz_)/,\r
3649                                 closed : /(br|hr|input|meta|img|link|param)/,\r
3650                                 entity_encoding : 'named',\r
3651                                 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
3652                                 valid_elements : '*[*]',\r
3653                                 extended_valid_elements : 0,\r
3654                                 valid_child_elements : 0,\r
3655                                 invalid_elements : 0,\r
3656                                 fix_table_elements : 0,\r
3657                                 fix_list_elements : true,\r
3658                                 fix_content_duplication : true,\r
3659                                 convert_fonts_to_spans : false,\r
3660                                 font_size_classes : 0,\r
3661                                 font_size_style_values : 0,\r
3662                                 apply_source_formatting : 0,\r
3663                                 indent_mode : 'simple',\r
3664                                 indent_char : '\t',\r
3665                                 indent_levels : 1,\r
3666                                 remove_linebreaks : 1,\r
3667                                 remove_redundant_brs : 1\r
3668                         }, s);\r
3670                         t.dom = s.dom;\r
3672                         if (s.remove_redundant_brs) {\r
3673                                 t.onPostProcess.add(function(se, o) {\r
3674                                         // Remove BR elements at end of list elements since they get rendered in IE\r
3675                                         o.content = o.content.replace(/<br \/>(\s*<\/li>)/g, '$1');\r
3676                                 });\r
3677                         }\r
3679                         if (s.fix_list_elements) {\r
3680                                 t.onPreProcess.add(function(se, o) {\r
3681                                         var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np;\r
3683                                         function prevNode(e, n) {\r
3684                                                 var a = n.split(','), i;\r
3686                                                 while ((e = e.previousSibling) != null) {\r
3687                                                         for (i=0; i<a.length; i++) {\r
3688                                                                 if (e.nodeName == a[i])\r
3689                                                                         return e;\r
3690                                                         }\r
3691                                                 }\r
3693                                                 return null;\r
3694                                         };\r
3696                                         for (x=0; x<a.length; x++) {\r
3697                                                 nl = t.dom.select(a[x], o.node);\r
3699                                                 for (i=0; i<nl.length; i++) {\r
3700                                                         n = nl[i];\r
3701                                                         p = n.parentNode;\r
3703                                                         if (r.test(p.nodeName)) {\r
3704                                                                 np = prevNode(n, 'LI');\r
3706                                                                 if (!np) {\r
3707                                                                         np = t.dom.create('li');\r
3708                                                                         np.innerHTML = '&nbsp;';\r
3709                                                                         np.appendChild(n);\r
3710                                                                         p.insertBefore(np, p.firstChild);\r
3711                                                                 } else\r
3712                                                                         np.appendChild(n);\r
3713                                                         }\r
3714                                                 }\r
3715                                         }\r
3716                                 });\r
3717                         }\r
3719                         if (s.fix_table_elements) {\r
3720                                 t.onPreProcess.add(function(se, o) {\r
3721                                         each(t.dom.select('table', o.node), function(e) {\r
3722                                                 var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), pa2, n, tm, pl = [], i, ns;\r
3724                                                 if (pa) {\r
3725                                                         pa2 = pa.cloneNode(false);\r
3727                                                         pl.push(e);\r
3728                                                         for (n = e; n = n.parentNode;) {\r
3729                                                                 pl.push(n);\r
3731                                                                 if (n == pa)\r
3732                                                                         break;\r
3733                                                         }\r
3735                                                         tm = pa2;\r
3736                                                         for (i = pl.length - 1; i >= 0; i--) {\r
3737                                                                 if (i == pl.length - 1) {\r
3738                                                                         while (ns = pl[i - 1].nextSibling)\r
3739                                                                                 tm.appendChild(ns.parentNode.removeChild(ns));\r
3740                                                                 } else {\r
3741                                                                         n = pl[i].cloneNode(false);\r
3743                                                                         if (i != 0) {\r
3744                                                                                 while (ns = pl[i - 1].nextSibling)\r
3745                                                                                         n.appendChild(ns.parentNode.removeChild(ns));\r
3746                                                                         }\r
3748                                                                         tm = tm.appendChild(n);\r
3749                                                                 }\r
3750                                                         }\r
3752                                                         e = t.dom.insertAfter(e.parentNode.removeChild(e), pa);\r
3753                                                         t.dom.insertAfter(e, pa);\r
3754                                                         t.dom.insertAfter(pa2, e);\r
3755                                                 }\r
3756                                         });\r
3757                                 });\r
3758                         }\r
3759                 },\r
3761                 setEntities : function(s) {\r
3762                         var t = this, a, i, l = {}, re = '', v;\r
3764                         // No need to setup more than once\r
3765                         if (t.entityLookup)\r
3766                                 return;\r
3768                         // Build regex and lookup array\r
3769                         a = s.split(',');\r
3770                         for (i = 0; i < a.length; i += 2) {\r
3771                                 v = a[i];\r
3773                                 // Don't add default &amp; &quot; etc.\r
3774                                 if (v == 34 || v == 38 || v == 60 || v == 62)\r
3775                                         continue;\r
3777                                 l[String.fromCharCode(a[i])] = a[i + 1];\r
3779                                 v = parseInt(a[i]).toString(16);\r
3780                                 re += '\\u' + '0000'.substring(v.length) + v;\r
3781                         }\r
3783                         if (!re) {\r
3784                                 t.settings.entity_encoding = 'raw';\r
3785                                 return;\r
3786                         }\r
3788                         t.entitiesRE = new RegExp('[' + re + ']', 'g');\r
3789                         t.entityLookup = l;\r
3790                 },\r
3792                 setValidChildRules : function(s) {\r
3793                         this.childRules = null;\r
3794                         this.addValidChildRules(s);\r
3795                 },\r
3797                 addValidChildRules : function(s) {\r
3798                         var t = this, inst, intr, bloc;\r
3800                         if (!s)\r
3801                                 return;\r
3803                         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
3804                         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
3805                         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
3807                         each(s.split(','), function(s) {\r
3808                                 var p = s.split(/\[|\]/), re;\r
3810                                 s = '';\r
3811                                 each(p[1].split('|'), function(v) {\r
3812                                         if (s)\r
3813                                                 s += '|';\r
3815                                         switch (v) {\r
3816                                                 case '%itrans':\r
3817                                                         v = intr;\r
3818                                                         break;\r
3820                                                 case '%itrans_na':\r
3821                                                         v = intr.substring(2);\r
3822                                                         break;\r
3824                                                 case '%istrict':\r
3825                                                         v = inst;\r
3826                                                         break;\r
3828                                                 case '%istrict_na':\r
3829                                                         v = inst.substring(2);\r
3830                                                         break;\r
3832                                                 case '%btrans':\r
3833                                                         v = bloc;\r
3834                                                         break;\r
3836                                                 case '%bstrict':\r
3837                                                         v = bloc;\r
3838                                                         break;\r
3839                                         }\r
3841                                         s += v;\r
3842                                 });\r
3843                                 re = new RegExp('^(' + s.toLowerCase() + ')$', 'i');\r
3845                                 each(p[0].split('/'), function(s) {\r
3846                                         t.childRules = t.childRules || {};\r
3847                                         t.childRules[s] = re;\r
3848                                 });\r
3849                         });\r
3851                         // Build regex\r
3852                         s = '';\r
3853                         each(t.childRules, function(v, k) {\r
3854                                 if (s)\r
3855                                         s += '|';\r
3857                                 s += k;\r
3858                         });\r
3860                         t.parentElementsRE = new RegExp('^(' + s.toLowerCase() + ')$', 'i');\r
3862                         /*console.debug(t.parentElementsRE.toString());\r
3863                         each(t.childRules, function(v) {\r
3864                                 console.debug(v.toString());\r
3865                         });*/\r
3866                 },\r
3868                 setRules : function(s) {\r
3869                         var t = this;\r
3871                         t._setup();\r
3872                         t.rules = {};\r
3873                         t.wildRules = [];\r
3874                         t.validElements = {};\r
3876                         return t.addRules(s);\r
3877                 },\r
3879                 addRules : function(s) {\r
3880                         var t = this, dr;\r
3882                         if (!s)\r
3883                                 return;\r
3885                         t._setup();\r
3887                         each(s.split(','), function(s) {\r
3888                                 var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = [];\r
3890                                 // Extend with default rules\r
3891                                 if (dr)\r
3892                                         at = tinymce.extend([], dr.attribs);\r
3894                                 // Parse attributes\r
3895                                 if (p.length > 1) {\r
3896                                         each(p[1].split('|'), function(s) {\r
3897                                                 var ar = {}, i;\r
3899                                                 at = at || [];\r
3901                                                 // Parse attribute rule\r
3902                                                 s = s.replace(/::/g, '~');\r
3903                                                 s = /^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(s);\r
3904                                                 s[2] = s[2].replace(/~/g, ':');\r
3906                                                 // Add required attributes\r
3907                                                 if (s[1] == '!') {\r
3908                                                         ra = ra || [];\r
3909                                                         ra.push(s[2]);\r
3910                                                 }\r
3912                                                 // Remove inherited attributes\r
3913                                                 if (s[1] == '-') {\r
3914                                                         for (i = 0; i <at.length; i++) {\r
3915                                                                 if (at[i].name == s[2]) {\r
3916                                                                         at.splice(i, 1);\r
3917                                                                         return;\r
3918                                                                 }\r
3919                                                         }\r
3920                                                 }\r
3922                                                 switch (s[3]) {\r
3923                                                         // Add default attrib values\r
3924                                                         case '=':\r
3925                                                                 ar.defaultVal = s[4] || '';\r
3926                                                                 break;\r
3928                                                         // Add forced attrib values\r
3929                                                         case ':':\r
3930                                                                 ar.forcedVal = s[4];\r
3931                                                                 break;\r
3933                                                         // Add validation values\r
3934                                                         case '<':\r
3935                                                                 ar.validVals = s[4].split('?');\r
3936                                                                 break;\r
3937                                                 }\r
3939                                                 if (/[*.?]/.test(s[2])) {\r
3940                                                         wat = wat || [];\r
3941                                                         ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$');\r
3942                                                         wat.push(ar);\r
3943                                                 } else {\r
3944                                                         ar.name = s[2];\r
3945                                                         at.push(ar);\r
3946                                                 }\r
3948                                                 va.push(s[2]);\r
3949                                         });\r
3950                                 }\r
3952                                 // Handle element names\r
3953                                 each(tn, function(s, i) {\r
3954                                         var pr = s.charAt(0), x = 1, ru = {};\r
3956                                         // Extend with default rule data\r
3957                                         if (dr) {\r
3958                                                 if (dr.noEmpty)\r
3959                                                         ru.noEmpty = dr.noEmpty;\r
3961                                                 if (dr.fullEnd)\r
3962                                                         ru.fullEnd = dr.fullEnd;\r
3964                                                 if (dr.padd)\r
3965                                                         ru.padd = dr.padd;\r
3966                                         }\r
3968                                         // Handle prefixes\r
3969                                         switch (pr) {\r
3970                                                 case '-':\r
3971                                                         ru.noEmpty = true;\r
3972                                                         break;\r
3974                                                 case '+':\r
3975                                                         ru.fullEnd = true;\r
3976                                                         break;\r
3978                                                 case '#':\r
3979                                                         ru.padd = true;\r
3980                                                         break;\r
3982                                                 default:\r
3983                                                         x = 0;\r
3984                                         }\r
3986                                         tn[i] = s = s.substring(x);\r
3987                                         t.validElements[s] = 1;\r
3989                                         // Add element name or element regex\r
3990                                         if (/[*.?]/.test(tn[0])) {\r
3991                                                 ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$');\r
3992                                                 t.wildRules = t.wildRules || {};\r
3993                                                 t.wildRules.push(ru);\r
3994                                         } else {\r
3995                                                 ru.name = tn[0];\r
3997                                                 // Store away default rule\r
3998                                                 if (tn[0] == '@')\r
3999                                                         dr = ru;\r
4001                                                 t.rules[s] = ru;\r
4002                                         }\r
4004                                         ru.attribs = at;\r
4006                                         if (ra)\r
4007                                                 ru.requiredAttribs = ra;\r
4009                                         if (wat) {\r
4010                                                 // Build valid attributes regexp\r
4011                                                 s = '';\r
4012                                                 each(va, function(v) {\r
4013                                                         if (s)\r
4014                                                                 s += '|';\r
4016                                                         s += '(' + wildcardToRE(v) + ')';\r
4017                                                 });\r
4018                                                 ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$');\r
4019                                                 ru.wildAttribs = wat;\r
4020                                         }\r
4021                                 });\r
4022                         });\r
4024                         // Build valid elements regexp\r
4025                         s = '';\r
4026                         each(t.validElements, function(v, k) {\r
4027                                 if (s)\r
4028                                         s += '|';\r
4030                                 if (k != '@')\r
4031                                         s += k;\r
4032                         });\r
4033                         t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$');\r
4035                         //console.debug(t.validElementsRE.toString());\r
4036                         //console.dir(t.rules);\r
4037                         //console.dir(t.wildRules);\r
4038                 },\r
4040                 findRule : function(n) {\r
4041                         var t = this, rl = t.rules, i, r;\r
4043                         t._setup();\r
4045                         // Exact match\r
4046                         r = rl[n];\r
4047                         if (r)\r
4048                                 return r;\r
4050                         // Try wildcards\r
4051                         rl = t.wildRules;\r
4052                         for (i = 0; i < rl.length; i++) {\r
4053                                 if (rl[i].nameRE.test(n))\r
4054                                         return rl[i];\r
4055                         }\r
4057                         return null;\r
4058                 },\r
4060                 findAttribRule : function(ru, n) {\r
4061                         var i, wa = ru.wildAttribs;\r
4063                         for (i = 0; i < wa.length; i++) {\r
4064                                 if (wa[i].nameRE.test(n))\r
4065                                         return wa[i];\r
4066                         }\r
4068                         return null;\r
4069                 },\r
4071                 serialize : function(n, o) {\r
4072                         var h, t = this;\r
4074                         t._setup();\r
4075                         o = o || {};\r
4076                         o.format = o.format || 'html';\r
4077                         t.processObj = o;\r
4078                         n = n.cloneNode(true);\r
4079                         t.key = '' + (parseInt(t.key) + 1);\r
4081                         // Pre process\r
4082                         if (!o.no_events) {\r
4083                                 o.node = n;\r
4084                                 t.onPreProcess.dispatch(t, o);\r
4085                         }\r
4087                         // Serialize HTML DOM into a string\r
4088                         t.writer.reset();\r
4089                         t._serializeNode(n, o.getInner);\r
4091                         // Post process\r
4092                         o.content = t.writer.getContent();\r
4094                         if (!o.no_events)\r
4095                                 t.onPostProcess.dispatch(t, o);\r
4097                         t._postProcess(o);\r
4098                         o.node = null;\r
4100                         return tinymce.trim(o.content);\r
4101                 },\r
4103                 // Internal functions\r
4105                 _postProcess : function(o) {\r
4106                         var t = this, s = t.settings, h = o.content, sc = [], p;\r
4108                         if (o.format == 'html') {\r
4109                                 // Protect some elements\r
4110                                 p = t._protect({\r
4111                                         content : h,\r
4112                                         patterns : [\r
4113                                                 {pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},\r
4114                                                 {pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},\r
4115                                                 {pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},\r
4116                                                 {pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}\r
4117                                         ]\r
4118                                 });\r
4120                                 h = p.content;\r
4122                                 // Entity encode\r
4123                                 if (s.entity_encoding !== 'raw')\r
4124                                         h = t._encode(h);\r
4126                                 // Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor\r
4127 /*                              if (o.set)\r
4128                                         h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');\r
4129                                 else\r
4130                                         h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');*/\r
4132                                 // Since Gecko and Safari keeps whitespace in the DOM we need to\r
4133                                 // remove it inorder to match other browsers. But I think Gecko and Safari is right.\r
4134                                 // This process is only done when getting contents out from the editor.\r
4135                                 if (!o.set) {\r
4136                                         // We need to replace paragraph whitespace with an nbsp before indentation to keep the \u00a0 char\r
4137                                         h = h.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g, s.entity_encoding == 'numeric' ? '<p$1>&#160;</p>' : '<p$1>&nbsp;</p>');\r
4139                                         if (s.remove_linebreaks) {\r
4140                                                 h = h.replace(/\r?\n|\r/g, ' ');\r
4141                                                 h = h.replace(/(<[^>]+>)\s+/g, '$1 ');\r
4142                                                 h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');\r
4143                                                 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
4144                                                 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
4145                                                 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
4146                                         }\r
4148                                         // Simple indentation\r
4149                                         if (s.apply_source_formatting && s.indent_mode == 'simple') {\r
4150                                                 // Add line breaks before and after block elements\r
4151                                                 h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');\r
4152                                                 h = h.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');\r
4153                                                 h = h.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');\r
4154                                                 h = h.replace(/\n\n/g, '\n');\r
4155                                         }\r
4156                                 }\r
4158                                 h = t._unprotect(h, p);\r
4160                                 // Restore CDATA sections\r
4161                                 h = h.replace(/<!--\[CDATA\[([\s\S]+)\]\]-->/g, '<![CDATA[$1]]>');\r
4163                                 // Restore the \u00a0 character if raw mode is enabled\r
4164                                 if (s.entity_encoding == 'raw')\r
4165                                         h = h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g, '<p$1>\u00a0</p>');\r
4166                         }\r
4168                         o.content = h;\r
4169                 },\r
4171                 _serializeNode : function(n, inn) {\r
4172                         var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;\r
4174                         if (!s.node_filter || s.node_filter(n)) {\r
4175                                 switch (n.nodeType) {\r
4176                                         case 1: // Element\r
4177                                                 if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))\r
4178                                                         return;\r
4180                                                 iv = false;\r
4181                                                 hc = n.hasChildNodes();\r
4182                                                 nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase();\r
4184                                                 // Add correct prefix on IE\r
4185                                                 if (isIE) {\r
4186                                                         if (n.scopeName !== 'HTML' && n.scopeName !== 'html')\r
4187                                                                 nn = n.scopeName + ':' + nn;\r
4188                                                 }\r
4190                                                 // Remove mce prefix on IE needed for the abbr element\r
4191                                                 if (nn.indexOf('mce:') === 0)\r
4192                                                         nn = nn.substring(4);\r
4194                                                 // Check if valid\r
4195                                                 if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {\r
4196                                                         iv = true;\r
4197                                                         break;\r
4198                                                 }\r
4200                                                 if (isIE) {\r
4201                                                         // Fix IE content duplication (DOM can have multiple copies of the same node)\r
4202                                                         if (s.fix_content_duplication) {\r
4203                                                                 if (n.mce_serialized == t.key)\r
4204                                                                         return;\r
4206                                                                 n.mce_serialized = t.key;\r
4207                                                         }\r
4209                                                         // IE sometimes adds a / infront of the node name\r
4210                                                         if (nn.charAt(0) == '/')\r
4211                                                                 nn = nn.substring(1);\r
4212                                                 } else if (isGecko) {\r
4213                                                         // Ignore br elements\r
4214                                                         if (n.nodeName === 'BR' && n.getAttribute('type') == '_moz')\r
4215                                                                 return;\r
4216                                                 }\r
4218                                                 // Check if valid child\r
4219                                                 if (t.childRules) {\r
4220                                                         if (t.parentElementsRE.test(t.elementName)) {\r
4221                                                                 if (!t.childRules[t.elementName].test(nn)) {\r
4222                                                                         iv = true;\r
4223                                                                         break;\r
4224                                                                 }\r
4225                                                         }\r
4227                                                         t.elementName = nn;\r
4228                                                 }\r
4230                                                 ru = t.findRule(nn);\r
4231                                                 nn = ru.name || nn;\r
4233                                                 // Skip empty nodes or empty node name in IE\r
4234                                                 if ((!hc && ru.noEmpty) || (isIE && !nn)) {\r
4235                                                         iv = true;\r
4236                                                         break;\r
4237                                                 }\r
4239                                                 // Check required\r
4240                                                 if (ru.requiredAttribs) {\r
4241                                                         a = ru.requiredAttribs;\r
4243                                                         for (i = a.length - 1; i >= 0; i--) {\r
4244                                                                 if (this.dom.getAttrib(n, a[i]) !== '')\r
4245                                                                         break;\r
4246                                                         }\r
4248                                                         // None of the required was there\r
4249                                                         if (i == -1) {\r
4250                                                                 iv = true;\r
4251                                                                 break;\r
4252                                                         }\r
4253                                                 }\r
4255                                                 w.writeStartElement(nn);\r
4257                                                 // Add ordered attributes\r
4258                                                 if (ru.attribs) {\r
4259                                                         for (i=0, at = ru.attribs, l = at.length; i<l; i++) {\r
4260                                                                 a = at[i];\r
4261                                                                 v = t._getAttrib(n, a);\r
4263                                                                 if (v !== null)\r
4264                                                                         w.writeAttribute(a.name, v);\r
4265                                                         }\r
4266                                                 }\r
4268                                                 // Add wild attributes\r
4269                                                 if (ru.validAttribsRE) {\r
4270                                                         at = isIE ? getIEAtts(n) : n.attributes;\r
4271                                                         for (i=at.length-1; i>-1; i--) {\r
4272                                                                 no = at[i];\r
4274                                                                 if (no.specified) {\r
4275                                                                         a = no.nodeName.toLowerCase();\r
4277                                                                         if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a))\r
4278                                                                                 continue;\r
4280                                                                         ar = t.findAttribRule(ru, a);\r
4281                                                                         v = t._getAttrib(n, ar, a);\r
4283                                                                         if (v !== null)\r
4284                                                                                 w.writeAttribute(a, v);\r
4285                                                                 }\r
4286                                                         }\r
4287                                                 }\r
4289                                                 // Padd empty nodes with a &nbsp;\r
4290                                                 if (!hc && ru.padd)\r
4291                                                         w.writeText('\u00a0');\r
4293                                                 break;\r
4295                                         case 3: // Text\r
4296                                                 // Check if valid child\r
4297                                                 if (t.childRules && t.parentElementsRE.test(t.elementName)) {\r
4298                                                         if (!t.childRules[t.elementName].test(n.nodeName))\r
4299                                                                 return;\r
4300                                                 }\r
4302                                                 return w.writeText(n.nodeValue);\r
4304                                         case 4: // CDATA\r
4305                                                 return w.writeCDATA(n.nodeValue);\r
4307                                         case 8: // Comment\r
4308                                                 return w.writeComment(n.nodeValue);\r
4309                                 }\r
4310                         } else if (n.nodeType == 1)\r
4311                                 hc = n.hasChildNodes();\r
4313                         if (hc) {\r
4314                                 cn = n.firstChild;\r
4316                                 while (cn) {\r
4317                                         t._serializeNode(cn);\r
4318                                         t.elementName = nn;\r
4319                                         cn = cn.nextSibling;\r
4320                                 }\r
4321                         }\r
4323                         // Write element end\r
4324                         if (!iv) {\r
4325                                 if (hc || !s.closed.test(nn))\r
4326                                         w.writeFullEndElement();\r
4327                                 else\r
4328                                         w.writeEndElement();\r
4329                         }\r
4330                 },\r
4332                 _protect : function(o) {\r
4333                         var t = this;\r
4335                         o.items = o.items || [];\r
4337                         function enc(s) {\r
4338                                 return s.replace(/[\r\n\\]/g, function(c) {\r
4339                                         if (c === '\n')\r
4340                                                 return '\\n';\r
4341                                         else if (c === '\\')\r
4342                                                 return '\\\\';\r
4344                                         return '\\r';\r
4345                                 });\r
4346                         };\r
4348                         function dec(s) {\r
4349                                 return s.replace(/\\[\\rn]/g, function(c) {\r
4350                                         if (c === '\\n')\r
4351                                                 return '\n';\r
4352                                         else if (c === '\\\\')\r
4353                                                 return '\\';\r
4355                                         return '\r';\r
4356                                 });\r
4357                         };\r
4359                         each(o.patterns, function(p) {\r
4360                                 o.content = dec(enc(o.content).replace(p.pattern, function(x, a, b, c) {\r
4361                                         b = dec(b);\r
4363                                         if (p.encode)\r
4364                                                 b = t._encode(b);\r
4366                                         o.items.push(b);\r
4367                                         return a + '<!--mce:' + (o.items.length - 1) + '-->' + c;\r
4368                                 }));\r
4369                         });\r
4371                         return o;\r
4372                 },\r
4374                 _unprotect : function(h, o) {\r
4375                         h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) {\r
4376                                 return o.items[parseInt(b)];\r
4377                         });\r
4379                         o.items = [];\r
4381                         return h;\r
4382                 },\r
4384                 _encode : function(h) {\r
4385                         var t = this, s = t.settings, l;\r
4387                         // Entity encode\r
4388                         if (s.entity_encoding !== 'raw') {\r
4389                                 if (s.entity_encoding.indexOf('named') != -1) {\r
4390                                         t.setEntities(s.entities);\r
4391                                         l = t.entityLookup;\r
4393                                         h = h.replace(t.entitiesRE, function(a) {\r
4394                                                 var v;\r
4396                                                 if (v = l[a])\r
4397                                                         a = '&' + v + ';';\r
4399                                                 return a;\r
4400                                         });\r
4401                                 }\r
4403                                 if (s.entity_encoding.indexOf('numeric') != -1) {\r
4404                                         h = h.replace(/[\u007E-\uFFFF]/g, function(a) {\r
4405                                                 return '&#' + a.charCodeAt(0) + ';';\r
4406                                         });\r
4407                                 }\r
4408                         }\r
4410                         return h;\r
4411                 },\r
4413                 _setup : function() {\r
4414                         var t = this, s = this.settings;\r
4416                         if (t.done)\r
4417                                 return;\r
4419                         t.done = 1;\r
4421                         t.setRules(s.valid_elements);\r
4422                         t.addRules(s.extended_valid_elements);\r
4423                         t.addValidChildRules(s.valid_child_elements);\r
4425                         if (s.invalid_elements)\r
4426                                 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(/,/g, '|').toLowerCase()) + ')$');\r
4428                         if (s.attrib_value_filter)\r
4429                                 t.attribValueFilter = s.attribValueFilter;\r
4430                 },\r
4432                 _getAttrib : function(n, a, na) {\r
4433                         var i, v;\r
4435                         na = na || a.name;\r
4437                         if (a.forcedVal && (v = a.forcedVal)) {\r
4438                                 if (v === '{$uid}')\r
4439                                         return this.dom.uniqueId();\r
4441                                 return v;\r
4442                         }\r
4444                         v = this.dom.getAttrib(n, na);\r
4446                         switch (na) {\r
4447                                 case 'rowspan':\r
4448                                 case 'colspan':\r
4449                                         // Whats the point? Remove usless attribute value\r
4450                                         if (v == '1')\r
4451                                                 v = '';\r
4453                                         break;\r
4454                         }\r
4456                         if (this.attribValueFilter)\r
4457                                 v = this.attribValueFilter(na, v, n);\r
4459                         if (a.validVals) {\r
4460                                 for (i = a.validVals.length - 1; i >= 0; i--) {\r
4461                                         if (v == a.validVals[i])\r
4462                                                 break;\r
4463                                 }\r
4465                                 if (i == -1)\r
4466                                         return null;\r
4467                         }\r
4469                         if (v === '' && typeof(a.defaultVal) != 'undefined') {\r
4470                                 v = a.defaultVal;\r
4472                                 if (v === '{$uid}')\r
4473                                         return this.dom.uniqueId();\r
4475                                 return v;\r
4476                         } else {\r
4477                                 // Remove internal mceItemXX classes when content is extracted from editor\r
4478                                 if (na == 'class' && this.processObj.get)\r
4479                                         v = v.replace(/\s?mceItem\w+\s?/g, '');\r
4480                         }\r
4482                         if (v === '')\r
4483                                 return null;\r
4486                         return v;\r
4487                 }\r
4489                 });\r
4490 })();\r
4492 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */\r
4494 (function() {\r
4495         var each = tinymce.each;\r
4497         tinymce.create('tinymce.dom.ScriptLoader', {\r
4498                 ScriptLoader : function(s) {\r
4499                         this.settings = s || {};\r
4500                         this.queue = [];\r
4501                         this.lookup = {};\r
4502                 },\r
4504                 isDone : function(u) {\r
4505                         return this.lookup[u] ? this.lookup[u].state == 2 : 0;\r
4506                 },\r
4508                 markDone : function(u) {\r
4509                         this.lookup[u] = {state : 2, url : u};\r
4510                 },\r
4512                 add : function(u, cb, s, pr) {\r
4513                         var t = this, lo = t.lookup, o;\r
4515                         if (o = lo[u]) {\r
4516                                 // Is loaded fire callback\r
4517                                 if (cb && o.state == 2)\r
4518                                         cb.call(s || this);\r
4520                                 return o;\r
4521                         }\r
4523                         o = {state : 0, url : u, func : cb, scope : s || this};\r
4525                         if (pr)\r
4526                                 t.queue.unshift(o);\r
4527                         else\r
4528                                 t.queue.push(o);\r
4530                         lo[u] = o;\r
4532                         return o;\r
4533                 },\r
4535                 load : function(u, cb, s) {\r
4536                         var t = this, o;\r
4538                         if (o = t.lookup[u]) {\r
4539                                 // Is loaded fire callback\r
4540                                 if (cb && o.state == 2)\r
4541                                         cb.call(s || t);\r
4543                                 return o;\r
4544                         }\r
4546                         function loadScript(u) {\r
4547                                 if (tinymce.dom.Event.domLoaded || t.settings.strict_mode) {\r
4548                                         tinymce.util.XHR.send({\r
4549                                                 url : tinymce._addVer(u),\r
4550                                                 error : t.settings.error,\r
4551                                                 async : false,\r
4552                                                 success : function(co) {\r
4553                                                         t.eval(co);\r
4554                                                 }\r
4555                                         });\r
4556                                 } else\r
4557                                         document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"></script>');\r
4558                         };\r
4560                         if (!tinymce.is(u, 'string')) {\r
4561                                 each(u, function(u) {\r
4562                                         loadScript(u);\r
4563                                 });\r
4565                                 if (cb)\r
4566                                         cb.call(s || t);\r
4567                         } else {\r
4568                                 loadScript(u);\r
4570                                 if (cb)\r
4571                                         cb.call(s || t);\r
4572                         }\r
4573                 },\r
4575                 loadQueue : function(cb, s) {\r
4576                         var t = this;\r
4578                         if (!t.queueLoading) {\r
4579                                 t.queueLoading = 1;\r
4580                                 t.queueCallbacks = [];\r
4582                                 t.loadScripts(t.queue, function() {\r
4583                                         t.queueLoading = 0;\r
4585                                         if (cb)\r
4586                                                 cb.call(s || t);\r
4588                                         each(t.queueCallbacks, function(o) {\r
4589                                                 o.func.call(o.scope);\r
4590                                         });\r
4591                                 });\r
4592                         } else if (cb)\r
4593                                 t.queueCallbacks.push({func : cb, scope : s || t});\r
4594                 },\r
4596                 eval : function(co) {\r
4597                         var w = window;\r
4599                         // Evaluate script\r
4600                         if (!w.execScript) {\r
4601                                 try {\r
4602                                         eval.call(w, co);\r
4603                                 } catch (ex) {\r
4604                                         eval(co, w); // Firefox 3.0a8\r
4605                                 }\r
4606                         } else\r
4607                                 w.execScript(co); // IE\r
4608                 },\r
4610                 loadScripts : function(sc, cb, s) {\r
4611                         var t = this, lo = t.lookup;\r
4613                         function done(o) {\r
4614                                 o.state = 2; // Has been loaded\r
4616                                 // Run callback\r
4617                                 if (o.func)\r
4618                                         o.func.call(o.scope || t);\r
4619                         };\r
4621                         function allDone() {\r
4622                                 var l;\r
4624                                 // Check if all files are loaded\r
4625                                 l = sc.length;\r
4626                                 each(sc, function(o) {\r
4627                                         o = lo[o.url];\r
4629                                         if (o.state === 2) {// It has finished loading\r
4630                                                 done(o);\r
4631                                                 l--;\r
4632                                         } else\r
4633                                                 load(o);\r
4634                                 });\r
4636                                 // They are all loaded\r
4637                                 if (l === 0 && cb) {\r
4638                                         cb.call(s || t);\r
4639                                         cb = 0;\r
4640                                 }\r
4641                         };\r
4643                         function load(o) {\r
4644                                 if (o.state > 0)\r
4645                                         return;\r
4647                                 o.state = 1; // Is loading\r
4649                                 tinymce.util.XHR.send({\r
4650                                         url : o.url,\r
4651                                         error : t.settings.error,\r
4652                                         success : function(co) {\r
4653                                                 t.eval(co);\r
4654                                                 done(o);\r
4655                                                 allDone();\r
4656                                         }\r
4657                                 });\r
4658                         };\r
4660                         each(sc, function(o) {\r
4661                                 var u = o.url;\r
4663                                 // Add to queue if needed\r
4664                                 if (!lo[u]) {\r
4665                                         lo[u] = o;\r
4666                                         t.queue.push(o);\r
4667                                 } else\r
4668                                         o = lo[u];\r
4670                                 // Is already loading or has been loaded\r
4671                                 if (o.state > 0)\r
4672                                         return;\r
4674                                 if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) {\r
4675                                         var ix, ol = '';\r
4677                                         // Add onload events\r
4678                                         if (cb || o.func) {\r
4679                                                 o.state = 1; // Is loading\r
4681                                                 ix = tinymce.dom.ScriptLoader._addOnLoad(function() {\r
4682                                                         done(o);\r
4683                                                         allDone();\r
4684                                                 });\r
4686                                                 if (tinymce.isIE)\r
4687                                                         ol = ' onreadystatechange="';\r
4688                                                 else\r
4689                                                         ol = ' onload="';\r
4691                                                 ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"';\r
4692                                         }\r
4694                                         document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"' + ol + '></script>');\r
4696                                         if (!o.func)\r
4697                                                 done(o);\r
4698                                 } else\r
4699                                         load(o);\r
4700                         });\r
4702                         allDone();\r
4703                 },\r
4705                 // Static methods\r
4706                 'static' : {\r
4707                         _addOnLoad : function(f) {\r
4708                                 var t = this;\r
4710                                 t._funcs = t._funcs || [];\r
4711                                 t._funcs.push(f);\r
4713                                 return t._funcs.length - 1;\r
4714                         },\r
4716                         _onLoad : function(e, u, ix) {\r
4717                                 if (!tinymce.isIE || e.readyState == 'complete')\r
4718                                         this._funcs[ix].call(this);\r
4719                         }\r
4720                 }\r
4722                 });\r
4724         // Global script loader\r
4725         tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();\r
4726 })();\r
4728 /* file:jscripts/tiny_mce/classes/ui/Control.js */\r
4730 (function() {\r
4731         // Shorten class names\r
4732         var DOM = tinymce.DOM, is = tinymce.is;\r
4734         tinymce.create('tinymce.ui.Control', {\r
4735                 Control : function(id, s) {\r
4736                         this.id = id;\r
4737                         this.settings = s = s || {};\r
4738                         this.rendered = false;\r
4739                         this.onRender = new tinymce.util.Dispatcher(this);\r
4740                         this.classPrefix = '';\r
4741                         this.scope = s.scope || this;\r
4742                         this.disabled = 0;\r
4743                         this.active = 0;\r
4744                 },\r
4746                 setDisabled : function(s) {\r
4747                         var e;\r
4749                         if (s != this.disabled) {\r
4750                                 e = DOM.get(this.id);\r
4752                                 // Add accessibility title for unavailable actions\r
4753                                 if (e && this.settings.unavailable_prefix) {\r
4754                                         if (s) {\r
4755                                                 this.prevTitle = e.title;\r
4756                                                 e.title = this.settings.unavailable_prefix + ": " + e.title;\r
4757                                         } else\r
4758                                                 e.title = this.prevTitle;\r
4759                                 }\r
4761                                 this.setState('Disabled', s);\r
4762                                 this.setState('Enabled', !s);\r
4763                                 this.disabled = s;\r
4764                         }\r
4765                 },\r
4767                 isDisabled : function() {\r
4768                         return this.disabled;\r
4769                 },\r
4771                 setActive : function(s) {\r
4772                         if (s != this.active) {\r
4773                                 this.setState('Active', s);\r
4774                                 this.active = s;\r
4775                         }\r
4776                 },\r
4778                 isActive : function() {\r
4779                         return this.active;\r
4780                 },\r
4782                 setState : function(c, s) {\r
4783                         var n = DOM.get(this.id);\r
4785                         c = this.classPrefix + c;\r
4787                         if (s)\r
4788                                 DOM.addClass(n, c);\r
4789                         else\r
4790                                 DOM.removeClass(n, c);\r
4791                 },\r
4793                 isRendered : function() {\r
4794                         return this.rendered;\r
4795                 },\r
4797                 renderHTML : function() {\r
4798                 },\r
4800                 renderTo : function(n) {\r
4801                         DOM.setHTML(n, this.renderHTML());\r
4802                 },\r
4804                 postRender : function() {\r
4805                         var t = this, b;\r
4807                         // Set pending states\r
4808                         if (is(t.disabled)) {\r
4809                                 b = t.disabled;\r
4810                                 t.disabled = -1;\r
4811                                 t.setDisabled(b);\r
4812                         }\r
4814                         if (is(t.active)) {\r
4815                                 b = t.active;\r
4816                                 t.active = -1;\r
4817                                 t.setActive(b);\r
4818                         }\r
4819                 },\r
4821                 remove : function() {\r
4822                         DOM.remove(this.id);\r
4823                         this.destroy();\r
4824                 },\r
4826                 destroy : function() {\r
4827                         tinymce.dom.Event.clear(this.id);\r
4828                 }\r
4830                 });\r
4831 })();\r
4832 /* file:jscripts/tiny_mce/classes/ui/Container.js */\r
4834 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {\r
4835         Container : function(id, s) {\r
4836                 this.parent(id, s);\r
4837                 this.controls = [];\r
4838                 this.lookup = {};\r
4839         },\r
4841         add : function(c) {\r
4842                 this.lookup[c.id] = c;\r
4843                 this.controls.push(c);\r
4845                 return c;\r
4846         },\r
4848         get : function(n) {\r
4849                 return this.lookup[n];\r
4850         }\r
4852         });\r
4855 /* file:jscripts/tiny_mce/classes/ui/Separator.js */\r
4857 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {\r
4858         Separator : function(id, s) {\r
4859                 this.parent(id, s);\r
4860                 this.classPrefix = 'mceSeparator';\r
4861         },\r
4863         renderHTML : function() {\r
4864                 return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});\r
4865         }\r
4867         });\r
4869 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */\r
4871 (function() {\r
4872         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
4874         tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {\r
4875                 MenuItem : function(id, s) {\r
4876                         this.parent(id, s);\r
4877                         this.classPrefix = 'mceMenuItem';\r
4878                 },\r
4880                 setSelected : function(s) {\r
4881                         this.setState('Selected', s);\r
4882                         this.selected = s;\r
4883                 },\r
4885                 isSelected : function() {\r
4886                         return this.selected;\r
4887                 },\r
4889                 postRender : function() {\r
4890                         var t = this;\r
4891                         \r
4892                         t.parent();\r
4894                         // Set pending state\r
4895                         if (is(t.selected))\r
4896                                 t.setSelected(t.selected);\r
4897                 }\r
4899                 });\r
4900 })();\r
4902 /* file:jscripts/tiny_mce/classes/ui/Menu.js */\r
4904 (function() {\r
4905         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
4907         tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {\r
4908                 Menu : function(id, s) {\r
4909                         var t = this;\r
4911                         t.parent(id, s);\r
4912                         t.items = {};\r
4913                         t.collapsed = false;\r
4914                         t.menuCount = 0;\r
4915                         t.onAddItem = new tinymce.util.Dispatcher(this);\r
4916                 },\r
4918                 expand : function(d) {\r
4919                         var t = this;\r
4921                         if (d) {\r
4922                                 walk(t, function(o) {\r
4923                                         if (o.expand)\r
4924                                                 o.expand();\r
4925                                 }, 'items', t);\r
4926                         }\r
4928                         t.collapsed = false;\r
4929                 },\r
4931                 collapse : function(d) {\r
4932                         var t = this;\r
4934                         if (d) {\r
4935                                 walk(t, function(o) {\r
4936                                         if (o.collapse)\r
4937                                                 o.collapse();\r
4938                                 }, 'items', t);\r
4939                         }\r
4941                         t.collapsed = true;\r
4942                 },\r
4944                 isCollapsed : function() {\r
4945                         return this.collapsed;\r
4946                 },\r
4948                 add : function(o) {\r
4949                         if (!o.settings)\r
4950                                 o = new tinymce.ui.MenuItem(o.id || DOM.uniqueId(), o);\r
4952                         this.onAddItem.dispatch(this, o);\r
4954                         return this.items[o.id] = o;\r
4955                 },\r
4957                 addSeparator : function() {\r
4958                         return this.add({separator : true});\r
4959                 },\r
4961                 addMenu : function(o) {\r
4962                         if (!o.collapse)\r
4963                                 o = this.createMenu(o);\r
4965                         this.menuCount++;\r
4967                         return this.add(o);\r
4968                 },\r
4970                 hasMenus : function() {\r
4971                         return this.menuCount !== 0;\r
4972                 },\r
4974                 remove : function(o) {\r
4975                         delete this.items[o.id];\r
4976                 },\r
4978                 removeAll : function() {\r
4979                         var t = this;\r
4981                         walk(t, function(o) {\r
4982                                 if (o.removeAll)\r
4983                                         o.removeAll();\r
4984                                 else\r
4985                                         o.remove();\r
4987                                 o.destroy();\r
4988                         }, 'items', t);\r
4990                         t.items = {};\r
4991                 },\r
4993                 createMenu : function(o) {\r
4994                         var m = new tinymce.ui.Menu(o.id || DOM.uniqueId(), o);\r
4996                         m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem);\r
4998                         return m;\r
4999                 }\r
5001                 });\r
5002 })();\r
5003 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */\r
5005 (function() {\r
5006         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;\r
5008         tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {\r
5009                 DropMenu : function(id, s) {\r
5010                         s = s || {};\r
5011                         s.container = s.container || DOM.doc.body;\r
5012                         s.offset_x = s.offset_x || 0;\r
5013                         s.offset_y = s.offset_y || 0;\r
5014                         s.vp_offset_x = s.vp_offset_x || 0;\r
5015                         s.vp_offset_y = s.vp_offset_y || 0;\r
5017                         if (is(s.icons) && !s.icons)\r
5018                                 s['class'] += ' mceNoIcons';\r
5020                         this.parent(id, s);\r
5021                         this.onShowMenu = new tinymce.util.Dispatcher(this);\r
5022                         this.onHideMenu = new tinymce.util.Dispatcher(this);\r
5023                         this.classPrefix = 'mceMenu';\r
5024                 },\r
5026                 createMenu : function(s) {\r
5027                         var t = this, cs = t.settings, m;\r
5029                         s.container = s.container || cs.container;\r
5030                         s.parent = t;\r
5031                         s.constrain = s.constrain || cs.constrain;\r
5032                         s['class'] = s['class'] || cs['class'];\r
5033                         s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x;\r
5034                         s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y;\r
5035                         m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s);\r
5037                         m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem);\r
5039                         return m;\r
5040                 },\r
5042                 update : function() {\r
5043                         var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;\r
5045                         tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth;\r
5046                         th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight;\r
5048                         if (!DOM.boxModel)\r
5049                                 t.element.setStyles({width : tw + 2, height : th + 2});\r
5050                         else\r
5051                                 t.element.setStyles({width : tw, height : th});\r
5053                         if (s.max_width)\r
5054                                 DOM.setStyle(co, 'width', tw);\r
5056                         if (s.max_height) {\r
5057                                 DOM.setStyle(co, 'height', th);\r
5059                                 if (tb.clientHeight < s.max_height)\r
5060                                         DOM.setStyle(co, 'overflow', 'hidden');\r
5061                         }\r
5062                 },\r
5064                 showMenu : function(x, y, px) {\r
5065                         var t = this, s = t.settings, co, vp = DOM.getViewPort(), w, h, mx, my, ot = 2, dm, tb, cp = t.classPrefix;\r
5067                         t.collapse(1);\r
5069                         if (t.isMenuVisible)\r
5070                                 return;\r
5072                         if (!t.rendered) {\r
5073                                 co = DOM.add(t.settings.container, t.renderNode());\r
5075                                 each(t.items, function(o) {\r
5076                                         o.postRender();\r
5077                                 });\r
5079                                 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
5080                         } else\r
5081                                 co = DOM.get('menu_' + t.id);\r
5083                         // Move layer out of sight unless it's Opera since it scrolls to top of page due to an bug\r
5084                         if (!tinymce.isOpera)\r
5085                                 DOM.setStyles(co, {left : -0xFFFF , top : -0xFFFF});\r
5087                         DOM.show(co);\r
5088                         t.update();\r
5090                         x += s.offset_x || 0;\r
5091                         y += s.offset_y || 0;\r
5092                         vp.w -= 4;\r
5093                         vp.h -= 4;\r
5095                         // Move inside viewport if not submenu\r
5096                         if (s.constrain) {\r
5097                                 w = co.clientWidth - ot;\r
5098                                 h = co.clientHeight - ot;\r
5099                                 mx = vp.x + vp.w;\r
5100                                 my = vp.y + vp.h;\r
5102                                 if ((x + s.vp_offset_x + w) > mx)\r
5103                                         x = px ? px - w : Math.max(0, (mx - s.vp_offset_x) - w);\r
5105                                 if ((y + s.vp_offset_y + h) > my)\r
5106                                         y = Math.max(0, (my - s.vp_offset_y) - h);\r
5107                         }\r
5109                         DOM.setStyles(co, {left : x , top : y});\r
5110                         t.element.update();\r
5112                         t.isMenuVisible = 1;\r
5113                         t.mouseClickFunc = Event.add(co, 'click', function(e) {\r
5114                                 var m;\r
5116                                 e = e.target;\r
5118                                 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) {\r
5119                                         m = t.items[e.id];\r
5121                                         if (m.isDisabled())\r
5122                                                 return;\r
5124                                         dm = t;\r
5126                                         while (dm) {\r
5127                                                 if (dm.hideMenu)\r
5128                                                         dm.hideMenu();\r
5130                                                 dm = dm.settings.parent;\r
5131                                         }\r
5133                                         if (m.settings.onclick)\r
5134                                                 m.settings.onclick(e);\r
5136                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem\r
5137                                 }\r
5138                         });\r
5140                         if (t.hasMenus()) {\r
5141                                 t.mouseOverFunc = Event.add(co, 'mouseover', function(e) {\r
5142                                         var m, r, mi;\r
5144                                         e = e.target;\r
5145                                         if (e && (e = DOM.getParent(e, 'TR'))) {\r
5146                                                 m = t.items[e.id];\r
5148                                                 if (t.lastMenu)\r
5149                                                         t.lastMenu.collapse(1);\r
5151                                                 if (m.isDisabled())\r
5152                                                         return;\r
5154                                                 if (e && DOM.hasClass(e, cp + 'ItemSub')) {\r
5155                                                         //p = DOM.getPos(s.container);\r
5156                                                         r = DOM.getRect(e);\r
5157                                                         m.showMenu((r.x + r.w - ot), r.y - ot, r.x);\r
5158                                                         t.lastMenu = m;\r
5159                                                         DOM.addClass(DOM.get(m.id).firstChild, cp + 'ItemActive');\r
5160                                                 }\r
5161                                         }\r
5162                                 });\r
5163                         }\r
5165                         t.onShowMenu.dispatch(t);\r
5167                         if (s.keyboard_focus) {\r
5168                                 Event.add(co, 'keydown', t._keyHandler, t);\r
5169                                 DOM.select('a', 'menu_' + t.id)[0].focus(); // Select first link\r
5170                                 t._focusIdx = 0;\r
5171                         }\r
5172                 },\r
5174                 hideMenu : function(c) {\r
5175                         var t = this, co = DOM.get('menu_' + t.id), e;\r
5177                         if (!t.isMenuVisible)\r
5178                                 return;\r
5180                         Event.remove(co, 'mouseover', t.mouseOverFunc);\r
5181                         Event.remove(co, 'click', t.mouseClickFunc);\r
5182                         Event.remove(co, 'keydown', t._keyHandler);\r
5183                         DOM.hide(co);\r
5184                         t.isMenuVisible = 0;\r
5186                         if (!c)\r
5187                                 t.collapse(1);\r
5189                         if (t.element)\r
5190                                 t.element.hide();\r
5192                         if (e = DOM.get(t.id))\r
5193                                 DOM.removeClass(e.firstChild, t.classPrefix + 'ItemActive');\r
5195                         t.onHideMenu.dispatch(t);\r
5196                 },\r
5198                 add : function(o) {\r
5199                         var t = this, co;\r
5201                         o = t.parent(o);\r
5203                         if (t.isRendered && (co = DOM.get('menu_' + t.id)))\r
5204                                 t._add(DOM.select('tbody', co)[0], o);\r
5206                         return o;\r
5207                 },\r
5209                 collapse : function(d) {\r
5210                         this.parent(d);\r
5211                         this.hideMenu(1);\r
5212                 },\r
5214                 remove : function(o) {\r
5215                         DOM.remove(o.id);\r
5216                         this.destroy();\r
5218                         return this.parent(o);\r
5219                 },\r
5221                 destroy : function() {\r
5222                         var t = this, co = DOM.get('menu_' + t.id);\r
5224                         Event.remove(co, 'mouseover', t.mouseOverFunc);\r
5225                         Event.remove(co, 'click', t.mouseClickFunc);\r
5227                         if (t.element)\r
5228                                 t.element.remove();\r
5230                         DOM.remove(co);\r
5231                 },\r
5233                 renderNode : function() {\r
5234                         var t = this, s = t.settings, n, tb, co, w;\r
5236                         w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:200000'});\r
5237                         co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : t.classPrefix + (s['class'] ? ' ' + s['class'] : '')});\r
5238                         t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
5240                         if (s.menu_line)\r
5241                                 DOM.add(co, 'span', {'class' : t.classPrefix + 'Line'});\r
5243 //                      n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'});\r
5244                         n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0});\r
5245                         tb = DOM.add(n, 'tbody');\r
5247                         each(t.items, function(o) {\r
5248                                 t._add(tb, o);\r
5249                         });\r
5251                         t.rendered = true;\r
5253                         return w;\r
5254                 },\r
5256                 // Internal functions\r
5258                 _keyHandler : function(e) {\r
5259                         var t = this, kc = e.keyCode;\r
5261                         function focus(d) {\r
5262                                 var i = t._focusIdx + d, e = DOM.select('a', 'menu_' + t.id)[i];\r
5264                                 if (e) {\r
5265                                         t._focusIdx = i;\r
5266                                         e.focus();\r
5267                                 }\r
5268                         };\r
5270                         switch (kc) {\r
5271                                 case 38:\r
5272                                         focus(-1); // Select first link\r
5273                                         return;\r
5275                                 case 40:\r
5276                                         focus(1);\r
5277                                         return;\r
5279                                 case 13:\r
5280                                         return;\r
5282                                 case 27:\r
5283                                         return this.hideMenu();\r
5284                         }\r
5285                 },\r
5287                 _add : function(tb, o) {\r
5288                         var n, s = o.settings, a, ro, it, cp = this.classPrefix;\r
5290                         if (s.separator) {\r
5291                                 ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'ItemSeparator'});\r
5292                                 DOM.add(ro, 'td', {'class' : cp + 'ItemSeparator'});\r
5294                                 if (n = ro.previousSibling)\r
5295                                         DOM.addClass(n, 'mceLast');\r
5297                                 return;\r
5298                         }\r
5300                         n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'Item ' + cp + 'ItemEnabled'});\r
5301                         n = it = DOM.add(n, 'td');\r
5302                         n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});\r
5304                         DOM.addClass(it, s['class']);\r
5305 //                      n = DOM.add(n, 'span', {'class' : 'item'});\r
5306                         DOM.add(n, 'span', {'class' : 'mceIcon' + (s.icon ? ' mce_' + s.icon : '')});\r
5307                         n = DOM.add(n, s.element || 'span', {'class' : 'mceText', title : o.settings.title}, o.settings.title);\r
5309                         if (o.settings.style)\r
5310                                 DOM.setAttrib(n, 'style', o.settings.style);\r
5312                         if (tb.childNodes.length == 1)\r
5313                                 DOM.addClass(ro, 'mceFirst');\r
5315                         if ((n = ro.previousSibling) && DOM.hasClass(n, cp + 'ItemSeparator'))\r
5316                                 DOM.addClass(ro, 'mceFirst');\r
5318                         if (o.collapse)\r
5319                                 DOM.addClass(ro, cp + 'ItemSub');\r
5321                         if (n = ro.previousSibling)\r
5322                                 DOM.removeClass(n, 'mceLast');\r
5324                         DOM.addClass(ro, 'mceLast');\r
5325                 }\r
5327                 });\r
5328 })();\r
5329 /* file:jscripts/tiny_mce/classes/ui/Button.js */\r
5331 (function() {\r
5332         var DOM = tinymce.DOM;\r
5334         tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {\r
5335                 Button : function(id, s) {\r
5336                         this.parent(id, s);\r
5337                         this.classPrefix = 'mceButton';\r
5338                 },\r
5340                 renderHTML : function() {\r
5341                         var cp = this.classPrefix, s = this.settings, h, l;\r
5343                         l = DOM.encode(s.label || '');\r
5344                         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
5346                         if (s.image)\r
5347                                 h += '<img class="mceIcon" src="' + s.image + '" />' + l + '</a>';\r
5348                         else\r
5349                                 h += '<span class="mceIcon ' + s['class'] + '"></span>' + (l ? '<span class="' + cp + 'Label">' + l + '</span>' : '') + '</a>';\r
5351                         return h;\r
5352                 },\r
5354                 postRender : function() {\r
5355                         var t = this, s = t.settings;\r
5357                         tinymce.dom.Event.add(t.id, 'click', function(e) {\r
5358                                 if (!t.isDisabled())\r
5359                                         return s.onclick.call(s.scope, e);\r
5360                         });\r
5361                 }\r
5363                 });\r
5364 })();\r
5366 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */\r
5368 (function() {\r
5369         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
5371         tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {\r
5372                 ListBox : function(id, s) {\r
5373                         var t = this;\r
5375                         t.parent(id, s);\r
5376                         t.items = [];\r
5377                         t.onChange = new Dispatcher(t);\r
5378                         t.onPostRender = new Dispatcher(t);\r
5379                         t.onAdd = new Dispatcher(t);\r
5380                         t.onRenderMenu = new tinymce.util.Dispatcher(this);\r
5381                         t.classPrefix = 'mceListBox';\r
5382                 },\r
5384                 select : function(v) {\r
5385                         var t = this, e, fv;\r
5387                         // Do we need to do something?\r
5388                         if (v != t.selectedValue) {\r
5389                                 e = DOM.get(t.id + '_text');\r
5390                                 t.selectedValue = v;\r
5392                                 // Find item\r
5393                                 each(t.items, function(o) {\r
5394                                         if (o.value == v) {\r
5395                                                 DOM.setHTML(e, DOM.encode(o.title));\r
5396                                                 fv = 1;\r
5397                                                 return false;\r
5398                                         }\r
5399                                 });\r
5401                                 // If no item was found then present title\r
5402                                 if (!fv) {\r
5403                                         DOM.setHTML(e, DOM.encode(t.settings.title));\r
5404                                         DOM.addClass(e, 'mceTitle');\r
5405                                         e = 0;\r
5406                                         return;\r
5407                                 } else\r
5408                                         DOM.removeClass(e, 'mceTitle');\r
5409                         }\r
5411                         e = 0;\r
5412                 },\r
5414                 add : function(n, v, o) {\r
5415                         var t = this;\r
5417                         o = o || {};\r
5418                         o = tinymce.extend(o, {\r
5419                                 title : n,\r
5420                                 value : v\r
5421                         });\r
5423                         t.items.push(o);\r
5424                         t.onAdd.dispatch(t, o);\r
5425                 },\r
5427                 getLength : function() {\r
5428                         return this.items.length;\r
5429                 },\r
5431                 renderHTML : function() {\r
5432                         var h = '', t = this, s = t.settings, cp = t.classPrefix;\r
5434                         h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="' + cp + ' ' + cp + 'Enabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';\r
5435                         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
5436                         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
5437                         h += '</tr></tbody></table>';\r
5439                         return h;\r
5440                 },\r
5442                 showMenu : function() {\r
5443                         var t = this, p1, p2, e = DOM.get(this.id), m;\r
5445                         if (t.isDisabled() || t.items.length == 0)\r
5446                                 return;\r
5448                         if (t.menu && t.menu.isMenuVisible)\r
5449                                 return t.hideMenu();\r
5451                         if (!t.isMenuRendered) {\r
5452                                 t.renderMenu();\r
5453                                 t.isMenuRendered = true;\r
5454                         }\r
5456                         p1 = DOM.getPos(this.settings.menu_container);\r
5457                         p2 = DOM.getPos(e);\r
5459                         m = t.menu;\r
5460                         m.settings.offset_x = p2.x;\r
5461                         m.settings.offset_y = p2.y;\r
5462                         m.settings.keyboard_focus = !tinymce.isOpera; // Opera is buggy when it comes to auto focus\r
5464                         // Select in menu\r
5465                         if (t.oldID)\r
5466                                 m.items[t.oldID].setSelected(0);\r
5468                         each(t.items, function(o) {\r
5469                                 if (o.value === t.selectedValue) {\r
5470                                         m.items[o.id].setSelected(1);\r
5471                                         t.oldID = o.id;\r
5472                                 }\r
5473                         });\r
5475                         m.showMenu(0, e.clientHeight);\r
5477                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5478                         DOM.addClass(t.id, t.classPrefix + 'Selected');\r
5480                         //DOM.get(t.id + '_text').focus();\r
5481                 },\r
5483                 hideMenu : function(e) {\r
5484                         var t = this;\r
5486                         // Prevent double toogles by canceling the mouse click event to the button\r
5487                         if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))\r
5488                                 return;\r
5490                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
5491                                 DOM.removeClass(t.id, t.classPrefix + 'Selected');\r
5492                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5494                                 if (t.menu)\r
5495                                         t.menu.hideMenu();\r
5496                         }\r
5497                 },\r
5499                 renderMenu : function() {\r
5500                         var t = this, m;\r
5502                         m = t.settings.control_manager.createDropMenu(t.id + '_menu', {\r
5503                                 menu_line : 1,\r
5504                                 'class' : t.classPrefix + 'Menu mceNoIcons',\r
5505                                 max_width : 150,\r
5506                                 max_height : 150\r
5507                         });\r
5509                         m.onHideMenu.add(t.hideMenu, t);\r
5511                         m.add({\r
5512                                 title : t.settings.title,\r
5513                                 'class' : 'mceMenuItemTitle',\r
5514                                 onclick : function() {\r
5515                                         if (t.settings.onselect('') !== false)\r
5516                                                 t.select(''); // Must be runned after\r
5517                                 }\r
5518                         });\r
5520                         each(t.items, function(o) {\r
5521                                 o.id = DOM.uniqueId();\r
5522                                 o.onclick = function() {\r
5523                                         if (t.settings.onselect(o.value) !== false)\r
5524                                                 t.select(o.value); // Must be runned after\r
5525                                 };\r
5527                                 m.add(o);\r
5528                         });\r
5530                         t.onRenderMenu.dispatch(t, m);\r
5531                         t.menu = m;\r
5532                 },\r
5534                 postRender : function() {\r
5535                         var t = this, cp = t.classPrefix;\r
5537                         Event.add(t.id, 'click', t.showMenu, t);\r
5538                         Event.add(t.id + '_text', 'focus', function(e) {\r
5539                                 if (!t._focused) {\r
5540                                         t.keyDownHandler = Event.add(t.id + '_text', 'keydown', function(e) {\r
5541                                                 var idx = -1, v, kc = e.keyCode;\r
5543                                                 // Find current index\r
5544                                                 each(t.items, function(v, i) {\r
5545                                                         if (t.selectedValue == v.value)\r
5546                                                                 idx = i;\r
5547                                                 });\r
5549                                                 // Move up/down\r
5550                                                 if (kc == 38)\r
5551                                                         v = t.items[idx - 1];\r
5552                                                 else if (kc == 40)\r
5553                                                         v = t.items[idx + 1];\r
5554                                                 else if (kc == 13) {\r
5555                                                         // Fake select on enter\r
5556                                                         v = t.selectedValue;\r
5557                                                         t.selectedValue = null; // Needs to be null to fake change\r
5558                                                         t.settings.onselect(v);\r
5559                                                         return Event.cancel(e);\r
5560                                                 }\r
5562                                                 if (v) {\r
5563                                                         t.hideMenu();\r
5564                                                         t.select(v.value);\r
5565                                                 }\r
5566                                         });\r
5567                                 }\r
5569                                 t._focused = 1;\r
5570                         });\r
5571                         Event.add(t.id + '_text', 'blur', function() {Event.remove(t.id + '_text', 'keydown', t.keyDownHandler); t._focused = 0;});\r
5573                         // Old IE doesn't have hover on all elements\r
5574                         if (tinymce.isIE6 || !DOM.boxModel) {\r
5575                                 Event.add(t.id, 'mouseover', function() {\r
5576                                         if (!DOM.hasClass(t.id, cp + 'Disabled'))\r
5577                                                 DOM.addClass(t.id, cp + 'Hover');\r
5578                                 });\r
5580                                 Event.add(t.id, 'mouseout', function() {\r
5581                                         if (!DOM.hasClass(t.id, cp + 'Disabled'))\r
5582                                                 DOM.removeClass(t.id, cp + 'Hover');\r
5583                                 });\r
5584                         }\r
5586                         t.onPostRender.dispatch(t, DOM.get(t.id));\r
5587                 },\r
5589                 destroy : function() {\r
5590                         this.parent();\r
5592                         Event.clear(this.id + '_text');\r
5593                 }\r
5595                 });\r
5596 })();\r
5597 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */\r
5599 (function() {\r
5600         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
5602         tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {\r
5603                 NativeListBox : function(id, s) {\r
5604                         this.parent(id, s);\r
5605                         this.classPrefix = 'mceNativeListBox';\r
5606                 },\r
5608                 setDisabled : function(s) {\r
5609                         DOM.get(this.id).disabled = s;\r
5610                 },\r
5612                 isDisabled : function() {\r
5613                         return DOM.get(this.id).disabled;\r
5614                 },\r
5616                 select : function(v) {\r
5617                         var e = DOM.get(this.id), ol = e.options;\r
5619                         v = '' + (v || '');\r
5621                         e.selectedIndex = 0;\r
5622                         each(ol, function(o, i) {\r
5623                                 if (o.value == v) {\r
5624                                         e.selectedIndex = i;\r
5625                                         return false;\r
5626                                 }\r
5627                         });\r
5628                 },\r
5630                 add : function(n, v, a) {\r
5631                         var o, t = this;\r
5633                         a = a || {};\r
5634                         a.value = v;\r
5636                         if (t.isRendered())\r
5637                                 DOM.add(DOM.get(this.id), 'option', a, n);\r
5639                         o = {\r
5640                                 title : n,\r
5641                                 value : v,\r
5642                                 attribs : a\r
5643                         };\r
5645                         t.items.push(o);\r
5646                         t.onAdd.dispatch(t, o);\r
5647                 },\r
5649                 getLength : function() {\r
5650                         return DOM.get(this.id).options.length - 1;\r
5651                 },\r
5653                 renderHTML : function() {\r
5654                         var h, t = this;\r
5656                         h = DOM.createHTML('option', {value : ''}, '-- ' + t.settings.title + ' --');\r
5658                         each(t.items, function(it) {\r
5659                                 h += DOM.createHTML('option', {value : it.value}, it.title);\r
5660                         });\r
5662                         h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h);\r
5664                         return h;\r
5665                 },\r
5667                 postRender : function() {\r
5668                         var t = this, ch;\r
5670                         t.rendered = true;\r
5672                         function onChange(e) {\r
5673                                 var v = e.target.options[e.target.selectedIndex].value;\r
5675                                 t.onChange.dispatch(t, v);\r
5677                                 if (t.settings.onselect)\r
5678                                         t.settings.onselect(v);\r
5679                         };\r
5681                         Event.add(t.id, 'change', onChange);\r
5683                         // Accessibility keyhandler\r
5684                         Event.add(t.id, 'keydown', function(e) {\r
5685                                 var bf;\r
5687                                 Event.remove(t.id, 'change', ch);\r
5689                                 bf = Event.add(t.id, 'blur', function() {\r
5690                                         Event.add(t.id, 'change', onChange);\r
5691                                         Event.remove(t.id, 'blur', bf);\r
5692                                 });\r
5694                                 if (e.keyCode == 13 || e.keyCode == 32) {\r
5695                                         onChange(e);\r
5696                                         return Event.cancel(e);\r
5697                                 }\r
5698                         });\r
5700                         t.onPostRender.dispatch(t, DOM.get(t.id));\r
5701                 }\r
5703                 });\r
5704 })();\r
5705 /* file:jscripts/tiny_mce/classes/ui/MenuButton.js */\r
5707 (function() {\r
5708         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
5710         tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {\r
5711                 MenuButton : function(id, s) {\r
5712                         this.parent(id, s);\r
5713                         this.onRenderMenu = new tinymce.util.Dispatcher(this);\r
5714                         s.menu_container = s.menu_container || DOM.doc.body;\r
5715                 },\r
5717                 showMenu : function() {\r
5718                         var t = this, p1, p2, e = DOM.get(t.id), m;\r
5720                         if (t.isDisabled())\r
5721                                 return;\r
5723                         if (!t.isMenuRendered) {\r
5724                                 t.renderMenu();\r
5725                                 t.isMenuRendered = true;\r
5726                         }\r
5728                         if (t.isMenuVisible)\r
5729                                 return t.hideMenu();\r
5731                         p1 = DOM.getPos(t.settings.menu_container);\r
5732                         p2 = DOM.getPos(e);\r
5734                         m = t.menu;\r
5735                         m.settings.offset_x = p2.x;\r
5736                         m.settings.offset_y = p2.y;\r
5737                         m.settings.vp_offset_x = p2.x;\r
5738                         m.settings.vp_offset_y = p2.y;\r
5739                         m.settings.keyboard_focus = t._focused;\r
5740                         m.showMenu(0, e.clientHeight);\r
5742                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5743                         t.setState('Selected', 1);\r
5745                         t.isMenuVisible = 1;\r
5746                 },\r
5748                 renderMenu : function() {\r
5749                         var t = this, m;\r
5751                         m = t.settings.control_manager.createDropMenu(t.id + '_menu', {\r
5752                                 menu_line : 1,\r
5753                                 'class' : this.classPrefix + 'Menu',\r
5754                                 icons : t.settings.icons\r
5755                         });\r
5757                         m.onHideMenu.add(t.hideMenu, t);\r
5759                         t.onRenderMenu.dispatch(t, m);\r
5760                         t.menu = m;\r
5761                 },\r
5763                 hideMenu : function(e) {\r
5764                         var t = this;\r
5766                         // Prevent double toogles by canceling the mouse click event to the button\r
5767                         if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id || e.id === t.id + '_open';}))\r
5768                                 return;\r
5770                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
5771                                 t.setState('Selected', 0);\r
5772                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5773                                 if (t.menu)\r
5774                                         t.menu.hideMenu();\r
5775                         }\r
5777                         t.isMenuVisible = 0;\r
5778                 },\r
5780                 postRender : function() {\r
5781                         var t = this, s = t.settings;\r
5783                         Event.add(t.id, 'click', function() {\r
5784                                 if (!t.isDisabled()) {\r
5785                                         if (s.onclick)\r
5786                                                 s.onclick(t.value);\r
5788                                         t.showMenu();\r
5789                                 }\r
5790                         });\r
5791                 }\r
5793                 });\r
5794 })();\r
5796 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */\r
5798 (function() {\r
5799         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
5801         tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {\r
5802                 SplitButton : function(id, s) {\r
5803                         this.parent(id, s);\r
5804                         this.classPrefix = 'mceSplitButton';\r
5805                 },\r
5807                 renderHTML : function() {\r
5808                         var h, t = this, s = t.settings, h1;\r
5810                         h = '<tbody><tr>';\r
5812                         if (s.image)\r
5813                                 h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'mceAction ' + s['class']});\r
5814                         else\r
5815                                 h1 = DOM.createHTML('span', {'class' : 'mceAction ' + s['class']}, '');\r
5817                         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
5818         \r
5819                         h1 = DOM.createHTML('span', {'class' : 'mceOpen ' + s['class']});\r
5820                         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
5822                         h += '</tr></tbody>';\r
5824                         return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);\r
5825                 },\r
5827                 postRender : function() {\r
5828                         var t = this, s = t.settings;\r
5830                         if (s.onclick) {\r
5831                                 Event.add(t.id + '_action', 'click', function() {\r
5832                                         if (!t.isDisabled())\r
5833                                                 s.onclick(t.value);\r
5834                                 });\r
5835                         }\r
5837                         Event.add(t.id + '_open', 'click', t.showMenu, t);\r
5838                         Event.add(t.id + '_open', 'focus', function() {t._focused = 1;});\r
5839                         Event.add(t.id + '_open', 'blur', function() {t._focused = 0;});\r
5841                         // Old IE doesn't have hover on all elements\r
5842                         if (tinymce.isIE6 || !DOM.boxModel) {\r
5843                                 Event.add(t.id, 'mouseover', function() {\r
5844                                         if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))\r
5845                                                 DOM.addClass(t.id, 'mceSplitButtonHover');\r
5846                                 });\r
5848                                 Event.add(t.id, 'mouseout', function() {\r
5849                                         if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))\r
5850                                                 DOM.removeClass(t.id, 'mceSplitButtonHover');\r
5851                                 });\r
5852                         }\r
5853                 },\r
5855                 destroy : function() {\r
5856                         this.parent();\r
5858                         Event.clear(this.id + '_action');\r
5859                         Event.clear(this.id + '_open');\r
5860                 }\r
5862                 });\r
5863 })();\r
5865 /* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */\r
5867 (function() {\r
5868         var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;\r
5870         tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {\r
5871                 ColorSplitButton : function(id, s) {\r
5872                         var t = this;\r
5874                         t.parent(id, s);\r
5876                         t.settings = s = tinymce.extend({\r
5877                                 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
5878                                 grid_width : 8,\r
5879                                 default_color : '#888888'\r
5880                         }, t.settings);\r
5882                         t.onShowMenu = new tinymce.util.Dispatcher(t);\r
5883                         t.onHideMenu = new tinymce.util.Dispatcher(t);\r
5885                         t.value = s.default_color;\r
5886                 },\r
5888                 showMenu : function() {\r
5889                         var t = this, r, p, e, p2;\r
5891                         if (t.isDisabled())\r
5892                                 return;\r
5894                         if (!t.isMenuRendered) {\r
5895                                 t.renderMenu();\r
5896                                 t.isMenuRendered = true;\r
5897                         }\r
5899                         if (t.isMenuVisible)\r
5900                                 return t.hideMenu();\r
5902                         e = DOM.get(t.id);\r
5903                         DOM.show(t.id + '_menu');\r
5904                         DOM.addClass(e, 'mceSplitButtonSelected');\r
5905                         p2 = DOM.getPos(e);\r
5906                         DOM.setStyles(t.id + '_menu', {\r
5907                                 left : p2.x,\r
5908                                 top : p2.y + e.clientHeight,\r
5909                                 zIndex : 200000\r
5910                         });\r
5911                         e = 0;\r
5913                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5915                         if (t._focused) {\r
5916                                 t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {\r
5917                                         if (e.keyCode == 27)\r
5918                                                 t.hideMenu();\r
5919                                 });\r
5921                                 DOM.select('a', t.id + '_menu')[0].focus(); // Select first link\r
5922                         }\r
5924                         t.onShowMenu.dispatch(t);\r
5926                         t.isMenuVisible = 1;\r
5927                 },\r
5929                 hideMenu : function(e) {\r
5930                         var t = this;\r
5932                         // Prevent double toogles by canceling the mouse click event to the button\r
5933                         if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))\r
5934                                 return;\r
5936                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {\r
5937                                 DOM.removeClass(t.id, 'mceSplitButtonSelected');\r
5938                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5939                                 Event.remove(t.id + '_menu', 'keydown', t._keyHandler);\r
5940                                 DOM.hide(t.id + '_menu');\r
5941                         }\r
5943                         t.onHideMenu.dispatch(t);\r
5945                         t.isMenuVisible = 0;\r
5946                 },\r
5948                 renderMenu : function() {\r
5949                         var t = this, m, i = 0, s = t.settings, n, tb, tr, w;\r
5951                         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
5952                         m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});\r
5953                         DOM.add(m, 'span', {'class' : 'mceMenuLine'});\r
5955                         n = DOM.add(m, 'table', {'class' : 'mceColorSplitMenu'});\r
5956                         tb = DOM.add(n, 'tbody');\r
5958                         // Generate color grid\r
5959                         i = 0;\r
5960                         each(is(s.colors, 'array') ? s.colors : s.colors.split(','), function(c) {\r
5961                                 c = c.replace(/^#/, '');\r
5963                                 if (!i--) {\r
5964                                         tr = DOM.add(tb, 'tr');\r
5965                                         i = s.grid_width - 1;\r
5966                                 }\r
5968                                 n = DOM.add(tr, 'td');\r
5970                                 n = DOM.add(n, 'a', {\r
5971                                         href : 'javascript:;',\r
5972                                         style : {\r
5973                                                 backgroundColor : '#' + c\r
5974                                         },\r
5975                                         mce_color : '#' + c\r
5976                                 });\r
5977                         });\r
5979                         if (s.more_colors_func) {\r
5980                                 n = DOM.add(tb, 'tr');\r
5981                                 n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'mceMoreColors'});\r
5982                                 n = DOM.add(n, 'a', {id : t.id + '_more', href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);\r
5984                                 Event.add(n, 'click', function(e) {\r
5985                                         s.more_colors_func.call(s.more_colors_scope || this);\r
5986                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem\r
5987                                 });\r
5988                         }\r
5990                         DOM.addClass(m, 'mceColorSplitMenu');\r
5992                         Event.add(t.id + '_menu', 'click', function(e) {\r
5993                                 var c;\r
5995                                 e = e.target;\r
5997                                 if (e.nodeName == 'A' && (c = e.getAttribute('mce_color')))\r
5998                                         t.setColor(c);\r
6000                                 return Event.cancel(e); // Prevent IE auto save warning\r
6001                         });\r
6003                         return w;\r
6004                 },\r
6006                 setColor : function(c) {\r
6007                         var t = this;\r
6009                         DOM.setStyle(t.id + '_preview', 'backgroundColor', c);\r
6011                         t.value = c;\r
6012                         t.hideMenu();\r
6013                         t.settings.onselect(c);\r
6014                 },\r
6016                 postRender : function() {\r
6017                         var t = this, id = t.id;\r
6019                         t.parent();\r
6020                         DOM.add(id + '_action', 'div', {id : id + '_preview', 'class' : 'mceColorPreview'});\r
6021                 },\r
6023                 destroy : function() {\r
6024                         this.parent();\r
6026                         Event.clear(this.id + '_menu');\r
6027                         Event.clear(this.id + '_more');\r
6028                         DOM.remove(this.id + '_menu');\r
6029                 }\r
6031                 });\r
6032 })();\r
6034 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */\r
6036 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {\r
6037         renderHTML : function() {\r
6038                 var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl;\r
6040                 cl = t.controls;\r
6041                 for (i=0; i<cl.length; i++) {\r
6042                         // Get current control, prev control, next control and if the control is a list box or not\r
6043                         co = cl[i];\r
6044                         pr = cl[i - 1];\r
6045                         nx = cl[i + 1];\r
6047                         // Add toolbar start\r
6048                         if (i === 0) {\r
6049                                 c = 'mceToolbarStart';\r
6051                                 if (co.Button)\r
6052                                         c += ' mceToolbarStartButton';\r
6053                                 else if (co.SplitButton)\r
6054                                         c += ' mceToolbarStartSplitButton';\r
6055                                 else if (co.ListBox)\r
6056                                         c += ' mceToolbarStartListBox';\r
6058                                 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
6059                         }\r
6061                         // Add toolbar end before list box and after the previous button\r
6062                         // This is to fix the o2k7 editor skins\r
6063                         if (pr && co.ListBox) {\r
6064                                 if (pr.Button || pr.SplitButton)\r
6065                                         h += dom.createHTML('td', {'class' : 'mceToolbarEnd'}, dom.createHTML('span', null, '<!-- IE -->'));\r
6066                         }\r
6068                         // Render control HTML\r
6070                         // IE 8 quick fix, needed to propertly generate a hit area for anchors\r
6071                         if (dom.stdMode)\r
6072                                 h += '<td style="position: relative">' + co.renderHTML() + '</td>';\r
6073                         else\r
6074                                 h += '<td>' + co.renderHTML() + '</td>';\r
6076                         // Add toolbar start after list box and before the next button\r
6077                         // This is to fix the o2k7 editor skins\r
6078                         if (nx && co.ListBox) {\r
6079                                 if (nx.Button || nx.SplitButton)\r
6080                                         h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->'));\r
6081                         }\r
6082                 }\r
6084                 c = 'mceToolbarEnd';\r
6086                 if (co.Button)\r
6087                         c += ' mceToolbarEndButton';\r
6088                 else if (co.SplitButton)\r
6089                         c += ' mceToolbarEndSplitButton';\r
6090                 else if (co.ListBox)\r
6091                         c += ' mceToolbarEndListBox';\r
6093                 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
6095                 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
6096         }\r
6098         });\r
6100 /* file:jscripts/tiny_mce/classes/AddOnManager.js */\r
6102 (function() {\r
6103         var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;\r
6105         tinymce.create('tinymce.AddOnManager', {\r
6106                 items : [],\r
6107                 urls : {},\r
6108                 lookup : {},\r
6109                 onAdd : new Dispatcher(this),\r
6111                 get : function(n) {\r
6112                         return this.lookup[n];\r
6113                 },\r
6115                 requireLangPack : function(n) {\r
6116                         var u, s = tinymce.EditorManager.settings;\r
6118                         if (s && s.language) {\r
6119                                 u = this.urls[n] + '/langs/' + s.language + '.js';\r
6121                                 if (!tinymce.dom.Event.domLoaded && !s.strict_mode)\r
6122                                         tinymce.ScriptLoader.load(u);\r
6123                                 else\r
6124                                         tinymce.ScriptLoader.add(u);\r
6125                         }\r
6126                 },\r
6128                 add : function(id, o) {\r
6129                         this.items.push(o);\r
6130                         this.lookup[id] = o;\r
6131                         this.onAdd.dispatch(this, id, o);\r
6133                         return o;\r
6134                 },\r
6136                 load : function(n, u, cb, s) {\r
6137                         var t = this;\r
6139                         if (t.urls[n])\r
6140                                 return;\r
6142                         if (u.indexOf('/') != 0 && u.indexOf('://') == -1)\r
6143                                 u = tinymce.baseURL + '/' +  u;\r
6145                         t.urls[n] = u.substring(0, u.lastIndexOf('/'));\r
6146                         tinymce.ScriptLoader.add(u, cb, s);\r
6147                 }\r
6149                 });\r
6151         // Create plugin and theme managers\r
6152         tinymce.PluginManager = new tinymce.AddOnManager();\r
6153         tinymce.ThemeManager = new tinymce.AddOnManager();\r
6154 }());\r
6155 /* file:jscripts/tiny_mce/classes/EditorManager.js */\r
6157 (function() {\r
6158         // Shorten names\r
6159         var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;\r
6161         tinymce.create('static tinymce.EditorManager', {\r
6162                 editors : {},\r
6163                 i18n : {},\r
6164                 activeEditor : null,\r
6166                 preInit : function() {\r
6167                         var t = this, lo = window.location;\r
6169                         // Setup some URLs where the editor API is located and where the document is\r
6170                         tinymce.documentBaseURL = lo.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');\r
6171                         if (!/[\/\\]$/.test(tinymce.documentBaseURL))\r
6172                                 tinymce.documentBaseURL += '/';\r
6174                         tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);\r
6175                         tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);\r
6177                         // User already specified a document.domain value\r
6178                         if (document.domain && lo.hostname != document.domain)\r
6179                                 tinymce.relaxedDomain = document.domain;\r
6181                         // Setup document domain if tinymce is loaded from other domain\r
6182                         if (!tinymce.relaxedDomain && tinymce.EditorManager.baseURI.host != lo.hostname && lo.hostname)\r
6183                                 document.domain = tinymce.relaxedDomain = lo.hostname.replace(/.*\.(.+\..+)$/, '$1');\r
6185                         // Add before unload listener\r
6186                         // This was required since IE was leaking memory if you added and removed beforeunload listeners\r
6187                         // with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event\r
6188                         t.onBeforeUnload = new tinymce.util.Dispatcher(t);\r
6190                         // Must be on window or IE will leak if the editor is placed in frame or iframe\r
6191                         Event.add(window, 'beforeunload', function(e) {\r
6192                                 t.onBeforeUnload.dispatch(t, e);\r
6193                         });\r
6194                 },\r
6196                 init : function(s) {\r
6197                         var t = this, pl, sl = tinymce.ScriptLoader, c, e, el = [], ed;\r
6199                         function execCallback(se, n, s) {\r
6200                                 var f = se[n];\r
6202                                 if (!f)\r
6203                                         return;\r
6205                                 if (tinymce.is(f, 'string')) {\r
6206                                         s = f.replace(/\.\w+$/, '');\r
6207                                         s = s ? tinymce.resolve(s) : 0;\r
6208                                         f = tinymce.resolve(f);\r
6209                                 }\r
6211                                 return f.apply(s || this, Array.prototype.slice.call(arguments, 2));\r
6212                         };\r
6214                         s = extend({\r
6215                                 theme : "simple",\r
6216                                 language : "en",\r
6217                                 strict_loading_mode : document.contentType == 'application/xhtml+xml'\r
6218                         }, s);\r
6220                         t.settings = s;\r
6222                         // If page not loaded and strict mode isn't enabled then load them\r
6223                         if (!Event.domLoaded && !s.strict_loading_mode) {\r
6224                                 // Load language\r
6225                                 if (s.language)\r
6226                                         sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
6228                                 // Load theme\r
6229                                 if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
6230                                         ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
6232                                 // Load plugins\r
6233                                 if (s.plugins) {\r
6234                                         pl = explode(s.plugins);\r
6236                                         // Load compat2x first\r
6237                                         if (tinymce.inArray(pl, 'compat2x') != -1)\r
6238                                                 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');\r
6240                                         // Load rest if plugins\r
6241                                         each(pl, function(v) {\r
6242                                                 if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) {\r
6243                                                         // Skip safari plugin for other browsers\r
6244                                                         if (!tinymce.isWebKit && v == 'safari')\r
6245                                                                 return;\r
6247                                                         PluginManager.load(v, 'plugins/' + v + '/editor_plugin' + tinymce.suffix + '.js');\r
6248                                                 }\r
6249                                         });\r
6250                                 }\r
6252                                 sl.loadQueue();\r
6253                         }\r
6255                         // Legacy call\r
6256                         Event.add(document, 'init', function() {\r
6257                                 var l, co;\r
6259                                 execCallback(s, 'onpageload');\r
6261                                 // Verify that it's a valid browser\r
6262                                 if (s.browsers) {\r
6263                                         l = false;\r
6265                                         each(explode(s.browsers), function(v) {\r
6266                                                 switch (v) {\r
6267                                                         case 'ie':\r
6268                                                         case 'msie':\r
6269                                                                 if (tinymce.isIE)\r
6270                                                                         l = true;\r
6271                                                                 break;\r
6273                                                         case 'gecko':\r
6274                                                                 if (tinymce.isGecko)\r
6275                                                                         l = true;\r
6276                                                                 break;\r
6278                                                         case 'safari':\r
6279                                                         case 'webkit':\r
6280                                                                 if (tinymce.isWebKit)\r
6281                                                                         l = true;\r
6282                                                                 break;\r
6284                                                         case 'opera':\r
6285                                                                 if (tinymce.isOpera)\r
6286                                                                         l = true;\r
6288                                                                 break;\r
6289                                                 }\r
6290                                         });\r
6292                                         // Not a valid one\r
6293                                         if (!l)\r
6294                                                 return;\r
6295                                 }\r
6297                                 switch (s.mode) {\r
6298                                         case "exact":\r
6299                                                 l = s.elements || '';\r
6301                                                 if(l.length > 0) {\r
6302                                                         each(explode(l), function(v) {\r
6303                                                                 if (DOM.get(v)) {\r
6304                                                                         ed = new tinymce.Editor(v, s);\r
6305                                                                         el.push(ed);\r
6306                                                                         ed.render(1);\r
6307                                                                 } else {\r
6308                                                                         c = 0;\r
6310                                                                         each(document.forms, function(f) {\r
6311                                                                                 each(f.elements, function(e) {\r
6312                                                                                         if (e.name === v) {\r
6313                                                                                                 v = 'mce_editor_' + c;\r
6314                                                                                                 DOM.setAttrib(e, 'id', v);\r
6316                                                                                                 ed = new tinymce.Editor(v, s);\r
6317                                                                                                 el.push(ed);\r
6318                                                                                                 ed.render(1);\r
6319                                                                                         }\r
6320                                                                                 });\r
6321                                                                         });\r
6322                                                                 }\r
6323                                                         });\r
6324                                                 }\r
6325                                                 break;\r
6327                                         case "textareas":\r
6328                                         case "specific_textareas":\r
6329                                                 function hasClass(n, c) {\r
6330                                                         return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);\r
6331                                                 };\r
6333                                                 each(DOM.select('textarea'), function(v) {\r
6334                                                         if (s.editor_deselector && hasClass(v, s.editor_deselector))\r
6335                                                                 return;\r
6337                                                         if (!s.editor_selector || hasClass(v, s.editor_selector)) {\r
6338                                                                 // Can we use the name\r
6339                                                                 e = DOM.get(v.name);\r
6340                                                                 if (!v.id && !e)\r
6341                                                                         v.id = v.name;\r
6343                                                                 // Generate unique name if missing or already exists\r
6344                                                                 if (!v.id || t.get(v.id))\r
6345                                                                         v.id = DOM.uniqueId();\r
6347                                                                 ed = new tinymce.Editor(v.id, s);\r
6348                                                                 el.push(ed);\r
6349                                                                 ed.render(1);\r
6350                                                         }\r
6351                                                 });\r
6352                                                 break;\r
6353                                 }\r
6355                                 // Call onInit when all editors are initialized\r
6356                                 if (s.oninit) {\r
6357                                         l = co = 0;\r
6359                                         each (el, function(ed) {\r
6360                                                 co++;\r
6362                                                 if (!ed.initialized) {\r
6363                                                         // Wait for it\r
6364                                                         ed.onInit.add(function() {\r
6365                                                                 l++;\r
6367                                                                 // All done\r
6368                                                                 if (l == co)\r
6369                                                                         execCallback(s, 'oninit');\r
6370                                                         });\r
6371                                                 } else\r
6372                                                         l++;\r
6374                                                 // All done\r
6375                                                 if (l == co)\r
6376                                                         execCallback(s, 'oninit');                                      \r
6377                                         });\r
6378                                 }\r
6379                         });\r
6380                 },\r
6382                 get : function(id) {\r
6383                         return this.editors[id];\r
6384                 },\r
6386                 getInstanceById : function(id) {\r
6387                         return this.get(id);\r
6388                 },\r
6390                 add : function(e) {\r
6391                         this.editors[e.id] = e;\r
6392                         this._setActive(e);\r
6394                         return e;\r
6395                 },\r
6397                 remove : function(e) {\r
6398                         var t = this;\r
6400                         // Not in the collection\r
6401                         if (!t.editors[e.id])\r
6402                                 return null;\r
6404                         delete t.editors[e.id];\r
6406                         // Select another editor since the active one was removed\r
6407                         if (t.activeEditor == e) {\r
6408                                 each(t.editors, function(e) {\r
6409                                         t._setActive(e);\r
6410                                         return false; // Break\r
6411                                 });\r
6412                         }\r
6414                         e.destroy();\r
6416                         return e;\r
6417                 },\r
6419                 execCommand : function(c, u, v) {\r
6420                         var t = this, ed = t.get(v), w;\r
6422                         // Manager commands\r
6423                         switch (c) {\r
6424                                 case "mceFocus":\r
6425                                         ed.focus();\r
6426                                         return true;\r
6428                                 case "mceAddEditor":\r
6429                                 case "mceAddControl":\r
6430                                         if (!t.get(v))\r
6431                                                 new tinymce.Editor(v, t.settings).render();\r
6433                                         return true;\r
6435                                 case "mceAddFrameControl":\r
6436                                         w = v.window;\r
6438                                         // Add tinyMCE global instance and tinymce namespace to specified window\r
6439                                         w.tinyMCE = tinyMCE;\r
6440                                         w.tinymce = tinymce;\r
6442                                         tinymce.DOM.doc = w.document;\r
6443                                         tinymce.DOM.win = w;\r
6445                                         ed = new tinymce.Editor(v.element_id, v);\r
6446                                         ed.render();\r
6448                                         // Fix IE memory leaks\r
6449                                         if (tinymce.isIE) {\r
6450                                                 function clr() {\r
6451                                                         ed.destroy();\r
6452                                                         w.detachEvent('onunload', clr);\r
6453                                                         w = w.tinyMCE = w.tinymce = null; // IE leak\r
6454                                                 };\r
6456                                                 w.attachEvent('onunload', clr);\r
6457                                         }\r
6459                                         v.page_window = null;\r
6461                                         return true;\r
6463                                 case "mceRemoveEditor":\r
6464                                 case "mceRemoveControl":\r
6465                                         ed.remove();\r
6466                                         return true;\r
6468                                 case 'mceToggleEditor':\r
6469                                         if (!ed) {\r
6470                                                 t.execCommand('mceAddControl', 0, v);\r
6471                                                 return true;\r
6472                                         }\r
6474                                         if (ed.isHidden())\r
6475                                                 ed.show();\r
6476                                         else\r
6477                                                 ed.hide();\r
6479                                         return true;\r
6480                         }\r
6482                         // Run command on active editor\r
6483                         if (t.activeEditor)\r
6484                                 return t.activeEditor.execCommand(c, u, v);\r
6486                         return false;\r
6487                 },\r
6489                 execInstanceCommand : function(id, c, u, v) {\r
6490                         var ed = this.get(id);\r
6492                         if (ed)\r
6493                                 return ed.execCommand(c, u, v);\r
6495                         return false;\r
6496                 },\r
6498                 triggerSave : function() {\r
6499                         each(this.editors, function(e) {\r
6500                                 e.save();\r
6501                         });\r
6502                 },\r
6504                 addI18n : function(p, o) {\r
6505                         var lo, i18n = this.i18n;\r
6507                         if (!tinymce.is(p, 'string')) {\r
6508                                 each(p, function(o, lc) {\r
6509                                         each(o, function(o, g) {\r
6510                                                 each(o, function(o, k) {\r
6511                                                         if (g === 'common')\r
6512                                                                 i18n[lc + '.' + k] = o;\r
6513                                                         else\r
6514                                                                 i18n[lc + '.' + g + '.' + k] = o;\r
6515                                                 });\r
6516                                         });\r
6517                                 });\r
6518                         } else {\r
6519                                 each(o, function(o, k) {\r
6520                                         i18n[p + '.' + k] = o;\r
6521                                 });\r
6522                         }\r
6523                 },\r
6525                 // Private methods\r
6527                 _setActive : function(e) {\r
6528                         this.selectedInstance = this.activeEditor = e;\r
6529                 }\r
6531                 });\r
6533         tinymce.EditorManager.preInit();\r
6534 })();\r
6536 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call\r
6537 var tinyMCE = window.tinyMCE = tinymce.EditorManager;\r
6539 /* file:jscripts/tiny_mce/classes/Editor.js */\r
6541 (function() {\r
6542         var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;\r
6543         var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;\r
6544         var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;\r
6545         var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;\r
6547         tinymce.create('tinymce.Editor', {\r
6548                 Editor : function(id, s) {\r
6549                         var t = this;\r
6551                         t.id = t.editorId = id;\r
6552                         t.execCommands = {};\r
6553                         t.queryStateCommands = {};\r
6554                         t.queryValueCommands = {};\r
6555                         t.plugins = {};\r
6557                         // Add events to the editor\r
6558                         each([\r
6559                                 'onPreInit',\r
6560                                 'onBeforeRenderUI',\r
6561                                 'onPostRender',\r
6562                                 'onInit',\r
6563                                 'onRemove',\r
6564                                 'onActivate',\r
6565                                 'onDeactivate',\r
6566                                 'onClick',\r
6567                                 'onEvent',\r
6568                                 'onMouseUp',\r
6569                                 'onMouseDown',\r
6570                                 'onDblClick',\r
6571                                 'onKeyDown',\r
6572                                 'onKeyUp',\r
6573                                 'onKeyPress',\r
6574                                 'onContextMenu',\r
6575                                 'onSubmit',\r
6576                                 'onReset',\r
6577                                 'onPaste',\r
6578                                 'onPreProcess',\r
6579                                 'onPostProcess',\r
6580                                 'onBeforeSetContent',\r
6581                                 'onBeforeGetContent',\r
6582                                 'onSetContent',\r
6583                                 'onGetContent',\r
6584                                 'onLoadContent',\r
6585                                 'onSaveContent',\r
6586                                 'onNodeChange',\r
6587                                 'onChange',\r
6588                                 'onBeforeExecCommand',\r
6589                                 'onExecCommand',\r
6590                                 'onUndo',\r
6591                                 'onRedo',\r
6592                                 'onVisualAid',\r
6593                                 'onSetProgressState'\r
6594                         ], function(e) {\r
6595                                 t[e] = new Dispatcher(t);\r
6596                         });\r
6598                         // Default editor config\r
6599                         t.settings = s = extend({\r
6600                                 id : id,\r
6601                                 language : 'en',\r
6602                                 docs_language : 'en',\r
6603                                 theme : 'simple',\r
6604                                 skin : 'default',\r
6605                                 delta_width : 0,\r
6606                                 delta_height : 0,\r
6607                                 popup_css : '',\r
6608                                 plugins : '',\r
6609                                 document_base_url : tinymce.documentBaseURL,\r
6610                                 add_form_submit_trigger : 1,\r
6611                                 submit_patch : 1,\r
6612                                 add_unload_trigger : 1,\r
6613                                 convert_urls : 1,\r
6614                                 relative_urls : 1,\r
6615                                 remove_script_host : 1,\r
6616                                 table_inline_editing : 0,\r
6617                                 object_resizing : 1,\r
6618                                 cleanup : 1,\r
6619                                 accessibility_focus : 1,\r
6620                                 custom_shortcuts : 1,\r
6621                                 custom_undo_redo_keyboard_shortcuts : 1,\r
6622                                 custom_undo_redo_restore_selection : 1,\r
6623                                 custom_undo_redo : 1,\r
6624                                 doctype : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',\r
6625                                 visual_table_class : 'mceItemTable',\r
6626                                 visual : 1,\r
6627                                 inline_styles : true,\r
6628                                 convert_fonts_to_spans : true,\r
6629                                 font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',\r
6630                                 apply_source_formatting : 1,\r
6631                                 directionality : 'ltr',\r
6632                                 forced_root_block : 'p',\r
6633                                 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|tabindex|accesskey],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
6634                                 hidden_input : 1,\r
6635                                 padd_empty_editor : 1,\r
6636                                 render_ui : 1,\r
6637                                 init_theme : 1,\r
6638                                 force_p_newlines : 1,\r
6639                                 indentation : '30px'\r
6640                         }, s);\r
6642                         // Setup URIs\r
6643                         t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {\r
6644                                 base_uri : tinyMCE.baseURI\r
6645                         });\r
6646                         t.baseURI = EditorManager.baseURI;\r
6648                         // Call setup\r
6649                         t.execCallback('setup', t);\r
6650                 },\r
6652                 render : function(nst) {\r
6653                         var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;\r
6655                         // Page is not loaded yet, wait for it\r
6656                         if (!Event.domLoaded) {\r
6657                                 Event.add(document, 'init', function() {\r
6658                                         t.render();\r
6659                                 });\r
6660                                 return;\r
6661                         }\r
6663                         // Force strict loading mode if render us called by user and not internally\r
6664                         if (!nst) {\r
6665                                 s.strict_loading_mode = 1;\r
6666                                 tinyMCE.settings = s;\r
6667                         }\r
6669                         // Element not found, then skip initialization\r
6670                         if (!t.getElement())\r
6671                                 return;\r
6673                         if (s.strict_loading_mode) {\r
6674                                 sl.settings.strict_mode = s.strict_loading_mode;\r
6675                                 tinymce.DOM.settings.strict = 1;\r
6676                         }\r
6678                         // Add hidden input for non input elements inside form elements\r
6679                         if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))\r
6680                                 DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);\r
6682                         t.windowManager = new tinymce.WindowManager(t);\r
6684                         if (s.encoding == 'xml') {\r
6685                                 t.onGetContent.add(function(ed, o) {\r
6686                                         if (o.save)\r
6687                                                 o.content = DOM.encode(o.content);\r
6688                                 });\r
6689                         }\r
6691                         if (s.add_form_submit_trigger) {\r
6692                                 t.onSubmit.addToTop(function() {\r
6693                                         if (t.initialized) {\r
6694                                                 t.save();\r
6695                                                 t.isNotDirty = 1;\r
6696                                         }\r
6697                                 });\r
6698                         }\r
6700                         if (s.add_unload_trigger && !s.ask) {\r
6701                                 t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {\r
6702                                         if (t.initialized && !t.destroyed && !t.isHidden())\r
6703                                                 t.save({format : 'raw', no_events : true});\r
6704                                 });\r
6705                         }\r
6707                         tinymce.addUnload(t.destroy, t);\r
6709                         if (s.submit_patch) {\r
6710                                 t.onBeforeRenderUI.add(function() {\r
6711                                         var n = t.getElement().form;\r
6713                                         if (!n)\r
6714                                                 return;\r
6716                                         // Already patched\r
6717                                         if (n._mceOldSubmit)\r
6718                                                 return;\r
6720                                         // Check page uses id="submit" or name="submit" for it's submit button\r
6721                                         if (!n.submit.nodeType && !n.submit.length) {\r
6722                                                 t.formElement = n;\r
6723                                                 n._mceOldSubmit = n.submit;\r
6724                                                 n.submit = function() {\r
6725                                                         // Save all instances\r
6726                                                         EditorManager.triggerSave();\r
6727                                                         t.isNotDirty = 1;\r
6729                                                         return this._mceOldSubmit(this);\r
6730                                                 };\r
6731                                         }\r
6733                                         n = null;\r
6734                                 });\r
6735                         }\r
6737                         // Load scripts\r
6738                         function loadScripts() {\r
6739                                 if (s.language)\r
6740                                         sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
6742                                 if (s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
6743                                         ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
6745                                 each(explode(s.plugins), function(p) {\r
6746                                         if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) {\r
6747                                                 // Skip safari plugin for other browsers\r
6748                                                 if (!isWebKit && p == 'safari')\r
6749                                                         return;\r
6751                                                 PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js');\r
6752                                         }\r
6753                                 });\r
6755                                 // Init when que is loaded\r
6756                                 sl.loadQueue(function() {\r
6757                                         if (s.ask) {\r
6758                                                 function ask() {\r
6759                                                         // Yield for awhile to avoid focus bug on FF 3 when cancel is pressed\r
6760                                                         window.setTimeout(function() {\r
6761                                                                 Event.remove(t.id, 'focus', ask);\r
6763                                                                 t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {\r
6764                                                                         if (s)\r
6765                                                                                 t.init();\r
6766                                                                 });\r
6767                                                         }, 0);\r
6768                                                 };\r
6770                                                 Event.add(t.id, 'focus', ask);\r
6771                                                 return;\r
6772                                         }\r
6774                                         if (!t.removed)\r
6775                                                 t.init();\r
6776                                 });\r
6777                         };\r
6779                         // Load compat2x first\r
6780                         if (s.plugins.indexOf('compat2x') != -1) {\r
6781                                 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');\r
6782                                 sl.loadQueue(loadScripts);\r
6783                         } else\r
6784                                 loadScripts();\r
6785                 },\r
6787                 init : function() {\r
6788                         var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;\r
6790                         EditorManager.add(t);\r
6792                         // Create theme\r
6793                         s.theme = s.theme.replace(/-/, '');\r
6794                         o = ThemeManager.get(s.theme);\r
6795                         t.theme = new o();\r
6797                         if (t.theme.init && s.init_theme)\r
6798                                 t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));\r
6800                         // Create all plugins\r
6801                         each(explode(s.plugins.replace(/\-/g, '')), function(p) {\r
6802                                 var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;\r
6804                                 if (c) {\r
6805                                         po = new c(t, u);\r
6807                                         t.plugins[p] = po;\r
6809                                         if (po.init)\r
6810                                                 po.init(t, u);\r
6811                                 }\r
6812                         });\r
6814                         // Setup popup CSS path(s)\r
6815                         if (s.popup_css)\r
6816                                 s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);\r
6817                         else\r
6818                                 s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");\r
6820                         if (s.popup_css_add)\r
6821                                 s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);\r
6823                         // Setup control factory\r
6824                         t.controlManager = new tinymce.ControlManager(t);\r
6825                         t.undoManager = new tinymce.UndoManager(t);\r
6827                         // Pass through\r
6828                         t.undoManager.onAdd.add(function(um, l) {\r
6829                                 if (!l.initial)\r
6830                                         return t.onChange.dispatch(t, l, um);\r
6831                         });\r
6833                         t.undoManager.onUndo.add(function(um, l) {\r
6834                                 return t.onUndo.dispatch(t, l, um);\r
6835                         });\r
6837                         t.undoManager.onRedo.add(function(um, l) {\r
6838                                 return t.onRedo.dispatch(t, l, um);\r
6839                         });\r
6841                         if (s.custom_undo_redo) {\r
6842                                 t.onExecCommand.add(function(ed, cmd, ui, val, a) {\r
6843                                         if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))\r
6844                                                 t.undoManager.add();\r
6845                                 });\r
6846                         }\r
6848                         t.onExecCommand.add(function(ed, c) {\r
6849                                 // Don't refresh the select lists until caret move\r
6850                                 if (!/^(FontName|FontSize)$/.test(c))\r
6851                                         t.nodeChanged();\r
6852                         });\r
6854                         // Remove ghost selections on images and tables in Gecko\r
6855                         if (isGecko) {\r
6856                                 function repaint(a, o) {\r
6857                                         if (!o || !o.initial)\r
6858                                                 t.execCommand('mceRepaint');\r
6859                                 };\r
6861                                 t.onUndo.add(repaint);\r
6862                                 t.onRedo.add(repaint);\r
6863                                 t.onSetContent.add(repaint);\r
6864                         }\r
6866                         // Enables users to override the control factory\r
6867                         t.onBeforeRenderUI.dispatch(t, t.controlManager);\r
6869                         // Measure box\r
6870                         if (s.render_ui) {\r
6871                                 w = s.width || e.style.width || e.offsetWidth;\r
6872                                 h = s.height || e.style.height || e.offsetHeight;\r
6873                                 t.orgDisplay = e.style.display;\r
6874                                 re = /^[0-9\.]+(|px)$/i;\r
6876                                 if (re.test('' + w))\r
6877                                         w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);\r
6879                                 if (re.test('' + h))\r
6880                                         h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);\r
6882                                 // Render UI\r
6883                                 o = t.theme.renderUI({\r
6884                                         targetNode : e,\r
6885                                         width : w,\r
6886                                         height : h,\r
6887                                         deltaWidth : s.delta_width,\r
6888                                         deltaHeight : s.delta_height\r
6889                                 });\r
6891                                 t.editorContainer = o.editorContainer;\r
6892                         }\r
6894                         \r
6895                         // Resize editor\r
6896                         DOM.setStyles(o.sizeContainer || o.editorContainer, {\r
6897                                 width : w,\r
6898                                 height : h\r
6899                         });\r
6901                         h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');\r
6902                         if (h < 100)\r
6903                                 h = 100;\r
6905                         t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" />';\r
6906                         t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';\r
6908                         if (tinymce.relaxedDomain)\r
6909                                 t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';\r
6911                         bi = s.body_id || 'tinymce';\r
6912                         if (bi.indexOf('=') != -1) {\r
6913                                 bi = t.getParam('body_id', '', 'hash');\r
6914                                 bi = bi[t.id] || bi;\r
6915                         }\r
6917                         bc = s.body_class || '';\r
6918                         if (bc.indexOf('=') != -1) {\r
6919                                 bc = t.getParam('body_class', '', 'hash');\r
6920                                 bc = bc[t.id] || '';\r
6921                         }\r
6923                         t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';\r
6925                         // Domain relaxing enabled, then set document domain\r
6926                         if (tinymce.relaxedDomain) {\r
6927                                 // We need to write the contents here in IE since multiple writes messes up refresh button and back button\r
6928                                 if (isIE || (tinymce.isOpera && parseFloat(opera.version()) >= 9.5))\r
6929                                         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
6930                                 else if (tinymce.isOpera)\r
6931                                         u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';                                  \r
6932                         }\r
6934                         // Create iframe\r
6935                         n = DOM.add(o.iframeContainer, 'iframe', {\r
6936                                 id : t.id + "_ifr",\r
6937                                 src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7\r
6938                                 frameBorder : '0',\r
6939                                 style : {\r
6940                                         width : '100%',\r
6941                                         height : h\r
6942                                 }\r
6943                         });\r
6945                         t.contentAreaContainer = o.iframeContainer;\r
6946                         DOM.get(o.editorContainer).style.display = t.orgDisplay;\r
6947                         DOM.get(t.id).style.display = 'none';\r
6949                         // Safari 2.x requires us to wait for the load event and load a real HTML doc\r
6950                         if (tinymce.isOldWebKit) {\r
6951                                 Event.add(n, 'load', t.setupIframe, t);\r
6952                                 n.src = tinymce.baseURL + '/plugins/safari/blank.htm';\r
6953                         } else {\r
6954                                 if (!isIE || !tinymce.relaxedDomain)\r
6955                                         t.setupIframe();\r
6957                                 e = n = o = null; // Cleanup\r
6958                         }\r
6959                 },\r
6961                 setupIframe : function() {\r
6962                         var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;\r
6964                         // Setup iframe body\r
6965                         if (!isIE || !tinymce.relaxedDomain) {\r
6966                                 d.open();\r
6967                                 d.write(t.iframeHTML);\r
6968                                 d.close();\r
6969                         }\r
6971                         // Design mode needs to be added here Ctrl+A will fail otherwise\r
6972                         if (!isIE) {\r
6973                                 try {\r
6974                                         if (!s.readonly)\r
6975                                                 d.designMode = 'On';\r
6976                                 } catch (ex) {\r
6977                                         // Will fail on Gecko if the editor is placed in an hidden container element\r
6978                                         // The design mode will be set ones the editor is focused\r
6979                                 }\r
6980                         }\r
6982                         // IE needs to use contentEditable or it will display non secure items for HTTPS\r
6983                         if (isIE) {\r
6984                                 // It will not steal focus if we hide it while setting contentEditable\r
6985                                 b = t.getBody();\r
6986                                 DOM.hide(b);\r
6988                                 if (!s.readonly)\r
6989                                         b.contentEditable = true;\r
6991                                 DOM.show(b);\r
6992                         }\r
6994                         // Setup objects\r
6995                         t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {\r
6996                                 keep_values : true,\r
6997                                 url_converter : t.convertURL,\r
6998                                 url_converter_scope : t,\r
6999                                 hex_colors : s.force_hex_style_colors,\r
7000                                 class_filter : s.class_filter,\r
7001                                 update_styles : 1,\r
7002                                 fix_ie_paragraphs : 1\r
7003                         });\r
7005                         t.serializer = new tinymce.dom.Serializer({\r
7006                                 entity_encoding : s.entity_encoding,\r
7007                                 entities : s.entities,\r
7008                                 valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,\r
7009                                 extended_valid_elements : s.extended_valid_elements,\r
7010                                 valid_child_elements : s.valid_child_elements,\r
7011                                 invalid_elements : s.invalid_elements,\r
7012                                 fix_table_elements : s.fix_table_elements,\r
7013                                 fix_list_elements : s.fix_list_elements,\r
7014                                 fix_content_duplication : s.fix_content_duplication,\r
7015                                 convert_fonts_to_spans : s.convert_fonts_to_spans,\r
7016                                 font_size_classes  : s.font_size_classes,\r
7017                                 font_size_style_values : s.font_size_style_values,\r
7018                                 apply_source_formatting : s.apply_source_formatting,\r
7019                                 remove_linebreaks : s.remove_linebreaks,\r
7020                                 dom : t.dom\r
7021                         });\r
7023                         t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);\r
7024                         t.forceBlocks = new tinymce.ForceBlocks(t, {\r
7025                                 forced_root_block : s.forced_root_block\r
7026                         });\r
7027                         t.editorCommands = new tinymce.EditorCommands(t);\r
7029                         // Pass through\r
7030                         t.serializer.onPreProcess.add(function(se, o) {\r
7031                                 return t.onPreProcess.dispatch(t, o, se);\r
7032                         });\r
7034                         t.serializer.onPostProcess.add(function(se, o) {\r
7035                                 return t.onPostProcess.dispatch(t, o, se);\r
7036                         });\r
7038                         t.onPreInit.dispatch(t);\r
7040                         if (!s.gecko_spellcheck)\r
7041                                 t.getBody().spellcheck = 0;\r
7043                         if (!s.readonly)\r
7044                                 t._addEvents();\r
7046                         t.controlManager.onPostRender.dispatch(t, t.controlManager);\r
7047                         t.onPostRender.dispatch(t);\r
7049                         if (s.directionality)\r
7050                                 t.getBody().dir = s.directionality;\r
7052                         if (s.nowrap)\r
7053                                 t.getBody().style.whiteSpace = "nowrap";\r
7055                         if (s.auto_resize)\r
7056                                 t.onNodeChange.add(t.resizeToContent, t);\r
7058                         if (s.custom_elements) {\r
7059                                 function handleCustom(ed, o) {\r
7060                                         each(explode(s.custom_elements), function(v) {\r
7061                                                 var n;\r
7063                                                 if (v.indexOf('~') === 0) {\r
7064                                                         v = v.substring(1);\r
7065                                                         n = 'span';\r
7066                                                 } else\r
7067                                                         n = 'div';\r
7069                                                 o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' mce_name="$1"$2>');\r
7070                                                 o.content = o.content.replace(new RegExp('</(' + v + ')>', 'g'), '</' + n + '>');\r
7071                                         });\r
7072                                 };\r
7074                                 t.onBeforeSetContent.add(handleCustom);\r
7075                                 t.onPostProcess.add(function(ed, o) {\r
7076                                         if (o.set)\r
7077                                                 handleCustom(ed, o)\r
7078                                 });\r
7079                         }\r
7081                         if (s.handle_node_change_callback) {\r
7082                                 t.onNodeChange.add(function(ed, cm, n) {\r
7083                                         t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());\r
7084                                 });\r
7085                         }\r
7087                         if (s.save_callback) {\r
7088                                 t.onSaveContent.add(function(ed, o) {\r
7089                                         var h = t.execCallback('save_callback', t.id, o.content, t.getBody());\r
7091                                         if (h)\r
7092                                                 o.content = h;\r
7093                                 });\r
7094                         }\r
7096                         if (s.onchange_callback) {\r
7097                                 t.onChange.add(function(ed, l) {\r
7098                                         t.execCallback('onchange_callback', t, l);\r
7099                                 });\r
7100                         }\r
7102                         if (s.convert_newlines_to_brs) {\r
7103                                 t.onBeforeSetContent.add(function(ed, o) {\r
7104                                         if (o.initial)\r
7105                                                 o.content = o.content.replace(/\r?\n/g, '<br />');\r
7106                                 });\r
7107                         }\r
7109                         if (s.fix_nesting && isIE) {\r
7110                                 t.onBeforeSetContent.add(function(ed, o) {\r
7111                                         o.content = t._fixNesting(o.content);\r
7112                                 });\r
7113                         }\r
7115                         if (s.preformatted) {\r
7116                                 t.onPostProcess.add(function(ed, o) {\r
7117                                         o.content = o.content.replace(/^\s*<pre.*?>/, '');\r
7118                                         o.content = o.content.replace(/<\/pre>\s*$/, '');\r
7120                                         if (o.set)\r
7121                                                 o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';\r
7122                                 });\r
7123                         }\r
7125                         if (s.verify_css_classes) {\r
7126                                 t.serializer.attribValueFilter = function(n, v) {\r
7127                                         var s, cl;\r
7129                                         if (n == 'class') {\r
7130                                                 // Build regexp for classes\r
7131                                                 if (!t.classesRE) {\r
7132                                                         cl = t.dom.getClasses();\r
7134                                                         if (cl.length > 0) {\r
7135                                                                 s = '';\r
7137                                                                 each (cl, function(o) {\r
7138                                                                         s += (s ? '|' : '') + o['class'];\r
7139                                                                 });\r
7141                                                                 t.classesRE = new RegExp('(' + s + ')', 'gi');\r
7142                                                         }\r
7143                                                 }\r
7145                                                 return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';\r
7146                                         }\r
7148                                         return v;\r
7149                                 };\r
7150                         }\r
7152                         if (s.convert_fonts_to_spans)\r
7153                                 t._convertFonts();\r
7155                         if (s.inline_styles)\r
7156                                 t._convertInlineElements();\r
7158                         if (s.cleanup_callback) {\r
7159                                 t.onBeforeSetContent.add(function(ed, o) {\r
7160                                         o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);\r
7161                                 });\r
7163                                 t.onPreProcess.add(function(ed, o) {\r
7164                                         if (o.set)\r
7165                                                 t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);\r
7167                                         if (o.get)\r
7168                                                 t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);\r
7169                                 });\r
7171                                 t.onPostProcess.add(function(ed, o) {\r
7172                                         if (o.set)\r
7173                                                 o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);\r
7175                                         if (o.get)                                              \r
7176                                                 o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);\r
7177                                 });\r
7178                         }\r
7180                         if (s.save_callback) {\r
7181                                 t.onGetContent.add(function(ed, o) {\r
7182                                         if (o.save)\r
7183                                                 o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());\r
7184                                 });\r
7185                         }\r
7187                         if (s.handle_event_callback) {\r
7188                                 t.onEvent.add(function(ed, e, o) {\r
7189                                         if (t.execCallback('handle_event_callback', e, ed, o) === false)\r
7190                                                 Event.cancel(e);\r
7191                                 });\r
7192                         }\r
7194                         t.onSetContent.add(function() {\r
7195                                 // Safari needs some time, it will crash the browser when a link is created otherwise\r
7196                                 // I think this crash issue is resolved in the latest 3.0.4\r
7197                                 //window.setTimeout(function() {\r
7198                                         t.addVisual(t.getBody());\r
7199                                 //}, 1);\r
7200                         });\r
7202                         // Remove empty contents\r
7203                         if (s.padd_empty_editor) {\r
7204                                 t.onPostProcess.add(function(ed, o) {\r
7205                                         o.content = o.content.replace(/^(<p>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');\r
7206                                 });\r
7207                         }\r
7209                         if (isGecko && !s.readonly) {\r
7210                                 try {\r
7211                                         // Design mode must be set here once again to fix a bug where\r
7212                                         // Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again\r
7213                                         d.designMode = 'Off';\r
7214                                         d.designMode = 'On';\r
7215                                 } catch (ex) {\r
7216                                         // Will fail on Gecko if the editor is placed in an hidden container element\r
7217                                         // The design mode will be set ones the editor is focused\r
7218                                 }\r
7219                         }\r
7221                         // A small timeout was needed since firefox will remove. Bug: #1838304\r
7222                         setTimeout(function () {\r
7223                                 if (t.removed)\r
7224                                         return;\r
7226                                 t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});\r
7227                                 t.startContent = t.getContent({format : 'raw'});\r
7228                                 t.undoManager.add({initial : true});\r
7229                                 t.initialized = true;\r
7231                                 t.onInit.dispatch(t);\r
7232                                 t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());\r
7233                                 t.execCallback('init_instance_callback', t);\r
7234                                 t.focus(true);\r
7235                                 t.nodeChanged({initial : 1});\r
7237                                 // Load specified content CSS last\r
7238                                 if (s.content_css) {\r
7239                                         tinymce.each(explode(s.content_css), function(u) {\r
7240                                                 t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));\r
7241                                         });\r
7242                                 }\r
7244                                 // Handle auto focus\r
7245                                 if (s.auto_focus) {\r
7246                                         setTimeout(function () {\r
7247                                                 var ed = EditorManager.get(s.auto_focus);\r
7249                                                 ed.selection.select(ed.getBody(), 1);\r
7250                                                 ed.selection.collapse(1);\r
7251                                                 ed.getWin().focus();\r
7252                                         }, 100);\r
7253                                 }\r
7254                         }, 1);\r
7255         \r
7256                         e = null;\r
7257                 },\r
7259                 \r
7260                 focus : function(sf) {\r
7261                         var oed, t = this, ce = t.settings.content_editable;\r
7263                         if (!sf) {\r
7264                                 // Is not content editable or the selection is outside the area in IE\r
7265                                 // the IE statement is needed to avoid bluring if element selections inside layers since\r
7266                                 // the layer is like it's own document in IE\r
7267                                 if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc()))\r
7268                                         t.getWin().focus();\r
7270                                                         }\r
7272                         if (EditorManager.activeEditor != t) {\r
7273                                 if ((oed = EditorManager.activeEditor) != null)\r
7274                                         oed.onDeactivate.dispatch(oed, t);\r
7276                                 t.onActivate.dispatch(t, oed);\r
7277                         }\r
7279                         EditorManager._setActive(t);\r
7280                 },\r
7282                 execCallback : function(n) {\r
7283                         var t = this, f = t.settings[n], s;\r
7285                         if (!f)\r
7286                                 return;\r
7288                         // Look through lookup\r
7289                         if (t.callbackLookup && (s = t.callbackLookup[n])) {\r
7290                                 f = s.func;\r
7291                                 s = s.scope;\r
7292                         }\r
7294                         if (is(f, 'string')) {\r
7295                                 s = f.replace(/\.\w+$/, '');\r
7296                                 s = s ? tinymce.resolve(s) : 0;\r
7297                                 f = tinymce.resolve(f);\r
7298                                 t.callbackLookup = t.callbackLookup || {};\r
7299                                 t.callbackLookup[n] = {func : f, scope : s};\r
7300                         }\r
7302                         return f.apply(s || t, Array.prototype.slice.call(arguments, 1));\r
7303                 },\r
7305                 translate : function(s) {\r
7306                         var c = this.settings.language || 'en', i18n = EditorManager.i18n;\r
7308                         if (!s)\r
7309                                 return '';\r
7311                         return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {\r
7312                                 return i18n[c + '.' + b] || '{#' + b + '}';\r
7313                         });\r
7314                 },\r
7316                 getLang : function(n, dv) {\r
7317                         return EditorManager.i18n[(this.settings.language || 'en') + '.' + n] || (is(dv) ? dv : '{#' + n + '}');\r
7318                 },\r
7320                 getParam : function(n, dv, ty) {\r
7321                         var tr = tinymce.trim, v = is(this.settings[n]) ? this.settings[n] : dv, o;\r
7323                         if (ty === 'hash') {\r
7324                                 o = {};\r
7326                                 if (is(v, 'string')) {\r
7327                                         each(v.indexOf('=') > 0 ? v.split(/[;,](?![^=;,]*(?:[;,]|$))/) : v.split(','), function(v) {\r
7328                                                 v = v.split('=');\r
7330                                                 if (v.length > 1)\r
7331                                                         o[tr(v[0])] = tr(v[1]);\r
7332                                                 else\r
7333                                                         o[tr(v[0])] = tr(v);\r
7334                                         });\r
7335                                 } else\r
7336                                         o = v;\r
7338                                 return o;\r
7339                         }\r
7341                         return v;\r
7342                 },\r
7344                 nodeChanged : function(o) {\r
7345                         var t = this, s = t.selection, n = s.getNode() || t.getBody();\r
7347                         // Fix for bug #1896577 it seems that this can not be fired while the editor is loading\r
7348                         if (t.initialized) {\r
7349                                 t.onNodeChange.dispatch(\r
7350                                         t,\r
7351                                         o ? o.controlManager || t.controlManager : t.controlManager,\r
7352                                         isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n, // Fix for IE initial state\r
7353                                         s.isCollapsed(),\r
7354                                         o\r
7355                                 );\r
7356                         }\r
7357                 },\r
7359                 addButton : function(n, s) {\r
7360                         var t = this;\r
7362                         t.buttons = t.buttons || {};\r
7363                         t.buttons[n] = s;\r
7364                 },\r
7366                 addCommand : function(n, f, s) {\r
7367                         this.execCommands[n] = {func : f, scope : s || this};\r
7368                 },\r
7370                 addQueryStateHandler : function(n, f, s) {\r
7371                         this.queryStateCommands[n] = {func : f, scope : s || this};\r
7372                 },\r
7374                 addQueryValueHandler : function(n, f, s) {\r
7375                         this.queryValueCommands[n] = {func : f, scope : s || this};\r
7376                 },\r
7378                 addShortcut : function(pa, desc, cmd_func, sc) {\r
7379                         var t = this, c;\r
7381                         if (!t.settings.custom_shortcuts)\r
7382                                 return false;\r
7384                         t.shortcuts = t.shortcuts || {};\r
7386                         if (is(cmd_func, 'string')) {\r
7387                                 c = cmd_func;\r
7389                                 cmd_func = function() {\r
7390                                         t.execCommand(c, false, null);\r
7391                                 };\r
7392                         }\r
7394                         if (is(cmd_func, 'object')) {\r
7395                                 c = cmd_func;\r
7397                                 cmd_func = function() {\r
7398                                         t.execCommand(c[0], c[1], c[2]);\r
7399                                 };\r
7400                         }\r
7402                         each(explode(pa), function(pa) {\r
7403                                 var o = {\r
7404                                         func : cmd_func,\r
7405                                         scope : sc || this,\r
7406                                         desc : desc,\r
7407                                         alt : false,\r
7408                                         ctrl : false,\r
7409                                         shift : false\r
7410                                 };\r
7412                                 each(explode(pa, '+'), function(v) {\r
7413                                         switch (v) {\r
7414                                                 case 'alt':\r
7415                                                 case 'ctrl':\r
7416                                                 case 'shift':\r
7417                                                         o[v] = true;\r
7418                                                         break;\r
7420                                                 default:\r
7421                                                         o.charCode = v.charCodeAt(0);\r
7422                                                         o.keyCode = v.toUpperCase().charCodeAt(0);\r
7423                                         }\r
7424                                 });\r
7426                                 t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o;\r
7427                         });\r
7429                         return true;\r
7430                 },\r
7432                 execCommand : function(cmd, ui, val, a) {\r
7433                         var t = this, s = 0, o, st;\r
7435                         if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus))\r
7436                                 t.focus();\r
7438                         o = {};\r
7439                         t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o);\r
7440                         if (o.terminate)\r
7441                                 return false;\r
7443                         // Command callback\r
7444                         if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) {\r
7445                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7446                                 return true;\r
7447                         }\r
7449                         // Registred commands\r
7450                         if (o = t.execCommands[cmd]) {\r
7451                                 st = o.func.call(o.scope, ui, val);\r
7453                                 // Fall through on true\r
7454                                 if (st !== true) {\r
7455                                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7456                                         return st;\r
7457                                 }\r
7458                         }\r
7460                         // Plugin commands\r
7461                         each(t.plugins, function(p) {\r
7462                                 if (p.execCommand && p.execCommand(cmd, ui, val)) {\r
7463                                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7464                                         s = 1;\r
7465                                         return false;\r
7466                                 }\r
7467                         });\r
7469                         if (s)\r
7470                                 return true;\r
7472                         // Theme commands\r
7473                         if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {\r
7474                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7475                                 return true;\r
7476                         }\r
7478                         // Editor commands\r
7479                         if (t.editorCommands.execCommand(cmd, ui, val)) {\r
7480                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7481                                 return true;\r
7482                         }\r
7484                         // Browser commands\r
7485                         t.getDoc().execCommand(cmd, ui, val);\r
7486                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7487                 },\r
7489                 queryCommandState : function(c) {\r
7490                         var t = this, o, s;\r
7492                         // Is hidden then return undefined\r
7493                         if (t._isHidden())\r
7494                                 return;\r
7496                         // Registred commands\r
7497                         if (o = t.queryStateCommands[c]) {\r
7498                                 s = o.func.call(o.scope);\r
7500                                 // Fall though on true\r
7501                                 if (s !== true)\r
7502                                         return s;\r
7503                         }\r
7505                         // Registred commands\r
7506                         o = t.editorCommands.queryCommandState(c);\r
7507                         if (o !== -1)\r
7508                                 return o;\r
7510                         // Browser commands\r
7511                         try {\r
7512                                 return this.getDoc().queryCommandState(c);\r
7513                         } catch (ex) {\r
7514                                 // Fails sometimes see bug: 1896577\r
7515                         }\r
7516                 },\r
7518                 queryCommandValue : function(c) {\r
7519                         var t = this, o, s;\r
7521                         // Is hidden then return undefined\r
7522                         if (t._isHidden())\r
7523                                 return;\r
7525                         // Registred commands\r
7526                         if (o = t.queryValueCommands[c]) {\r
7527                                 s = o.func.call(o.scope);\r
7529                                 // Fall though on true\r
7530                                 if (s !== true)\r
7531                                         return s;\r
7532                         }\r
7534                         // Registred commands\r
7535                         o = t.editorCommands.queryCommandValue(c);\r
7536                         if (is(o))\r
7537                                 return o;\r
7539                         // Browser commands\r
7540                         try {\r
7541                                 return this.getDoc().queryCommandValue(c);\r
7542                         } catch (ex) {\r
7543                                 // Fails sometimes see bug: 1896577\r
7544                         }\r
7545                 },\r
7547                 show : function() {\r
7548                         var t = this;\r
7550                         DOM.show(t.getContainer());\r
7551                         DOM.hide(t.id);\r
7552                         t.load();\r
7553                 },\r
7555                 hide : function() {\r
7556                         var t = this, d = t.getDoc();\r
7558                         // Fixed bug where IE has a blinking cursor left from the editor\r
7559                         if (isIE && d)\r
7560                                 d.execCommand('SelectAll');\r
7562                         // We must save before we hide so Safari doesn't crash\r
7563                         t.save();\r
7564                         DOM.hide(t.getContainer());\r
7565                         DOM.setStyle(t.id, 'display', t.orgDisplay);\r
7566                 },\r
7568                 isHidden : function() {\r
7569                         return !DOM.isHidden(this.id);\r
7570                 },\r
7572                 setProgressState : function(b, ti, o) {\r
7573                         this.onSetProgressState.dispatch(this, b, ti, o);\r
7575                         return b;\r
7576                 },\r
7578                 resizeToContent : function() {\r
7579                         var t = this;\r
7581                         DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight);\r
7582                 },\r
7584                 load : function(o) {\r
7585                         var t = this, e = t.getElement(), h;\r
7587                         o = o || {};\r
7588                         o.load = true;\r
7590                         h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);\r
7591                         o.element = e;\r
7593                         if (!o.no_events)\r
7594                                 t.onLoadContent.dispatch(t, o);\r
7596                         o.element = e = null;\r
7598                         return h;\r
7599                 },\r
7601                 save : function(o) {\r
7602                         var t = this, e = t.getElement(), h, f;\r
7604                         if (!t.initialized)\r
7605                                 return;\r
7607                         o = o || {};\r
7608                         o.save = true;\r
7610                         // Add undo level will trigger onchange event\r
7611                         if (!o.no_events) {\r
7612                                 t.undoManager.typing = 0;\r
7613                                 t.undoManager.add();\r
7614                         }\r
7616                         o.element = e;\r
7617                         h = o.content = t.getContent(o);\r
7619                         if (!o.no_events)\r
7620                                 t.onSaveContent.dispatch(t, o);\r
7622                         h = o.content;\r
7624                         if (!/TEXTAREA|INPUT/i.test(e.nodeName)) {\r
7625                                 e.innerHTML = h;\r
7627                                 // Update hidden form element\r
7628                                 if (f = DOM.getParent(t.id, 'form')) {\r
7629                                         each(f.elements, function(e) {\r
7630                                                 if (e.name == t.id) {\r
7631                                                         e.value = h;\r
7632                                                         return false;\r
7633                                                 }\r
7634                                         });\r
7635                                 }\r
7636                         } else\r
7637                                 e.value = h;\r
7639                         o.element = e = null;\r
7641                         return h;\r
7642                 },\r
7644                 setContent : function(h, o) {\r
7645                         var t = this;\r
7647                         o = o || {};\r
7648                         o.format = o.format || 'html';\r
7649                         o.set = true;\r
7650                         o.content = h;\r
7652                         if (!o.no_events)\r
7653                                 t.onBeforeSetContent.dispatch(t, o);\r
7655                         // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content\r
7656                         // It will also be impossible to place the caret in the editor unless there is a BR element present\r
7657                         if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {\r
7658                                 o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />');\r
7659                                 o.format = 'raw';\r
7660                         }\r
7662                         o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content));\r
7664                         if (o.format != 'raw' && t.settings.cleanup) {\r
7665                                 o.getInner = true;\r
7666                                 o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));\r
7667                         }\r
7669                         if (!o.no_events)\r
7670                                 t.onSetContent.dispatch(t, o);\r
7672                         return o.content;\r
7673                 },\r
7675                 getContent : function(o) {\r
7676                         var t = this, h;\r
7678                         o = o || {};\r
7679                         o.format = o.format || 'html';\r
7680                         o.get = true;\r
7682                         if (!o.no_events)\r
7683                                 t.onBeforeGetContent.dispatch(t, o);\r
7685                         if (o.format != 'raw' && t.settings.cleanup) {\r
7686                                 o.getInner = true;\r
7687                                 h = t.serializer.serialize(t.getBody(), o);\r
7688                         } else\r
7689                                 h = t.getBody().innerHTML;\r
7691                         h = h.replace(/^\s*|\s*$/g, '');\r
7692                         o.content = h;\r
7694                         if (!o.no_events)\r
7695                                 t.onGetContent.dispatch(t, o);\r
7697                         return o.content;\r
7698                 },\r
7700                 isDirty : function() {\r
7701                         var t = this;\r
7703                         return tinymce.trim(t.startContent) != tinymce.trim(t.getContent({format : 'raw', no_events : 1})) && !t.isNotDirty;\r
7704                 },\r
7706                 getContainer : function() {\r
7707                         var t = this;\r
7709                         if (!t.container)\r
7710                                 t.container = DOM.get(t.editorContainer || t.id + '_parent');\r
7712                         return t.container;\r
7713                 },\r
7715                 getContentAreaContainer : function() {\r
7716                         return this.contentAreaContainer;\r
7717                 },\r
7719                 getElement : function() {\r
7720                         return DOM.get(this.settings.content_element || this.id);\r
7721                 },\r
7723                 getWin : function() {\r
7724                         var t = this, e;\r
7726                         if (!t.contentWindow) {\r
7727                                 e = DOM.get(t.id + "_ifr");\r
7729                                 if (e)\r
7730                                         t.contentWindow = e.contentWindow;\r
7731                         }\r
7733                         return t.contentWindow;\r
7734                 },\r
7736                 getDoc : function() {\r
7737                         var t = this, w;\r
7739                         if (!t.contentDocument) {\r
7740                                 w = t.getWin();\r
7742                                 if (w)\r
7743                                         t.contentDocument = w.document;\r
7744                         }\r
7746                         return t.contentDocument;\r
7747                 },\r
7749                 getBody : function() {\r
7750                         return this.bodyElement || this.getDoc().body;\r
7751                 },\r
7753                 convertURL : function(u, n, e) {\r
7754                         var t = this, s = t.settings;\r
7756                         // Use callback instead\r
7757                         if (s.urlconverter_callback)\r
7758                                 return t.execCallback('urlconverter_callback', u, e, true, n);\r
7760                         // Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs\r
7761                         if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0)\r
7762                                 return u;\r
7764                         // Convert to relative\r
7765                         if (s.relative_urls)\r
7766                                 return t.documentBaseURI.toRelative(u);\r
7768                         // Convert to absolute\r
7769                         u = t.documentBaseURI.toAbsolute(u, s.remove_script_host);\r
7771                         return u;\r
7772                 },\r
7774                 addVisual : function(e) {\r
7775                         var t = this, s = t.settings;\r
7777                         e = e || t.getBody();\r
7779                         if (!is(t.hasVisual))\r
7780                                 t.hasVisual = s.visual;\r
7782                         each(t.dom.select('table,a', e), function(e) {\r
7783                                 var v;\r
7785                                 switch (e.nodeName) {\r
7786                                         case 'TABLE':\r
7787                                                 v = t.dom.getAttrib(e, 'border');\r
7789                                                 if (!v || v == '0') {\r
7790                                                         if (t.hasVisual)\r
7791                                                                 t.dom.addClass(e, s.visual_table_class);\r
7792                                                         else\r
7793                                                                 t.dom.removeClass(e, s.visual_table_class);\r
7794                                                 }\r
7796                                                 return;\r
7798                                         case 'A':\r
7799                                                 v = t.dom.getAttrib(e, 'name');\r
7801                                                 if (v) {\r
7802                                                         if (t.hasVisual)\r
7803                                                                 t.dom.addClass(e, 'mceItemAnchor');\r
7804                                                         else\r
7805                                                                 t.dom.removeClass(e, 'mceItemAnchor');\r
7806                                                 }\r
7808                                                 return;\r
7809                                 }\r
7810                         });\r
7812                         t.onVisualAid.dispatch(t, e, t.hasVisual);\r
7813                 },\r
7815                 remove : function() {\r
7816                         var t = this, e = t.getContainer();\r
7818                         t.removed = 1; // Cancels post remove event execution\r
7819                         t.hide();\r
7821                         t.execCallback('remove_instance_callback', t);\r
7822                         t.onRemove.dispatch(t);\r
7824                         // Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command\r
7825                         t.onExecCommand.listeners = [];\r
7827                         EditorManager.remove(t);\r
7828                         DOM.remove(e);\r
7829                 },\r
7831                 destroy : function(s) {\r
7832                         var t = this;\r
7834                         // One time is enough\r
7835                         if (t.destroyed)\r
7836                                 return;\r
7838                         if (!s) {\r
7839                                 tinymce.removeUnload(t.destroy);\r
7840                                 tinyMCE.onBeforeUnload.remove(t._beforeUnload);\r
7842                                 // Manual destroy\r
7843                                 if (t.theme.destroy)\r
7844                                         t.theme.destroy();\r
7846                                 // Destroy controls, selection and dom\r
7847                                 t.controlManager.destroy();\r
7848                                 t.selection.destroy();\r
7849                                 t.dom.destroy();\r
7851                                 // Remove all events\r
7853                                 // Don't clear the window or document if content editable\r
7854                                 // is enabled since other instances might still be present\r
7855                                 if (!t.settings.content_editable) {\r
7856                                         Event.clear(t.getWin());\r
7857                                         Event.clear(t.getDoc());\r
7858                                 }\r
7860                                 Event.clear(t.getBody());\r
7861                                 Event.clear(t.formElement);\r
7862                         }\r
7864                         if (t.formElement) {\r
7865                                 t.formElement.submit = t.formElement._mceOldSubmit;\r
7866                                 t.formElement._mceOldSubmit = null;\r
7867                         }\r
7869                         t.contentAreaContainer = t.formElement = t.container = t.settings.content_element = t.bodyElement = t.contentDocument = t.contentWindow = null;\r
7871                         if (t.selection)\r
7872                                 t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null;\r
7874                         t.destroyed = 1;\r
7875                 },\r
7877                 // Internal functions\r
7879                 _addEvents : function() {\r
7880                         // 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset\r
7881                         var t = this, i, s = t.settings, lo = {\r
7882                                 mouseup : 'onMouseUp',\r
7883                                 mousedown : 'onMouseDown',\r
7884                                 click : 'onClick',\r
7885                                 keyup : 'onKeyUp',\r
7886                                 keydown : 'onKeyDown',\r
7887                                 keypress : 'onKeyPress',\r
7888                                 submit : 'onSubmit',\r
7889                                 reset : 'onReset',\r
7890                                 contextmenu : 'onContextMenu',\r
7891                                 dblclick : 'onDblClick',\r
7892                                 paste : 'onPaste' // Doesn't work in all browsers yet\r
7893                         };\r
7895                         function eventHandler(e, o) {\r
7896                                 var ty = e.type;\r
7898                                 // Don't fire events when it's removed\r
7899                                 if (t.removed)\r
7900                                         return;\r
7902                                 // Generic event handler\r
7903                                 if (t.onEvent.dispatch(t, e, o) !== false) {\r
7904                                         // Specific event handler\r
7905                                         t[lo[e.fakeType || e.type]].dispatch(t, e, o);\r
7906                                 }\r
7907                         };\r
7909                         // Add DOM events\r
7910                         each(lo, function(v, k) {\r
7911                                 switch (k) {\r
7912                                         case 'contextmenu':\r
7913                                                 if (tinymce.isOpera) {\r
7914                                                         // Fake contextmenu on Opera\r
7915                                                         Event.add(t.getBody(), 'mousedown', function(e) {\r
7916                                                                 if (e.ctrlKey) {\r
7917                                                                         e.fakeType = 'contextmenu';\r
7918                                                                         eventHandler(e);\r
7919                                                                 }\r
7920                                                         });\r
7921                                                 } else\r
7922                                                         Event.add(t.getBody(), k, eventHandler);\r
7923                                                 break;\r
7925                                         case 'paste':\r
7926                                                 Event.add(t.getBody(), k, function(e) {\r
7927                                                         var tx, h, el, r;\r
7929                                                         // Get plain text data\r
7930                                                         if (e.clipboardData)\r
7931                                                                 tx = e.clipboardData.getData('text/plain');\r
7932                                                         else if (tinymce.isIE)\r
7933                                                                 tx = t.getWin().clipboardData.getData('Text');\r
7935                                                         // Get HTML data\r
7936                                                         /*if (tinymce.isIE) {\r
7937                                                                 el = DOM.add(DOM.doc.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'});\r
7938                                                                 r = DOM.doc.body.createTextRange();\r
7939                                                                 r.moveToElementText(el);\r
7940                                                                 r.execCommand('Paste');\r
7941                                                                 h = el.innerHTML;\r
7942                                                                 DOM.remove(el);\r
7943                                                         }*/\r
7945                                                         eventHandler(e, {text : tx, html : h});\r
7946                                                 });\r
7947                                                 break;\r
7949                                         case 'submit':\r
7950                                         case 'reset':\r
7951                                                 Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);\r
7952                                                 break;\r
7954                                         default:\r
7955                                                 Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);\r
7956                                 }\r
7957                         });\r
7959                         Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {\r
7960                                 t.focus(true);\r
7961                         });\r
7963                         \r
7964                         // Fixes bug where a specified document_base_uri could result in broken images\r
7965                         // This will also fix drag drop of images in Gecko\r
7966                         if (tinymce.isGecko) {\r
7967                                 // Convert all images to absolute URLs\r
7968 /*                              t.onSetContent.add(function(ed, o) {\r
7969                                         each(ed.dom.select('img'), function(e) {\r
7970                                                 var v;\r
7972                                                 if (v = e.getAttribute('mce_src'))\r
7973                                                         e.src = t.documentBaseURI.toAbsolute(v);\r
7974                                         })\r
7975                                 });*/\r
7977                                 Event.add(t.getDoc(), 'DOMNodeInserted', function(e) {\r
7978                                         var v;\r
7980                                         e = e.target;\r
7982                                         if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src')))\r
7983                                                 e.src = t.documentBaseURI.toAbsolute(v);\r
7984                                 });\r
7985                         }\r
7987                         // Set various midas options in Gecko\r
7988                         if (isGecko) {\r
7989                                 function setOpts() {\r
7990                                         var t = this, d = t.getDoc(), s = t.settings;\r
7992                                         if (isGecko && !s.readonly) {\r
7993                                                 if (t._isHidden()) {\r
7994                                                         try {\r
7995                                                                 if (!s.content_editable)\r
7996                                                                         d.designMode = 'On';\r
7997                                                         } catch (ex) {\r
7998                                                                 // Fails if it's hidden\r
7999                                                         }\r
8000                                                 }\r
8002                                                 try {\r
8003                                                         // Try new Gecko method\r
8004                                                         d.execCommand("styleWithCSS", 0, false);\r
8005                                                 } catch (ex) {\r
8006                                                         // Use old method\r
8007                                                         if (!t._isHidden())\r
8008                                                                 try {d.execCommand("useCSS", 0, true);} catch (ex) {}\r
8009                                                 }\r
8011                                                 if (!s.table_inline_editing)\r
8012                                                         try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}\r
8014                                                 if (!s.object_resizing)\r
8015                                                         try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}\r
8016                                         }\r
8017                                 };\r
8019                                 t.onBeforeExecCommand.add(setOpts);\r
8020                                 t.onMouseDown.add(setOpts);\r
8021                         }\r
8023                         // Add node change handlers\r
8024                         t.onMouseUp.add(t.nodeChanged);\r
8025                         t.onClick.add(t.nodeChanged);\r
8026                         t.onKeyUp.add(function(ed, e) {\r
8027                                 var c = e.keyCode;\r
8029                                 if ((c >= 33 && c <= 36) || (c >= 37 && c <= 40) || c == 13 || c == 45 || c == 46 || c == 8 || (tinymce.isMac && c >= 91 && c <= 93) || e.ctrlKey)\r
8030                                         t.nodeChanged();\r
8031                         });\r
8033                         // Add reset handler\r
8034                         t.onReset.add(function() {\r
8035                                 t.setContent(t.startContent, {format : 'raw'});\r
8036                         });\r
8038                         if (t.getParam('tab_focus')) {\r
8039                                 function tabCancel(ed, e) {\r
8040                                         if (e.keyCode === 9)\r
8041                                                 return Event.cancel(e);\r
8042                                 };\r
8044                                 function tabHandler(ed, e) {\r
8045                                         var x, i, f, el, v;\r
8047                                         function find(d) {\r
8048                                                 f = DOM.getParent(ed.id, 'form');\r
8049                                                 el = f.elements;\r
8051                                                 if (f) {\r
8052                                                         each(el, function(e, i) {\r
8053                                                                 if (e.id == ed.id) {\r
8054                                                                         x = i;\r
8055                                                                         return false;\r
8056                                                                 }\r
8057                                                         });\r
8059                                                         if (d > 0) {\r
8060                                                                 for (i = x + 1; i < el.length; i++) {\r
8061                                                                         if (el[i].type != 'hidden')\r
8062                                                                                 return el[i];\r
8063                                                                 }\r
8064                                                         } else {\r
8065                                                                 for (i = x - 1; i >= 0; i--) {\r
8066                                                                         if (el[i].type != 'hidden')\r
8067                                                                                 return el[i];\r
8068                                                                 }\r
8069                                                         }\r
8070                                                 }\r
8072                                                 return null;\r
8073                                         };\r
8075                                         if (e.keyCode === 9) {\r
8076                                                 v = explode(ed.getParam('tab_focus'));\r
8078                                                 if (v.length == 1) {\r
8079                                                         v[1] = v[0];\r
8080                                                         v[0] = ':prev';\r
8081                                                 }\r
8083                                                 // Find element to focus\r
8084                                                 if (e.shiftKey) {\r
8085                                                         if (v[0] == ':prev')\r
8086                                                                 el = find(-1);\r
8087                                                         else\r
8088                                                                 el = DOM.get(v[0]);\r
8089                                                 } else {\r
8090                                                         if (v[1] == ':next')\r
8091                                                                 el = find(1);\r
8092                                                         else\r
8093                                                                 el = DOM.get(v[1]);\r
8094                                                 }\r
8096                                                 if (el) {\r
8097                                                         if (ed = EditorManager.get(el.id || el.name))\r
8098                                                                 ed.focus();\r
8099                                                         else\r
8100                                                                 window.setTimeout(function() {window.focus();el.focus();}, 10);\r
8102                                                         return Event.cancel(e);\r
8103                                                 }\r
8104                                         }\r
8105                                 };\r
8107                                 t.onKeyUp.add(tabCancel);\r
8109                                 if (isGecko) {\r
8110                                         t.onKeyPress.add(tabHandler);\r
8111                                         t.onKeyDown.add(tabCancel);\r
8112                                 } else\r
8113                                         t.onKeyDown.add(tabHandler);\r
8114                         }\r
8116                         // Add shortcuts\r
8117                         if (s.custom_shortcuts) {\r
8118                                 if (s.custom_undo_redo_keyboard_shortcuts) {\r
8119                                         t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');\r
8120                                         t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');\r
8121                                 }\r
8123                                 // Add default shortcuts for gecko\r
8124                                 if (isGecko) {\r
8125                                         t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold');\r
8126                                         t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic');\r
8127                                         t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline');\r
8128                                 }\r
8130                                 // BlockFormat shortcuts keys\r
8131                                 for (i=1; i<=6; i++)\r
8132                                         t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, '<h' + i + '>']);\r
8134                                 t.addShortcut('ctrl+7', '', ['FormatBlock', false, '<p>']);\r
8135                                 t.addShortcut('ctrl+8', '', ['FormatBlock', false, '<div>']);\r
8136                                 t.addShortcut('ctrl+9', '', ['FormatBlock', false, '<address>']);\r
8138                                 function find(e) {\r
8139                                         var v = null;\r
8141                                         if (!e.altKey && !e.ctrlKey && !e.metaKey)\r
8142                                                 return v;\r
8144                                         each(t.shortcuts, function(o) {\r
8145                                                 if (o.ctrl != e.ctrlKey && (!tinymce.isMac || o.ctrl == e.metaKey))\r
8146                                                         return;\r
8148                                                 if (o.alt != e.altKey)\r
8149                                                         return;\r
8151                                                 if (o.shift != e.shiftKey)\r
8152                                                         return;\r
8154                                                 if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {\r
8155                                                         v = o;\r
8156                                                         return false;\r
8157                                                 }\r
8158                                         });\r
8160                                         return v;\r
8161                                 };\r
8163                                 t.onKeyUp.add(function(ed, e) {\r
8164                                         var o = find(e);\r
8166                                         if (o)\r
8167                                                 return Event.cancel(e);\r
8168                                 });\r
8170                                 t.onKeyPress.add(function(ed, e) {\r
8171                                         var o = find(e);\r
8173                                         if (o)\r
8174                                                 return Event.cancel(e);\r
8175                                 });\r
8177                                 t.onKeyDown.add(function(ed, e) {\r
8178                                         var o = find(e);\r
8180                                         if (o) {\r
8181                                                 o.func.call(o.scope);\r
8182                                                 return Event.cancel(e);\r
8183                                         }\r
8184                                 });\r
8185                         }\r
8187                         if (tinymce.isIE) {\r
8188                                 // Fix so resize will only update the width and height attributes not the styles of an image\r
8189                                 // It will also block mceItemNoResize items\r
8190                                 Event.add(t.getDoc(), 'controlselect', function(e) {\r
8191                                         var re = t.resizeInfo, cb;\r
8193                                         e = e.target;\r
8195                                         // Don't do this action for non image elements\r
8196                                         if (e.nodeName !== 'IMG')\r
8197                                                 return;\r
8199                                         if (re)\r
8200                                                 Event.remove(re.node, re.ev, re.cb);\r
8202                                         if (!t.dom.hasClass(e, 'mceItemNoResize')) {\r
8203                                                 ev = 'resizeend';\r
8204                                                 cb = Event.add(e, ev, function(e) {\r
8205                                                         var v;\r
8207                                                         e = e.target;\r
8209                                                         if (v = t.dom.getStyle(e, 'width')) {\r
8210                                                                 t.dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));\r
8211                                                                 t.dom.setStyle(e, 'width', '');\r
8212                                                         }\r
8214                                                         if (v = t.dom.getStyle(e, 'height')) {\r
8215                                                                 t.dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));\r
8216                                                                 t.dom.setStyle(e, 'height', '');\r
8217                                                         }\r
8218                                                 });\r
8219                                         } else {\r
8220                                                 ev = 'resizestart';\r
8221                                                 cb = Event.add(e, 'resizestart', Event.cancel, Event);\r
8222                                         }\r
8224                                         re = t.resizeInfo = {\r
8225                                                 node : e,\r
8226                                                 ev : ev,\r
8227                                                 cb : cb\r
8228                                         };\r
8229                                 });\r
8231                                 t.onKeyDown.add(function(ed, e) {\r
8232                                         switch (e.keyCode) {\r
8233                                                 case 8:\r
8234                                                         // Fix IE control + backspace browser bug\r
8235                                                         if (t.selection.getRng().item) {\r
8236                                                                 t.selection.getRng().item(0).removeNode();\r
8237                                                                 return Event.cancel(e);\r
8238                                                         }\r
8239                                         }\r
8240                                 });\r
8241                         }\r
8243                         if (tinymce.isOpera) {\r
8244                                 t.onClick.add(function(ed, e) {\r
8245                                         Event.prevent(e);\r
8246                                 });\r
8247                         }\r
8249                         // Add custom undo/redo handlers\r
8250                         if (s.custom_undo_redo) {\r
8251                                 function addUndo() {\r
8252                                         t.undoManager.typing = 0;\r
8253                                         t.undoManager.add();\r
8254                                 };\r
8256                                 // Add undo level on editor blur\r
8257                                 if (tinymce.isIE) {\r
8258                                         Event.add(t.getWin(), 'blur', function(e) {\r
8259                                                 var n;\r
8261                                                 // Check added for fullscreen bug\r
8262                                                 if (t.selection) {\r
8263                                                         n = t.selection.getNode();\r
8265                                                         // Add undo level is selection was lost to another document\r
8266                                                         if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc())\r
8267                                                                 addUndo();\r
8268                                                 }\r
8269                                         });\r
8270                                 } else {\r
8271                                         Event.add(t.getDoc(), 'blur', function() {\r
8272                                                 if (t.selection && !t.removed)\r
8273                                                         addUndo();\r
8274                                         });\r
8275                                 }\r
8277                                 t.onMouseDown.add(addUndo);\r
8279                                 t.onKeyUp.add(function(ed, e) {\r
8280                                         if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) {\r
8281                                                 t.undoManager.typing = 0;\r
8282                                                 t.undoManager.add();\r
8283                                         }\r
8284                                 });\r
8286                                 t.onKeyDown.add(function(ed, e) {\r
8287                                         // Is caracter positon keys\r
8288                                         if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) {\r
8289                                                 if (t.undoManager.typing) {\r
8290                                                         t.undoManager.add();\r
8291                                                         t.undoManager.typing = 0;\r
8292                                                 }\r
8294                                                 return;\r
8295                                         }\r
8297                                         if (!t.undoManager.typing) {\r
8298                                                 t.undoManager.add();\r
8299                                                 t.undoManager.typing = 1;\r
8300                                         }\r
8301                                 });\r
8302                         }\r
8303                 },\r
8305                 _convertInlineElements : function() {\r
8306                         var t = this, s = t.settings, dom = t.dom, v, e, na, st, sp;\r
8308                         function convert(ed, o) {\r
8309                                 if (!s.inline_styles)\r
8310                                         return;\r
8312                                 if (o.get) {\r
8313                                         each(t.dom.select('table,u,strike', o.node), function(n) {\r
8314                                                 switch (n.nodeName) {\r
8315                                                         case 'TABLE':\r
8316                                                                 if (v = dom.getAttrib(n, 'height')) {\r
8317                                                                         dom.setStyle(n, 'height', v);\r
8318                                                                         dom.setAttrib(n, 'height', '');\r
8319                                                                 }\r
8320                                                                 break;\r
8322                                                         case 'U':\r
8323                                                         case 'STRIKE':\r
8324                                                                 //sp = dom.create('span', {style : dom.getAttrib(n, 'style')});\r
8325                                                                 n.style.textDecoration = n.nodeName == 'U' ? 'underline' : 'line-through';\r
8326                                                                 dom.setAttrib(n, 'mce_style', '');\r
8327                                                                 dom.setAttrib(n, 'mce_name', 'span');\r
8328                                                                 break;\r
8329                                                 }\r
8330                                         });\r
8331                                 } else if (o.set) {\r
8332                                         each(t.dom.select('table,span', o.node).reverse(), function(n) {\r
8333                                                 if (n.nodeName == 'TABLE') {\r
8334                                                         if (v = dom.getStyle(n, 'height'))\r
8335                                                                 dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));\r
8336                                                 } else {\r
8337                                                         // Convert spans to elements\r
8338                                                         if (n.style.textDecoration == 'underline')\r
8339                                                                 na = 'u';\r
8340                                                         else if (n.style.textDecoration == 'line-through')\r
8341                                                                 na = 'strike';\r
8342                                                         else\r
8343                                                                 na = '';\r
8345                                                         if (na) {\r
8346                                                                 n.style.textDecoration = '';\r
8347                                                                 dom.setAttrib(n, 'mce_style', '');\r
8349                                                                 e = dom.create(na, {\r
8350                                                                         style : dom.getAttrib(n, 'style')\r
8351                                                                 });\r
8353                                                                 dom.replace(e, n, 1);\r
8354                                                         }\r
8355                                                 }\r
8356                                         });\r
8357                                 }\r
8358                         };\r
8360                         t.onPreProcess.add(convert);\r
8362                         if (!s.cleanup_on_startup) {\r
8363                                 t.onSetContent.add(function(ed, o) {\r
8364                                         if (o.initial)\r
8365                                                 convert(t, {node : t.getBody(), set : 1});\r
8366                                 });\r
8367                         }\r
8368                 },\r
8370                 _convertFonts : function() {\r
8371                         var t = this, s = t.settings, dom = t.dom, fz, fzn, sl, cl;\r
8373                         // No need\r
8374                         if (!s.inline_styles)\r
8375                                 return;\r
8377                         // Font pt values and font size names\r
8378                         fz = [8, 10, 12, 14, 18, 24, 36];\r
8379                         fzn = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large'];\r
8381                         if (sl = s.font_size_style_values)\r
8382                                 sl = explode(sl);\r
8384                         if (cl = s.font_size_classes)\r
8385                                 cl = explode(cl);\r
8387                         function convertToFonts(no) {\r
8388                                 var n, f, nl, x, i, v, st;\r
8390                                 // Convert spans to fonts on non WebKit browsers\r
8391                                 if (tinymce.isWebKit || !s.inline_styles)\r
8392                                         return;\r
8394                                 nl = t.dom.select('span', no);\r
8395                                 for (x = nl.length - 1; x >= 0; x--) {\r
8396                                         n = nl[x];\r
8398                                         f = dom.create('font', {\r
8399                                                 color : dom.toHex(dom.getStyle(n, 'color')),\r
8400                                                 face : dom.getStyle(n, 'fontFamily'),\r
8401                                                 style : dom.getAttrib(n, 'style'),\r
8402                                                 'class' : dom.getAttrib(n, 'class')\r
8403                                         });\r
8405                                         // Clear color and font family\r
8406                                         st = f.style;\r
8407                                         if (st.color || st.fontFamily) {\r
8408                                                 st.color = st.fontFamily = '';\r
8409                                                 dom.setAttrib(f, 'mce_style', ''); // Remove cached style data\r
8410                                         }\r
8412                                         if (sl) {\r
8413                                                 i = inArray(sl, dom.getStyle(n, 'fontSize'));\r
8415                                                 if (i != -1) {\r
8416                                                         dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
8417                                                         //f.style.fontSize = '';\r
8418                                                 }\r
8419                                         } else if (cl) {\r
8420                                                 i = inArray(cl, dom.getAttrib(n, 'class'));\r
8421                                                 v = dom.getStyle(n, 'fontSize');\r
8423                                                 if (i == -1 && v.indexOf('pt') > 0)\r
8424                                                         i = inArray(fz, parseInt(v));\r
8426                                                 if (i == -1)\r
8427                                                         i = inArray(fzn, v);\r
8429                                                 if (i != -1) {\r
8430                                                         dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
8431                                                         f.style.fontSize = '';\r
8432                                                 }\r
8433                                         }\r
8435                                         if (f.color || f.face || f.size) {\r
8436                                                 f.style.fontFamily = '';\r
8437                                                 dom.setAttrib(f, 'mce_style', '');\r
8438                                                 dom.replace(f, n, 1);\r
8439                                         }\r
8441                                         f = n = null;\r
8442                                 }\r
8443                         };\r
8445                         // Run on setup\r
8446                         t.onSetContent.add(function(ed, o) {\r
8447                                 convertToFonts(ed.getBody());\r
8448                         });\r
8450                         // Run on cleanup\r
8451                         t.onPreProcess.add(function(ed, o) {\r
8452                                 var n, sp, nl, x;\r
8454                                 // Keep unit tests happy\r
8455                                 if (!s.inline_styles)\r
8456                                         return;\r
8458                                 if (o.get) {\r
8459                                         nl = t.dom.select('font', o.node);\r
8460                                         for (x = nl.length - 1; x >= 0; x--) {\r
8461                                                 n = nl[x];\r
8463                                                 sp = dom.create('span', {\r
8464                                                         style : dom.getAttrib(n, 'style'),\r
8465                                                         'class' : dom.getAttrib(n, 'class')\r
8466                                                 });\r
8468                                                 dom.setStyles(sp, {\r
8469                                                         fontFamily : dom.getAttrib(n, 'face'),\r
8470                                                         color : dom.getAttrib(n, 'color'),\r
8471                                                         backgroundColor : n.style.backgroundColor\r
8472                                                 });\r
8474                                                 if (n.size) {\r
8475                                                         if (sl)\r
8476                                                                 dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]);\r
8477                                                         else\r
8478                                                                 dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);\r
8479                                                 }\r
8481                                                 dom.setAttrib(sp, 'mce_style', '');\r
8482                                                 dom.replace(sp, n, 1);\r
8483                                         }\r
8484                                 }\r
8485                         });\r
8486                 },\r
8488                 _isHidden : function() {\r
8489                         var s;\r
8491                         if (!isGecko)\r
8492                                 return 0;\r
8494                         // Weird, wheres that cursor selection?\r
8495                         s = this.selection.getSel();\r
8496                         return (!s || !s.rangeCount || s.rangeCount == 0);\r
8497                 },\r
8499                 // Fix for bug #1867292\r
8500                 _fixNesting : function(s) {\r
8501                         var d = [], i;\r
8503                         s = s.replace(/<(\/)?([^\s>]+)[^>]*?>/g, function(a, b, c) {\r
8504                                 var e;\r
8506                                 // Handle end element\r
8507                                 if (b === '/') {\r
8508                                         if (!d.length)\r
8509                                                 return '';\r
8511                                         if (c !== d[d.length - 1].tag) {\r
8512                                                 for (i=d.length - 1; i>=0; i--) {\r
8513                                                         if (d[i].tag === c) {\r
8514                                                                 d[i].close = 1;\r
8515                                                                 break;\r
8516                                                         }\r
8517                                                 }\r
8519                                                 return '';\r
8520                                         } else {\r
8521                                                 d.pop();\r
8523                                                 if (d.length && d[d.length - 1].close) {\r
8524                                                         a = a + '</' + d[d.length - 1].tag + '>';\r
8525                                                         d.pop();\r
8526                                                 }\r
8527                                         }\r
8528                                 } else {\r
8529                                         // Ignore these\r
8530                                         if (/^(br|hr|input|meta|img|link|param)$/i.test(c))\r
8531                                                 return a;\r
8533                                         // Ignore closed ones\r
8534                                         if (/\/>$/.test(a))\r
8535                                                 return a;\r
8537                                         d.push({tag : c}); // Push start element\r
8538                                 }\r
8540                                 return a;\r
8541                         });\r
8543                         // End all open tags\r
8544                         for (i=d.length - 1; i>=0; i--)\r
8545                                 s += '</' + d[i].tag + '>';\r
8547                         return s;\r
8548                 }\r
8550                 });\r
8551 })();\r
8553 /* file:jscripts/tiny_mce/classes/EditorCommands.js */\r
8555 (function() {\r
8556         var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;\r
8558         tinymce.create('tinymce.EditorCommands', {\r
8559                 EditorCommands : function(ed) {\r
8560                         this.editor = ed;\r
8561                 },\r
8563                 execCommand : function(cmd, ui, val) {\r
8564                         var t = this, ed = t.editor, f;\r
8566                         switch (cmd) {\r
8567                                 case 'Cut':\r
8568                                 case 'Copy':\r
8569                                 case 'Paste':\r
8570                                         try {\r
8571                                                 ed.getDoc().execCommand(cmd, ui, val);\r
8572                                         } catch (ex) {\r
8573                                                 if (isGecko) {\r
8574                                                         ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {\r
8575                                                                 if (s)\r
8576                                                                         window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');\r
8577                                                         });\r
8578                                                 } else\r
8579                                                         ed.windowManager.alert(ed.getLang('clipboard_no_support'));\r
8580                                         }\r
8582                                         return true;\r
8584                                 // Ignore these\r
8585                                 case 'mceResetDesignMode':\r
8586                                 case 'mceBeginUndoLevel':\r
8587                                         return true;\r
8589                                 // Ignore these\r
8590                                 case 'unlink':\r
8591                                         t.UnLink();\r
8592                                         return true;\r
8594                                 // Bundle these together\r
8595                                 case 'JustifyLeft':\r
8596                                 case 'JustifyCenter':\r
8597                                 case 'JustifyRight':\r
8598                                 case 'JustifyFull':\r
8599                                         t.mceJustify(cmd, cmd.substring(7).toLowerCase());\r
8600                                         return true;\r
8602                                 case 'mceEndUndoLevel':\r
8603                                 case 'mceAddUndoLevel':\r
8604                                         ed.undoManager.add();\r
8605                                         return true;\r
8607                                 default:\r
8608                                         f = this[cmd];\r
8610                                         if (f) {\r
8611                                                 f.call(this, ui, val);\r
8612                                                 return true;\r
8613                                         }\r
8614                         }\r
8616                         return false;\r
8617                 },\r
8619                 Indent : function() {\r
8620                         var ed = this.editor, d = ed.dom, s = ed.selection, e, iv, iu;\r
8622                         // Setup indent level\r
8623                         iv = ed.settings.indentation;\r
8624                         iu = /[a-z%]+$/i.exec(iv);\r
8625                         iv = parseInt(iv);\r
8627                         if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
8628                                 each(this._getSelectedBlocks(), function(e) {\r
8629                                         d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);\r
8630                                 });\r
8632                                 return;\r
8633                         }\r
8635                         ed.getDoc().execCommand('Indent', false, null);\r
8637                         if (isIE) {\r
8638                                 d.getParent(s.getNode(), function(n) {\r
8639                                         if (n.nodeName == 'BLOCKQUOTE') {\r
8640                                                 n.dir = n.style.cssText = '';\r
8641                                         }\r
8642                                 });\r
8643                         }\r
8644                 },\r
8646                 Outdent : function() {\r
8647                         var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu;\r
8649                         // Setup indent level\r
8650                         iv = ed.settings.indentation;\r
8651                         iu = /[a-z%]+$/i.exec(iv);\r
8652                         iv = parseInt(iv);\r
8654                         if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
8655                                 each(this._getSelectedBlocks(), function(e) {\r
8656                                         v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);\r
8657                                         d.setStyle(e, 'paddingLeft', v ? v + iu : '');\r
8658                                 });\r
8660                                 return;\r
8661                         }\r
8663                         ed.getDoc().execCommand('Outdent', false, null);\r
8664                 },\r
8666                 mceSetAttribute : function(u, v) {\r
8667                         var ed = this.editor, d = ed.dom, e;\r
8669                         if (e = d.getParent(ed.selection.getNode(), d.isBlock))\r
8670                                 d.setAttrib(e, v.name, v.value);\r
8671                 },\r
8673                 mceSetContent : function(u, v) {\r
8674                         this.editor.setContent(v);\r
8675                 },\r
8677                 mceToggleVisualAid : function() {\r
8678                         var ed = this.editor;\r
8680                         ed.hasVisual = !ed.hasVisual;\r
8681                         ed.addVisual();\r
8682                 },\r
8684                 mceReplaceContent : function(u, v) {\r
8685                         var s = this.editor.selection;\r
8687                         s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'})));\r
8688                 },\r
8690                 mceInsertLink : function(u, v) {\r
8691                         var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A');\r
8693                         if (tinymce.is(v, 'string'))\r
8694                                 v = {href : v};\r
8696                         function set(e) {\r
8697                                 each(v, function(v, k) {\r
8698                                         ed.dom.setAttrib(e, k, v);\r
8699                                 });\r
8700                         };\r
8702                         if (!e) {\r
8703                                 ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');\r
8704                                 each(ed.dom.select('a'), function(e) {\r
8705                                         if (e.href == 'javascript:mctmp(0);')\r
8706                                                 set(e);\r
8707                                 });\r
8708                         } else {\r
8709                                 if (v.href)\r
8710                                         set(e);\r
8711                                 else\r
8712                                         ed.dom.remove(e, 1);\r
8713                         }\r
8714                 },\r
8716                 UnLink : function() {\r
8717                         var ed = this.editor, s = ed.selection;\r
8719                         if (s.isCollapsed())\r
8720                                 s.select(s.getNode());\r
8722                         ed.getDoc().execCommand('unlink', false, null);\r
8723                         s.collapse(0);\r
8724                 },\r
8726                 FontName : function(u, v) {\r
8727                         var t = this, ed = t.editor, s = ed.selection, e;\r
8729                         if (!v) {\r
8730                                 if (s.isCollapsed())\r
8731                                         s.select(s.getNode());\r
8733                                 t.RemoveFormat();\r
8734                         } else\r
8735                                 ed.getDoc().execCommand('FontName', false, v);\r
8736                 },\r
8738                 FontSize : function(u, v) {\r
8739                         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
8741                         // Remove style sizes\r
8742                         each(ed.dom.select('font'), function(e) {\r
8743                                 e.style.fontSize = '';\r
8744                         });\r
8746                         // Let the browser add new size it will remove unneded ones in some browsers\r
8747                         ed.getDoc().execCommand('FontSize', false, v);\r
8749                         // Add style values\r
8750                         if (s.inline_styles) {\r
8751                                 each(ed.dom.select('font'), function(e) {\r
8752                                         // Try remove redundant font elements\r
8753                                         if (e.parentNode.nodeName == 'FONT' && e.size == e.parentNode.size) {\r
8754                                                 if (!bm)\r
8755                                                         bm = ed.selection.getBookmark();\r
8757                                                 ed.dom.remove(e, 1);\r
8758                                                 return;\r
8759                                         }\r
8761                                         // Setup font size based on font size value\r
8762                                         if (v = e.size) {\r
8763                                                 if (fzc && fzc.length > 0)\r
8764                                                         ed.dom.setAttrib(e, 'class', fzc[parseInt(v) - 1]);\r
8765                                                 else\r
8766                                                         ed.dom.setStyle(e, 'fontSize', fz[parseInt(v) - 1]);\r
8767                                         }\r
8768                                 });\r
8769                         }\r
8771                         ed.selection.moveToBookmark(bm);\r
8772                 },\r
8774                 queryCommandValue : function(c) {\r
8775                         var f = this['queryValue' + c];\r
8777                         if (f)\r
8778                                 return f.call(this, c);\r
8780                         return false;\r
8781                 },\r
8783                 queryCommandState : function(cmd) {\r
8784                         var f;\r
8786                         switch (cmd) {\r
8787                                 // Bundle these together\r
8788                                 case 'JustifyLeft':\r
8789                                 case 'JustifyCenter':\r
8790                                 case 'JustifyRight':\r
8791                                 case 'JustifyFull':\r
8792                                         return this.queryStateJustify(cmd, cmd.substring(7).toLowerCase());\r
8794                                 default:\r
8795                                         if (f = this['queryState' + cmd])\r
8796                                                 return f.call(this, cmd);\r
8797                         }\r
8799                         return -1;\r
8800                 },\r
8802                 _queryState : function(c) {\r
8803                         try {\r
8804                                 return this.editor.getDoc().queryCommandState(c);\r
8805                         } catch (ex) {\r
8806                                 // Ignore exception\r
8807                         }\r
8808                 },\r
8810                 _queryVal : function(c) {\r
8811                         try {\r
8812                                 return this.editor.getDoc().queryCommandValue(c);\r
8813                         } catch (ex) {\r
8814                                 // Ignore exception\r
8815                         }\r
8816                 },\r
8818                 queryValueFontSize : function() {\r
8819                         var ed = this.editor, v = 0, p;\r
8821                         if (isOpera || isWebKit) {\r
8822                                 if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
8823                                         v = p.size;\r
8825                                 return v;\r
8826                         }\r
8828                         return this._queryVal('FontSize');\r
8829                 },\r
8831                 queryValueFontName : function() {\r
8832                         var ed = this.editor, v = 0, p;\r
8834                         if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
8835                                 v = p.face;\r
8837                         if (!v)\r
8838                                 v = this._queryVal('FontName');\r
8840                         return v;\r
8841                 },\r
8843                 mceJustify : function(c, v) {\r
8844                         var ed = this.editor, se = ed.selection, n = se.getNode(), nn = n.nodeName, bl, nb, dom = ed.dom, rm;\r
8846                         if (ed.settings.inline_styles && this.queryStateJustify(c, v))\r
8847                                 rm = 1;\r
8849                         bl = dom.getParent(n, ed.dom.isBlock);\r
8851                         if (nn == 'IMG') {\r
8852                                 if (v == 'full')\r
8853                                         return;\r
8855                                 if (rm) {\r
8856                                         if (v == 'center')\r
8857                                                 dom.setStyle(bl || n.parentNode, 'textAlign', '');\r
8859                                         dom.setStyle(n, 'float', '');\r
8860                                         this.mceRepaint();\r
8861                                         return;\r
8862                                 }\r
8864                                 if (v == 'center') {\r
8865                                         // Do not change table elements\r
8866                                         if (bl && /^(TD|TH)$/.test(bl.nodeName))\r
8867                                                 bl = 0;\r
8869                                         if (!bl || bl.childNodes.length > 1) {\r
8870                                                 nb = dom.create('p');\r
8871                                                 nb.appendChild(n.cloneNode(false));\r
8873                                                 if (bl)\r
8874                                                         dom.insertAfter(nb, bl);\r
8875                                                 else\r
8876                                                         dom.insertAfter(nb, n);\r
8878                                                 dom.remove(n);\r
8879                                                 n = nb.firstChild;\r
8880                                                 bl = nb;\r
8881                                         }\r
8883                                         dom.setStyle(bl, 'textAlign', v);\r
8884                                         dom.setStyle(n, 'float', '');\r
8885                                 } else {\r
8886                                         dom.setStyle(n, 'float', v);\r
8887                                         dom.setStyle(bl || n.parentNode, 'textAlign', '');\r
8888                                 }\r
8890                                 this.mceRepaint();\r
8891                                 return;\r
8892                         }\r
8894                         // Handle the alignment outselfs, less quirks in all browsers\r
8895                         if (ed.settings.inline_styles && ed.settings.forced_root_block) {\r
8896                                 if (rm)\r
8897                                         v = '';\r
8899                                 each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {\r
8900                                         dom.setAttrib(e, 'align', '');\r
8901                                         dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);\r
8902                                 });\r
8904                                 return;\r
8905                         } else if (!rm)\r
8906                                 ed.getDoc().execCommand(c, false, null);\r
8908                         if (ed.settings.inline_styles) {\r
8909                                 if (rm) {\r
8910                                         dom.getParent(ed.selection.getNode(), function(n) {\r
8911                                                 if (n.style && n.style.textAlign)\r
8912                                                         dom.setStyle(n, 'textAlign', '');\r
8913                                         });\r
8915                                         return;\r
8916                                 }\r
8918                                 each(dom.select('*'), function(n) {\r
8919                                         var v = n.align;\r
8921                                         if (v) {\r
8922                                                 if (v == 'full')\r
8923                                                         v = 'justify';\r
8925                                                 dom.setStyle(n, 'textAlign', v);\r
8926                                                 dom.setAttrib(n, 'align', '');\r
8927                                         }\r
8928                                 });\r
8929                         }\r
8930                 },\r
8932                 mceSetCSSClass : function(u, v) {\r
8933                         this.mceSetStyleInfo(0, {command : 'setattrib', name : 'class', value : v});\r
8934                 },\r
8936                 getSelectedElement : function() {\r
8937                         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
8939                         if (se.isCollapsed() || r.item)\r
8940                                 return se.getNode();\r
8942                         // Setup regexp\r
8943                         re = ed.settings.merge_styles_invalid_parents;\r
8944                         if (tinymce.is(re, 'string'))\r
8945                                 re = new RegExp(re, 'i');\r
8947                         if (isIE) {\r
8948                                 r1 = r.duplicate();\r
8949                                 r1.collapse(true);\r
8950                                 sc = r1.parentElement();\r
8952                                 r2 = r.duplicate();\r
8953                                 r2.collapse(false);\r
8954                                 ec = r2.parentElement();\r
8956                                 if (sc != ec) {\r
8957                                         r1.move('character', 1);\r
8958                                         sc = r1.parentElement();\r
8959                                 }\r
8961                                 if (sc == ec) {\r
8962                                         r1 = r.duplicate();\r
8963                                         r1.moveToElementText(sc);\r
8965                                         if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0)\r
8966                                                 return re && re.test(sc.nodeName) ? null : sc;\r
8967                                 }\r
8968                         } else {\r
8969                                 function getParent(n) {\r
8970                                         return dom.getParent(n, function(n) {return n.nodeType == 1;});\r
8971                                 };\r
8973                                 sc = r.startContainer;\r
8974                                 ec = r.endContainer;\r
8975                                 so = r.startOffset;\r
8976                                 eo = r.endOffset;\r
8978                                 if (!r.collapsed) {\r
8979                                         if (sc == ec) {\r
8980                                                 if (so - eo < 2) {\r
8981                                                         if (sc.hasChildNodes()) {\r
8982                                                                 sp = sc.childNodes[so];\r
8983                                                                 return re && re.test(sp.nodeName) ? null : sp;\r
8984                                                         }\r
8985                                                 }\r
8986                                         }\r
8987                                 }\r
8989                                 if (sc.nodeType != 3 || ec.nodeType != 3)\r
8990                                         return null;\r
8992                                 if (so == 0) {\r
8993                                         sp = getParent(sc);\r
8995                                         if (sp && sp.firstChild != sc)\r
8996                                                 sp = null;\r
8997                                 }\r
8999                                 if (so == sc.nodeValue.length) {\r
9000                                         e = sc.nextSibling;\r
9002                                         if (e && e.nodeType == 1)\r
9003                                                 sp = sc.nextSibling;\r
9004                                 }\r
9006                                 if (eo == 0) {\r
9007                                         e = ec.previousSibling;\r
9009                                         if (e && e.nodeType == 1)\r
9010                                                 ep = e;\r
9011                                 }\r
9013                                 if (eo == ec.nodeValue.length) {\r
9014                                         ep = getParent(ec);\r
9016                                         if (ep && ep.lastChild != ec)\r
9017                                                 ep = null;\r
9018                                 }\r
9020                                 // Same element\r
9021                                 if (sp == ep)\r
9022                                         return re && sp && re.test(sp.nodeName) ? null : sp;\r
9023                         }\r
9025                         return null;\r
9026                 },\r
9028                 InsertHorizontalRule : function() {\r
9029                         // Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");\r
9030                         if (isGecko || isIE)\r
9031                                 this.editor.selection.setContent('<hr />');\r
9032                         else\r
9033                                 this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');\r
9034                 },\r
9036                 RemoveFormat : function() {\r
9037                         var t = this, ed = t.editor, s = ed.selection, b;\r
9039                         // Safari breaks tables\r
9040                         if (isWebKit)\r
9041                                 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
9042                         else\r
9043                                 ed.getDoc().execCommand('RemoveFormat', false, null);\r
9045                         t.mceSetStyleInfo(0, {command : 'removeformat'});\r
9046                         ed.addVisual();\r
9047                 },\r
9049                 mceSetStyleInfo : function(u, v) {\r
9050                         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
9052                         function set(n, e) {\r
9053                                 if (n.nodeType == 1) {\r
9054                                         switch (v.command) {\r
9055                                                 case 'setattrib':\r
9056                                                         return dom.setAttrib(n, v.name, v.value);\r
9058                                                 case 'setstyle':\r
9059                                                         return dom.setStyle(n, v.name, v.value);\r
9061                                                 case 'removeformat':\r
9062                                                         return dom.setAttrib(n, 'class', '');\r
9063                                         }\r
9064                                 }\r
9065                         };\r
9067                         // Setup regexp\r
9068                         re = ed.settings.merge_styles_invalid_parents;\r
9069                         if (tinymce.is(re, 'string'))\r
9070                                 re = new RegExp(re, 'i');\r
9072                         // Set style info on selected element\r
9073                         if ((e = t.getSelectedElement()) && !ed.settings.force_span_wrappers)\r
9074                                 set(e, 1);\r
9075                         else {\r
9076                                 // Generate wrappers and set styles on them\r
9077                                 d.execCommand('FontName', false, '__');\r
9078                                 each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {\r
9079                                         var sp, e;\r
9081                                         if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {\r
9082                                                 sp = dom.create(nn, {mce_new : '1'});\r
9084                                                 set(sp);\r
9086                                                 each (n.childNodes, function(n) {\r
9087                                                         sp.appendChild(n.cloneNode(true));\r
9088                                                 });\r
9090                                                 dom.replace(sp, n);\r
9091                                         }\r
9092                                 });\r
9093                         }\r
9095                         // Remove wrappers inside new ones\r
9096                         each(dom.select(nn).reverse(), function(n) {\r
9097                                 var p = n.parentNode;\r
9099                                 // Check if it's an old span in a new wrapper\r
9100                                 if (!dom.getAttrib(n, 'mce_new')) {\r
9101                                         // Find new wrapper\r
9102                                         p = dom.getParent(n, function(n) {\r
9103                                                 return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');\r
9104                                         });\r
9106                                         if (p)\r
9107                                                 dom.remove(n, 1);\r
9108                                 }\r
9109                         });\r
9111                         // Merge wrappers with parent wrappers\r
9112                         each(dom.select(nn).reverse(), function(n) {\r
9113                                 var p = n.parentNode;\r
9115                                 if (!p || !dom.getAttrib(n, 'mce_new'))\r
9116                                         return;\r
9118                                 if (ed.settings.force_span_wrappers && p.nodeName != 'SPAN')\r
9119                                         return;\r
9121                                 // Has parent of the same type and only child\r
9122                                 if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1)\r
9123                                         return dom.remove(p, 1);\r
9125                                 // Has parent that is more suitable to have the class and only child\r
9126                                 if (n.nodeType == 1 && (!re || !re.test(p.nodeName)) && p.childNodes.length == 1) {\r
9127                                         set(p); // Set style info on parent instead\r
9128                                         dom.setAttrib(n, 'class', '');\r
9129                                 }\r
9130                         });\r
9132                         // Remove empty wrappers\r
9133                         each(dom.select(nn).reverse(), function(n) {\r
9134                                 if (dom.getAttrib(n, 'mce_new') || (dom.getAttribs(n).length <= 1 && n.className === '')) {\r
9135                                         if (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style'))\r
9136                                                 return dom.remove(n, 1);\r
9138                                         dom.setAttrib(n, 'mce_new', ''); // Remove mce_new marker\r
9139                                 }\r
9140                         });\r
9142                         s.moveToBookmark(b);\r
9143                 },\r
9145                 queryStateJustify : function(c, v) {\r
9146                         var ed = this.editor, n = ed.selection.getNode(), dom = ed.dom;\r
9148                         if (n && n.nodeName == 'IMG') {\r
9149                                 if (dom.getStyle(n, 'float') == v)\r
9150                                         return 1;\r
9152                                 return n.parentNode.style.textAlign == v;\r
9153                         }\r
9155                         n = dom.getParent(ed.selection.getStart(), function(n) {\r
9156                                 return n.nodeType == 1 && n.style.textAlign;\r
9157                         });\r
9159                         if (v == 'full')\r
9160                                 v = 'justify';\r
9162                         if (ed.settings.inline_styles)\r
9163                                 return (n && n.style.textAlign == v);\r
9165                         return this._queryState(c);\r
9166                 },\r
9168                 HiliteColor : function(ui, val) {\r
9169                         var t = this, ed = t.editor, d = ed.getDoc();\r
9171                         function set(s) {\r
9172                                 if (!isGecko)\r
9173                                         return;\r
9175                                 try {\r
9176                                         // Try new Gecko method\r
9177                                         d.execCommand("styleWithCSS", 0, s);\r
9178                                 } catch (ex) {\r
9179                                         // Use old\r
9180                                         d.execCommand("useCSS", 0, !s);\r
9181                                 }\r
9182                         };\r
9184                         if (isGecko || isOpera) {\r
9185                                 set(true);\r
9186                                 d.execCommand('hilitecolor', false, val);\r
9187                                 set(false);\r
9188                         } else\r
9189                                 d.execCommand('BackColor', false, val);\r
9190                 },\r
9192                 Undo : function() {\r
9193                         var ed = this.editor;\r
9195                         if (ed.settings.custom_undo_redo) {\r
9196                                 ed.undoManager.undo();\r
9197                                 ed.nodeChanged();\r
9198                         } else\r
9199                                 ed.getDoc().execCommand('Undo', false, null);\r
9200                 },\r
9202                 Redo : function() {\r
9203                         var ed = this.editor;\r
9205                         if (ed.settings.custom_undo_redo) {\r
9206                                 ed.undoManager.redo();\r
9207                                 ed.nodeChanged();\r
9208                         } else\r
9209                                 ed.getDoc().execCommand('Redo', false, null);\r
9210                 },\r
9212                 FormatBlock : function(ui, val) {\r
9213                         var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b;\r
9215                         function isBlock(n) {\r
9216                                 return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName);\r
9217                         };\r
9219                         bl = dom.getParent(s.getNode(), function(n) {\r
9220                                 return isBlock(n);\r
9221                         });\r
9223                         // IE has an issue where it removes the parent div if you change format on the paragrah in <div><p>Content</p></div>\r
9224                         // FF and Opera doesn't change parent DIV elements if you switch format\r
9225                         if (bl) {\r
9226                                 if ((isIE && isBlock(bl.parentNode)) || bl.nodeName == 'DIV') {\r
9227                                         // Rename block element\r
9228                                         nb = ed.dom.create(val);\r
9230                                         each(dom.getAttribs(bl), function(v) {\r
9231                                                 dom.setAttrib(nb, v.nodeName, dom.getAttrib(bl, v.nodeName));\r
9232                                         });\r
9234                                         b = s.getBookmark();\r
9235                                         dom.replace(nb, bl, 1);\r
9236                                         s.moveToBookmark(b);\r
9237                                         ed.nodeChanged();\r
9238                                         return;\r
9239                                 }\r
9240                         }\r
9242                         val = ed.settings.forced_root_block ? (val || '<p>') : val;\r
9244                         if (val.indexOf('<') == -1)\r
9245                                 val = '<' + val + '>';\r
9247                         if (tinymce.isGecko)\r
9248                                 val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1');\r
9250                         ed.getDoc().execCommand('FormatBlock', false, val);\r
9251                 },\r
9253                 mceCleanup : function() {\r
9254                         var ed = this.editor, s = ed.selection, b = s.getBookmark();\r
9255                         ed.setContent(ed.getContent());\r
9256                         s.moveToBookmark(b);\r
9257                 },\r
9259                 mceRemoveNode : function(ui, val) {\r
9260                         var ed = this.editor, s = ed.selection, b, n = val || s.getNode();\r
9262                         // Make sure that the body node isn't removed\r
9263                         if (n == ed.getBody())\r
9264                                 return;\r
9266                         b = s.getBookmark();\r
9267                         ed.dom.remove(n, 1);\r
9268                         s.moveToBookmark(b);\r
9269                         ed.nodeChanged();\r
9270                 },\r
9272                 mceSelectNodeDepth : function(ui, val) {\r
9273                         var ed = this.editor, s = ed.selection, c = 0;\r
9275                         ed.dom.getParent(s.getNode(), function(n) {\r
9276                                 if (n.nodeType == 1 && c++ == val) {\r
9277                                         s.select(n);\r
9278                                         ed.nodeChanged();\r
9279                                         return false;\r
9280                                 }\r
9281                         }, ed.getBody());\r
9282                 },\r
9284                 mceSelectNode : function(u, v) {\r
9285                         this.editor.selection.select(v);\r
9286                 },\r
9288                 mceInsertContent : function(ui, val) {\r
9289                         this.editor.selection.setContent(val);\r
9290                 },\r
9292                 mceInsertRawHTML : function(ui, val) {\r
9293                         var ed = this.editor;\r
9295                         ed.selection.setContent('tiny_mce_marker');\r
9296                         ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val));\r
9297                 },\r
9299                 mceRepaint : function() {\r
9300                         var s, b, e = this.editor;\r
9302                         if (tinymce.isGecko) {\r
9303                                 try {\r
9304                                         s = e.selection;\r
9305                                         b = s.getBookmark(true);\r
9307                                         if (s.getSel())\r
9308                                                 s.getSel().selectAllChildren(e.getBody());\r
9310                                         s.collapse(true);\r
9311                                         s.moveToBookmark(b);\r
9312                                 } catch (ex) {\r
9313                                         // Ignore\r
9314                                 }\r
9315                         }\r
9316                 },\r
9318                 queryStateUnderline : function() {\r
9319                         var ed = this.editor, n = ed.selection.getNode();\r
9321                         if (n && n.nodeName == 'A')\r
9322                                 return false;\r
9324                         return this._queryState('Underline');\r
9325                 },\r
9327                 queryStateOutdent : function() {\r
9328                         var ed = this.editor, n;\r
9330                         if (ed.settings.inline_styles) {\r
9331                                 if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
9332                                         return true;\r
9334                                 if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
9335                                         return true;\r
9336                         } else\r
9337                                 return !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE');\r
9339                         return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList();\r
9340                 },\r
9342                 queryStateInsertUnorderedList : function() {\r
9343                         return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL');\r
9344                 },\r
9346                 queryStateInsertOrderedList : function() {\r
9347                         return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL');\r
9348                 },\r
9350                 queryStatemceBlockQuote : function() {\r
9351                         return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9352                 },\r
9354                 mceBlockQuote : function() {\r
9355                         var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;\r
9357                         function getBQ(e) {\r
9358                                 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9359                         };\r
9361                         // Get start/end block\r
9362                         sb = dom.getParent(s.getStart(), dom.isBlock);\r
9363                         eb = dom.getParent(s.getEnd(), dom.isBlock);\r
9365                         // Remove blockquote(s)\r
9366                         if (bq = getBQ(sb)) {\r
9367                                 if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
9368                                         bm = s.getBookmark();\r
9370                                 // Move all elements after the end block into new bq\r
9371                                 if (getBQ(eb)) {\r
9372                                         bq2 = bq.cloneNode(false);\r
9374                                         while (n = eb.nextSibling)\r
9375                                                 bq2.appendChild(n.parentNode.removeChild(n));\r
9376                                 }\r
9378                                 // Add new bq after\r
9379                                 if (bq2)\r
9380                                         dom.insertAfter(bq2, bq);\r
9382                                 // Move all selected blocks after the current bq\r
9383                                 nl = t._getSelectedBlocks(sb, eb);\r
9384                                 for (i = nl.length - 1; i >= 0; i--) {\r
9385                                         dom.insertAfter(nl[i], bq);\r
9386                                 }\r
9388                                 // Empty bq, then remove it\r
9389                                 if (/^\s*$/.test(bq.innerHTML))\r
9390                                         dom.remove(bq, 1); // Keep children so boomark restoration works correctly\r
9392                                 // Empty bq, then remote it\r
9393                                 if (bq2 && /^\s*$/.test(bq2.innerHTML))\r
9394                                         dom.remove(bq2, 1); // Keep children so boomark restoration works correctly\r
9396                                 if (!bm) {\r
9397                                         // Move caret inside empty block element\r
9398                                         if (!isIE) {\r
9399                                                 r = ed.getDoc().createRange();\r
9400                                                 r.setStart(sb, 0);\r
9401                                                 r.setEnd(sb, 0);\r
9402                                                 s.setRng(r);\r
9403                                         } else {\r
9404                                                 s.select(sb);\r
9405                                                 s.collapse(0);\r
9407                                                 // IE misses the empty block some times element so we must move back the caret\r
9408                                                 if (dom.getParent(s.getStart(), dom.isBlock) != sb) {\r
9409                                                         r = s.getRng();\r
9410                                                         r.move('character', -1);\r
9411                                                         r.select();\r
9412                                                 }\r
9413                                         }\r
9414                                 } else\r
9415                                         t.editor.selection.moveToBookmark(bm);\r
9417                                 return;\r
9418                         }\r
9420                         // Since IE can start with a totally empty document we need to add the first bq and paragraph\r
9421                         if (isIE && !sb && !eb) {\r
9422                                 t.editor.getDoc().execCommand('Indent');\r
9423                                 n = getBQ(s.getNode());\r
9424                                 n.style.margin = n.dir = ''; // IE adds margin and dir to bq\r
9425                                 return;\r
9426                         }\r
9428                         if (!sb || !eb)\r
9429                                 return;\r
9431                         // If empty paragraph node then do not use bookmark\r
9432                         if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
9433                                 bm = s.getBookmark();\r
9435                         // Move selected block elements into a bq\r
9436                         each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {\r
9437                                 // Found existing BQ add to this one\r
9438                                 if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
9439                                         bq = e;\r
9440                                         return;\r
9441                                 }\r
9443                                 // No BQ found, create one\r
9444                                 if (!bq) {\r
9445                                         bq = dom.create('blockquote');\r
9446                                         e.parentNode.insertBefore(bq, e);\r
9447                                 }\r
9449                                 // Add children from existing BQ\r
9450                                 if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
9451                                         n = e.firstChild;\r
9453                                         while (n) {\r
9454                                                 bq.appendChild(n.cloneNode(true));\r
9455                                                 n = n.nextSibling;\r
9456                                         }\r
9458                                         dom.remove(e);\r
9459                                         return;\r
9460                                 }\r
9462                                 // Add non BQ element to BQ\r
9463                                 bq.appendChild(dom.remove(e));\r
9464                         });\r
9466                         if (!bm) {\r
9467                                 // Move caret inside empty block element\r
9468                                 if (!isIE) {\r
9469                                         r = ed.getDoc().createRange();\r
9470                                         r.setStart(sb, 0);\r
9471                                         r.setEnd(sb, 0);\r
9472                                         s.setRng(r);\r
9473                                 } else {\r
9474                                         s.select(sb);\r
9475                                         s.collapse(1);\r
9476                                 }\r
9477                         } else\r
9478                                 s.moveToBookmark(bm);\r
9479                 },\r
9480 /*\r
9481                 _mceBlockQuote : function() {\r
9482                         var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;\r
9484                         function findBQ(e) {\r
9485                                 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9486                         };\r
9488                         // Remove blockquote(s)\r
9489                         if (findBQ(s.getStart())) {\r
9490                                 each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
9491                                         // Found BQ lets remove it\r
9492                                         if (e.nodeName == 'BLOCKQUOTE')\r
9493                                                 dom.remove(e, 1);\r
9494                                 });\r
9496                                 t.editor.selection.moveToBookmark(b);\r
9497                                 return;\r
9498                         }\r
9500                         each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
9501                                 var n;\r
9503                                 // Found existing BQ add to this one\r
9504                                 if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
9505                                         bq = e;\r
9506                                         return;\r
9507                                 }\r
9509                                 // No BQ found, create one\r
9510                                 if (!bq) {\r
9511                                         bq = dom.create('blockquote');\r
9512                                         e.parentNode.insertBefore(bq, e);\r
9513                                 }\r
9515                                 // Add children from existing BQ\r
9516                                 if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
9517                                         n = e.firstChild;\r
9519                                         while (n) {\r
9520                                                 bq.appendChild(n.cloneNode(true));\r
9521                                                 n = n.nextSibling;\r
9522                                         }\r
9524                                         dom.remove(e);\r
9526                                         return;\r
9527                                 }\r
9529                                 // Add non BQ element to BQ\r
9530                                 bq.appendChild(dom.remove(e));\r
9531                         });\r
9533                         t.editor.selection.moveToBookmark(b);\r
9534                 },\r
9535 */\r
9536                 _getSelectedBlocks : function(st, en) {\r
9537                         var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];\r
9539                         sb = dom.getParent(st || s.getStart(), dom.isBlock);\r
9540                         eb = dom.getParent(en || s.getEnd(), dom.isBlock);\r
9542                         if (sb)\r
9543                                 bl.push(sb);\r
9545                         if (sb && eb && sb != eb) {\r
9546                                 n = sb;\r
9548                                 while ((n = n.nextSibling) && n != eb) {\r
9549                                         if (dom.isBlock(n))\r
9550                                                 bl.push(n);\r
9551                                 }\r
9552                         }\r
9554                         if (eb && sb != eb)\r
9555                                 bl.push(eb);\r
9557                         return bl;\r
9558                 }\r
9559         });\r
9560 })();\r
9563 /* file:jscripts/tiny_mce/classes/UndoManager.js */\r
9565 tinymce.create('tinymce.UndoManager', {\r
9566         index : 0,\r
9567         data : null,\r
9568         typing : 0,\r
9570         UndoManager : function(ed) {\r
9571                 var t = this, Dispatcher = tinymce.util.Dispatcher;\r
9573                 t.editor = ed;\r
9574                 t.data = [];\r
9575                 t.onAdd = new Dispatcher(this);\r
9576                 t.onUndo = new Dispatcher(this);\r
9577                 t.onRedo = new Dispatcher(this);\r
9578         },\r
9580         add : function(l) {\r
9581                 var t = this, i, ed = t.editor, b, s = ed.settings, la;\r
9583                 l = l || {};\r
9584                 l.content = l.content || ed.getContent({format : 'raw', no_events : 1});\r
9586                 // Add undo level if needed\r
9587                 l.content = l.content.replace(/^\s*|\s*$/g, '');\r
9588                 la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];\r
9589                 if (!l.initial && la && l.content == la.content)\r
9590                         return null;\r
9592                 // Time to compress\r
9593                 if (s.custom_undo_redo_levels) {\r
9594                         if (t.data.length > s.custom_undo_redo_levels) {\r
9595                                 for (i = 0; i < t.data.length - 1; i++)\r
9596                                         t.data[i] = t.data[i + 1];\r
9598                                 t.data.length--;\r
9599                                 t.index = t.data.length;\r
9600                         }\r
9601                 }\r
9603                 if (s.custom_undo_redo_restore_selection && !l.initial)\r
9604                         l.bookmark = b = l.bookmark || ed.selection.getBookmark();\r
9606                 if (t.index < t.data.length)\r
9607                         t.index++;\r
9609                 // Only initial marked undo levels should be allowed as first item\r
9610                 // This to workaround a bug with Firefox and the blur event\r
9611                 if (t.data.length === 0 && !l.initial)\r
9612                         return null;\r
9614                 // Add level\r
9615                 t.data.length = t.index + 1;\r
9616                 t.data[t.index++] = l;\r
9618                 if (l.initial)\r
9619                         t.index = 0;\r
9621                 // Set initial bookmark use first real undo level\r
9622                 if (t.data.length == 2 && t.data[0].initial)\r
9623                         t.data[0].bookmark = b;\r
9625                 t.onAdd.dispatch(t, l);\r
9626                 ed.isNotDirty = 0;\r
9628                 //console.dir(t.data);\r
9630                 return l;\r
9631         },\r
9633         undo : function() {\r
9634                 var t = this, ed = t.editor, l = l, i;\r
9636                 if (t.typing) {\r
9637                         t.add();\r
9638                         t.typing = 0;\r
9639                 }\r
9641                 if (t.index > 0) {\r
9642                         // If undo on last index then take snapshot\r
9643                         if (t.index == t.data.length && t.index > 1) {\r
9644                                 i = t.index;\r
9645                                 t.typing = 0;\r
9647                                 if (!t.add())\r
9648                                         t.index = i;\r
9650                                 --t.index;\r
9651                         }\r
9653                         l = t.data[--t.index];\r
9654                         ed.setContent(l.content, {format : 'raw'});\r
9655                         ed.selection.moveToBookmark(l.bookmark);\r
9657                         t.onUndo.dispatch(t, l);\r
9658                 }\r
9660                 return l;\r
9661         },\r
9663         redo : function() {\r
9664                 var t = this, ed = t.editor, l = null;\r
9666                 if (t.index < t.data.length - 1) {\r
9667                         l = t.data[++t.index];\r
9668                         ed.setContent(l.content, {format : 'raw'});\r
9669                         ed.selection.moveToBookmark(l.bookmark);\r
9671                         t.onRedo.dispatch(t, l);\r
9672                 }\r
9674                 return l;\r
9675         },\r
9677         clear : function() {\r
9678                 var t = this;\r
9680                 t.data = [];\r
9681                 t.index = 0;\r
9682                 t.typing = 0;\r
9683                 t.add({initial : true});\r
9684         },\r
9686         hasUndo : function() {\r
9687                 return this.index != 0 || this.typing;\r
9688         },\r
9690         hasRedo : function() {\r
9691                 return this.index < this.data.length - 1;\r
9692         }\r
9694         });\r
9695 /* file:jscripts/tiny_mce/classes/ForceBlocks.js */\r
9697 (function() {\r
9698         // Shorten names\r
9699         var Event, isIE, isGecko, isOpera, each, extend;\r
9701         Event = tinymce.dom.Event;\r
9702         isIE = tinymce.isIE;\r
9703         isGecko = tinymce.isGecko;\r
9704         isOpera = tinymce.isOpera;\r
9705         each = tinymce.each;\r
9706         extend = tinymce.extend;\r
9708         tinymce.create('tinymce.ForceBlocks', {\r
9709                 ForceBlocks : function(ed) {\r
9710                         var t = this, s = ed.settings, elm;\r
9712                         t.editor = ed;\r
9713                         t.dom = ed.dom;\r
9714                         elm = (s.forced_root_block || 'p').toLowerCase();\r
9715                         s.element = elm.toUpperCase();\r
9717                         ed.onPreInit.add(t.setup, t);\r
9719                         t.reOpera = new RegExp('(\\u00a0|&#160;|&nbsp;)<\/' + elm + '>', 'gi');\r
9720                         t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');\r
9721                         t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');\r
9722                         t.reNbsp2BR2 = new RegExp('<p( )([^>]+)>(&nbsp;|&#160;)<\\\/p>|<p>(&nbsp;|&#160;)<\\\/p>'.replace(/p/g, elm), 'gi');\r
9723                         t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
9724                         t.reTrailBr = new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
9726                         function padd(ed, o) {\r
9727                                 if (isOpera)\r
9728                                         o.content = o.content.replace(t.reOpera, '</' + elm + '>');\r
9730                                 o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0</' + elm + '>');\r
9732                                 if (!isIE && !isOpera && o.set) {\r
9733                                         // Use &nbsp; instead of BR in padded paragraphs\r
9734                                         o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');\r
9735                                         o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');\r
9736                                 } else {\r
9737                                         o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');\r
9738                                         o.content = o.content.replace(t.reTrailBr, '</' + elm + '>');\r
9739                                 }\r
9740                         };\r
9742                         ed.onBeforeSetContent.add(padd);\r
9743                         ed.onPostProcess.add(padd);\r
9745                         if (s.forced_root_block) {\r
9746                                 ed.onInit.add(t.forceRoots, t);\r
9747                                 ed.onSetContent.add(t.forceRoots, t);\r
9748                                 ed.onBeforeGetContent.add(t.forceRoots, t);\r
9749                         }\r
9750                 },\r
9752                 setup : function() {\r
9753                         var t = this, ed = t.editor, s = ed.settings;\r
9755                         // Force root blocks when typing and when getting output\r
9756                         if (s.forced_root_block) {\r
9757                                 ed.onKeyUp.add(t.forceRoots, t);\r
9758                                 ed.onPreProcess.add(t.forceRoots, t);\r
9759                         }\r
9761                         if (s.force_br_newlines) {\r
9762                                 // Force IE to produce BRs on enter\r
9763                                 if (isIE) {\r
9764                                         ed.onKeyPress.add(function(ed, e) {\r
9765                                                 var n, s = ed.selection;\r
9767                                                 if (e.keyCode == 13 && s.getNode().nodeName != 'LI') {\r
9768                                                         s.setContent('<br id="__" /> ', {format : 'raw'});\r
9769                                                         n = ed.dom.get('__');\r
9770                                                         n.removeAttribute('id');\r
9771                                                         s.select(n);\r
9772                                                         s.collapse();\r
9773                                                         return Event.cancel(e);\r
9774                                                 }\r
9775                                         });\r
9776                                 }\r
9778                                 return;\r
9779                         }\r
9781                         if (!isIE && s.force_p_newlines) {\r
9782 /*                              ed.onPreProcess.add(function(ed, o) {\r
9783                                         each(ed.dom.select('br', o.node), function(n) {\r
9784                                                 var p = n.parentNode;\r
9786                                                 // Replace <p><br /></p> with <p>&nbsp;</p>\r
9787                                                 if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n)) {\r
9788                                                         p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n);\r
9789                                                 }\r
9790                                         });\r
9791                                 });*/\r
9793                                 ed.onKeyPress.add(function(ed, e) {\r
9794                                         if (e.keyCode == 13 && !e.shiftKey) {\r
9795                                                 if (!t.insertPara(e))\r
9796                                                         Event.cancel(e);\r
9797                                         }\r
9798                                 });\r
9800                                 if (isGecko) {\r
9801                                         ed.onKeyDown.add(function(ed, e) {\r
9802                                                 if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey)\r
9803                                                         t.backspaceDelete(e, e.keyCode == 8);\r
9804                                         });\r
9805                                 }\r
9806                         }\r
9808                         function ren(rn, na) {\r
9809                                 var ne = ed.dom.create(na);\r
9811                                 each(rn.attributes, function(a) {\r
9812                                         if (a.specified && a.nodeValue)\r
9813                                                 ne.setAttribute(a.nodeName.toLowerCase(), a.nodeValue);\r
9814                                 });\r
9816                                 each(rn.childNodes, function(n) {\r
9817                                         ne.appendChild(n.cloneNode(true));\r
9818                                 });\r
9820                                 rn.parentNode.replaceChild(ne, rn);\r
9822                                 return ne;\r
9823                         };\r
9825                         // Replaces IE:s auto generated paragraphs with the specified element name\r
9826                         if (isIE && s.element != 'P') {\r
9827                                 ed.onKeyPress.add(function(ed, e) {\r
9828                                         t.lastElm = ed.selection.getNode().nodeName;\r
9829                                 });\r
9831                                 ed.onKeyUp.add(function(ed, e) {\r
9832                                         var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();\r
9834                                         if (b.childNodes.length === 1 && n.nodeName == 'P') {\r
9835                                                 n = ren(n, s.element);\r
9836                                                 sel.select(n);\r
9837                                                 sel.collapse();\r
9838                                                 ed.nodeChanged();\r
9839                                         } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {\r
9840                                                 bl = ed.dom.getParent(n, 'P');\r
9842                                                 if (bl) {\r
9843                                                         ren(bl, s.element);\r
9844                                                         ed.nodeChanged();\r
9845                                                 }\r
9846                                         }\r
9847                                 });\r
9848                         }\r
9849                 },\r
9851                 find : function(n, t, s) {\r
9852                         var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1;\r
9854                         while (n = w.nextNode()) {\r
9855                                 c++;\r
9857                                 // Index by node\r
9858                                 if (t == 0 && n == s)\r
9859                                         return c;\r
9861                                 // Node by index\r
9862                                 if (t == 1 && c == s)\r
9863                                         return n;\r
9864                         }\r
9866                         return -1;\r
9867                 },\r
9869                 forceRoots : function(ed, e) {\r
9870                         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
9871                         var nx, bl, bp, sp, le, nl = b.childNodes, i;\r
9873                         // Fix for bug #1863847\r
9874                         if (e && e.keyCode == 13)\r
9875                                 return true;\r
9877                         // Wrap non blocks into blocks\r
9878                         for (i = nl.length - 1; i >= 0; i--) {\r
9879                                 nx = nl[i];\r
9881                                 // Is text or non block element\r
9882                                 if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) {\r
9883                                         if (!bl) {\r
9884                                                 // Create new block but ignore whitespace\r
9885                                                 if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {\r
9886                                                         // Store selection\r
9887                                                         if (si == -2 && r) {\r
9888                                                                 if (!isIE) {\r
9889                                                                         // If element is inside body, might not be the case in contentEdiable mode\r
9890                                                                         if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) {\r
9891                                                                                 so = r.startOffset;\r
9892                                                                                 eo = r.endOffset;\r
9893                                                                                 si = t.find(b, 0, r.startContainer);\r
9894                                                                                 ei = t.find(b, 0, r.endContainer);\r
9895                                                                         }\r
9896                                                                 } else {\r
9897                                                                         tr = d.body.createTextRange();\r
9898                                                                         tr.moveToElementText(b);\r
9899                                                                         tr.collapse(1);\r
9900                                                                         bp = tr.move('character', c) * -1;\r
9902                                                                         tr = r.duplicate();\r
9903                                                                         tr.collapse(1);\r
9904                                                                         sp = tr.move('character', c) * -1;\r
9906                                                                         tr = r.duplicate();\r
9907                                                                         tr.collapse(0);\r
9908                                                                         le = (tr.move('character', c) * -1) - sp;\r
9910                                                                         si = sp - bp;\r
9911                                                                         ei = le;\r
9912                                                                 }\r
9913                                                         }\r
9915                                                         bl = ed.dom.create(ed.settings.forced_root_block);\r
9916                                                         bl.appendChild(nx.cloneNode(1));\r
9917                                                         nx.parentNode.replaceChild(bl, nx);\r
9918                                                 }\r
9919                                         } else {\r
9920                                                 if (bl.hasChildNodes())\r
9921                                                         bl.insertBefore(nx, bl.firstChild);\r
9922                                                 else\r
9923                                                         bl.appendChild(nx);\r
9924                                         }\r
9925                                 } else\r
9926                                         bl = null; // Time to create new block\r
9927                         }\r
9929                         // Restore selection\r
9930                         if (si != -2) {\r
9931                                 if (!isIE) {\r
9932                                         bl = b.getElementsByTagName(ed.settings.element)[0];\r
9933                                         r = d.createRange();\r
9935                                         // Select last location or generated block\r
9936                                         if (si != -1)\r
9937                                                 r.setStart(t.find(b, 1, si), so);\r
9938                                         else\r
9939                                                 r.setStart(bl, 0);\r
9941                                         // Select last location or generated block\r
9942                                         if (ei != -1)\r
9943                                                 r.setEnd(t.find(b, 1, ei), eo);\r
9944                                         else\r
9945                                                 r.setEnd(bl, 0);\r
9947                                         if (s) {\r
9948                                                 s.removeAllRanges();\r
9949                                                 s.addRange(r);\r
9950                                         }\r
9951                                 } else {\r
9952                                         try {\r
9953                                                 r = s.createRange();\r
9954                                                 r.moveToElementText(b);\r
9955                                                 r.collapse(1);\r
9956                                                 r.moveStart('character', si);\r
9957                                                 r.moveEnd('character', ei);\r
9958                                                 r.select();\r
9959                                         } catch (ex) {\r
9960                                                 // Ignore\r
9961                                         }\r
9962                                 }\r
9963                         }\r
9964                 },\r
9966                 getParentBlock : function(n) {\r
9967                         var d = this.dom;\r
9969                         return d.getParent(n, d.isBlock);\r
9970                 },\r
9972                 insertPara : function(e) {\r
9973                         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
9974                         var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch;\r
9976                         function isEmpty(n) {\r
9977                                 n = n.innerHTML;\r
9978                                 n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars\r
9979                                 n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
9981                                 return n.replace(/[ \t\r\n]+/g, '') == '';\r
9982                         };\r
9984                         // If root blocks are forced then use Operas default behavior since it's really good\r
9985 // Removed due to bug: #1853816\r
9986 //                      if (se.forced_root_block && isOpera)\r
9987 //                              return true;\r
9989                         // Setup before range\r
9990                         rb = d.createRange();\r
9992                         // If is before the first block element and in body, then move it into first block element\r
9993                         rb.setStart(s.anchorNode, s.anchorOffset);\r
9994                         rb.collapse(true);\r
9996                         // Setup after range\r
9997                         ra = d.createRange();\r
9999                         // If is before the first block element and in body, then move it into first block element\r
10000                         ra.setStart(s.focusNode, s.focusOffset);\r
10001                         ra.collapse(true);\r
10003                         // Setup start/end points\r
10004                         dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0;\r
10005                         sn = dir ? s.anchorNode : s.focusNode;\r
10006                         so = dir ? s.anchorOffset : s.focusOffset;\r
10007                         en = dir ? s.focusNode : s.anchorNode;\r
10008                         eo = dir ? s.focusOffset : s.anchorOffset;\r
10010                         // If selection is in empty table cell\r
10011                         if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) {\r
10012                                 dom.remove(sn.firstChild); // Remove BR\r
10014                                 // Create two new block elements\r
10015                                 ed.dom.add(sn, se.element, null, '<br />');\r
10016                                 aft = ed.dom.add(sn, se.element, null, '<br />');\r
10018                                 // Move caret into the last one\r
10019                                 r = d.createRange();\r
10020                                 r.selectNodeContents(aft);\r
10021                                 r.collapse(1);\r
10022                                 ed.selection.setRng(r);\r
10024                                 return false;\r
10025                         }\r
10027                         // If the caret is in an invalid location in FF we need to move it into the first block\r
10028                         if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) {\r
10029                                 sn = en = sn.firstChild;\r
10030                                 so = eo = 0;\r
10031                                 rb = d.createRange();\r
10032                                 rb.setStart(sn, 0);\r
10033                                 ra = d.createRange();\r
10034                                 ra.setStart(en, 0);\r
10035                         }\r
10037                         // Never use body as start or end node\r
10038                         sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes\r
10039                         sn = sn.nodeName == "BODY" ? sn.firstChild : sn;\r
10040                         en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes\r
10041                         en = en.nodeName == "BODY" ? en.firstChild : en;\r
10043                         // Get start and end blocks\r
10044                         sb = t.getParentBlock(sn);\r
10045                         eb = t.getParentBlock(en);\r
10046                         bn = sb ? sb.nodeName : se.element; // Get block name to create\r
10048                         // Return inside list use default browser behavior\r
10049                         if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))\r
10050                                 return true;\r
10052                         // If caption or absolute layers then always generate new blocks within\r
10053                         if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {\r
10054                                 bn = se.element;\r
10055                                 sb = null;\r
10056                         }\r
10058                         // If caption or absolute layers then always generate new blocks within\r
10059                         if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {\r
10060                                 bn = se.element;\r
10061                                 eb = null;\r
10062                         }\r
10064                         // Use P instead\r
10065                         if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {\r
10066                                 bn = se.element;\r
10067                                 sb = eb = null;\r
10068                         }\r
10070                         // Setup new before and after blocks\r
10071                         bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn);\r
10072                         aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn);\r
10074                         // Remove id from after clone\r
10075                         aft.removeAttribute('id');\r
10077                         // Is header and cursor is at the end, then force paragraph under\r
10078                         if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)\r
10079                                 aft = ed.dom.create(se.element);\r
10081                         // Find start chop node\r
10082                         n = sc = sn;\r
10083                         do {\r
10084                                 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))\r
10085                                         break;\r
10087                                 sc = n;\r
10088                         } while ((n = n.previousSibling ? n.previousSibling : n.parentNode));\r
10090                         // Find end chop node\r
10091                         n = ec = en;\r
10092                         do {\r
10093                                 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))\r
10094                                         break;\r
10096                                 ec = n;\r
10097                         } while ((n = n.nextSibling ? n.nextSibling : n.parentNode));\r
10099                         // Place first chop part into before block element\r
10100                         if (sc.nodeName == bn)\r
10101                                 rb.setStart(sc, 0);\r
10102                         else\r
10103                                 rb.setStartBefore(sc);\r
10105                         rb.setEnd(sn, so);\r
10106                         bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari\r
10108                         // Place secnd chop part within new block element\r
10109                         try {\r
10110                                 ra.setEndAfter(ec);\r
10111                         } catch(ex) {\r
10112                                 //console.debug(s.focusNode, s.focusOffset);\r
10113                         }\r
10115                         ra.setStart(en, eo);\r
10116                         aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari\r
10118                         // Create range around everything\r
10119                         r = d.createRange();\r
10120                         if (!sc.previousSibling && sc.parentNode.nodeName == bn) {\r
10121                                 r.setStartBefore(sc.parentNode);\r
10122                         } else {\r
10123                                 if (rb.startContainer.nodeName == bn && rb.startOffset == 0)\r
10124                                         r.setStartBefore(rb.startContainer);\r
10125                                 else\r
10126                                         r.setStart(rb.startContainer, rb.startOffset);\r
10127                         }\r
10129                         if (!ec.nextSibling && ec.parentNode.nodeName == bn)\r
10130                                 r.setEndAfter(ec.parentNode);\r
10131                         else\r
10132                                 r.setEnd(ra.endContainer, ra.endOffset);\r
10134                         // Delete and replace it with new block elements\r
10135                         r.deleteContents();\r
10137                         if (isOpera)\r
10138                                 ed.getWin().scrollTo(0, vp.y);\r
10140                         // Never wrap blocks in blocks\r
10141                         if (bef.firstChild && bef.firstChild.nodeName == bn)\r
10142                                 bef.innerHTML = bef.firstChild.innerHTML;\r
10144                         if (aft.firstChild && aft.firstChild.nodeName == bn)\r
10145                                 aft.innerHTML = aft.firstChild.innerHTML;\r
10147                         // Padd empty blocks\r
10148                         if (isEmpty(bef))\r
10149                                 bef.innerHTML = '<br />';\r
10151                         if (isEmpty(aft))\r
10152                                 aft.innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there\r
10154                         // Opera needs this one backwards for older versions\r
10155                         if (isOpera && parseFloat(opera.version()) < 9.5) {\r
10156                                 r.insertNode(bef);\r
10157                                 r.insertNode(aft);\r
10158                         } else {\r
10159                                 r.insertNode(aft);\r
10160                                 r.insertNode(bef);\r
10161                         }\r
10163                         // Normalize\r
10164                         aft.normalize();\r
10165                         bef.normalize();\r
10167                         function first(n) {\r
10168                                 return d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() || n;\r
10169                         };\r
10171                         // Move cursor and scroll into view\r
10172                         r = d.createRange();\r
10173                         r.selectNodeContents(isGecko ? first(aft) : aft);\r
10174                         r.collapse(1);\r
10175                         s.removeAllRanges();\r
10176                         s.addRange(r);\r
10178                         // 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
10179                         y = ed.dom.getPos(aft).y;\r
10180                         ch = aft.clientHeight;\r
10182                         // Is element within viewport\r
10183                         if (y < vp.y || y + ch > vp.y + vp.h) {\r
10184                                 ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + 25); // Needs to be hardcoded to roughly one line of text if a huge text block is broken into two blocks\r
10185                                 //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
10186                         }\r
10188                         return false;\r
10189                 },\r
10191                 backspaceDelete : function(e, bs) {\r
10192                         var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;\r
10194                         // The caret sometimes gets stuck in Gecko if you delete empty paragraphs\r
10195                         // This workaround removes the element by hand and moves the caret to the previous element\r
10196                         if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) {\r
10197                                 if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) {\r
10198                                         // Find previous block element\r
10199                                         n = sc;\r
10200                                         while ((n = n.previousSibling) && !ed.dom.isBlock(n)) ;\r
10202                                         if (n) {\r
10203                                                 if (sc != b.firstChild) {\r
10204                                                         // Find last text node\r
10205                                                         w = ed.dom.doc.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
10206                                                         while (tn = w.nextNode())\r
10207                                                                 n = tn;\r
10209                                                         // Place caret at the end of last text node\r
10210                                                         r = ed.getDoc().createRange();\r
10211                                                         r.setStart(n, n.nodeValue ? n.nodeValue.length : 0);\r
10212                                                         r.setEnd(n, n.nodeValue ? n.nodeValue.length : 0);\r
10213                                                         se.setRng(r);\r
10215                                                         // Remove the target container\r
10216                                                         ed.dom.remove(sc);\r
10217                                                 }\r
10219                                                 return Event.cancel(e);\r
10220                                         }\r
10221                                 }\r
10222                         }\r
10224                         // Gecko generates BR elements here and there, we don't like those so lets remove them\r
10225                         function handler(e) {\r
10226                                 var pr;\r
10228                                 e = e.target;\r
10230                                 // A new BR was created in a block element, remove it\r
10231                                 if (e && e.parentNode && e.nodeName == 'BR' && (n = t.getParentBlock(e))) {\r
10232                                         pr = e.previousSibling;\r
10234                                         Event.remove(b, 'DOMNodeInserted', handler);\r
10236                                         // Is there whitespace at the end of the node before then we might need the pesky BR\r
10237                                         // to place the caret at a correct location see bug: #2013943\r
10238                                         if (pr && pr.nodeType == 3 && /\s+$/.test(pr.nodeValue))\r
10239                                                 return;\r
10241                                         // Only remove BR elements that got inserted in the middle of the text\r
10242                                         if (e.previousSibling || e.nextSibling)\r
10243                                                 ed.dom.remove(e);\r
10244                                 }\r
10245                         };\r
10247                         // Listen for new nodes\r
10248                         Event._add(b, 'DOMNodeInserted', handler);\r
10250                         // Remove listener\r
10251                         window.setTimeout(function() {\r
10252                                 Event._remove(b, 'DOMNodeInserted', handler);\r
10253                         }, 1);\r
10254                 }\r
10255         });\r
10256 })();\r
10258 /* file:jscripts/tiny_mce/classes/ControlManager.js */\r
10260 (function() {\r
10261         // Shorten names\r
10262         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;\r
10264         tinymce.create('tinymce.ControlManager', {\r
10265                 ControlManager : function(ed, s) {\r
10266                         var t = this, i;\r
10268                         s = s || {};\r
10269                         t.editor = ed;\r
10270                         t.controls = {};\r
10271                         t.onAdd = new tinymce.util.Dispatcher(t);\r
10272                         t.onPostRender = new tinymce.util.Dispatcher(t);\r
10273                         t.prefix = s.prefix || ed.id + '_';\r
10274                         t._cls = {};\r
10276                         t.onPostRender.add(function() {\r
10277                                 each(t.controls, function(c) {\r
10278                                         c.postRender();\r
10279                                 });\r
10280                         });\r
10281                 },\r
10283                 get : function(id) {\r
10284                         return this.controls[this.prefix + id] || this.controls[id];\r
10285                 },\r
10287                 setActive : function(id, s) {\r
10288                         var c = null;\r
10290                         if (c = this.get(id))\r
10291                                 c.setActive(s);\r
10293                         return c;\r
10294                 },\r
10296                 setDisabled : function(id, s) {\r
10297                         var c = null;\r
10299                         if (c = this.get(id))\r
10300                                 c.setDisabled(s);\r
10302                         return c;\r
10303                 },\r
10305                 add : function(c) {\r
10306                         var t = this;\r
10308                         if (c) {\r
10309                                 t.controls[c.id] = c;\r
10310                                 t.onAdd.dispatch(c, t);\r
10311                         }\r
10313                         return c;\r
10314                 },\r
10316                 createControl : function(n) {\r
10317                         var c, t = this, ed = t.editor;\r
10319                         each(ed.plugins, function(p) {\r
10320                                 if (p.createControl) {\r
10321                                         c = p.createControl(n, t);\r
10323                                         if (c)\r
10324                                                 return false;\r
10325                                 }\r
10326                         });\r
10328                         switch (n) {\r
10329                                 case "|":\r
10330                                 case "separator":\r
10331                                         return t.createSeparator();\r
10332                         }\r
10334                         if (!c && ed.buttons && (c = ed.buttons[n]))\r
10335                                 return t.createButton(n, c);\r
10337                         return t.add(c);\r
10338                 },\r
10340                 createDropMenu : function(id, s, cc) {\r
10341                         var t = this, ed = t.editor, c, bm, v, cls;\r
10343                         s = extend({\r
10344                                 'class' : 'mceDropDown',\r
10345                                 constrain : ed.settings.constrain_menus\r
10346                         }, s);\r
10348                         s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';\r
10349                         if (v = ed.getParam('skin_variant'))\r
10350                                 s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);\r
10352                         id = t.prefix + id;\r
10353                         cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;\r
10354                         c = t.controls[id] = new cls(id, s);\r
10355                         c.onAddItem.add(function(c, o) {\r
10356                                 var s = o.settings;\r
10358                                 s.title = ed.getLang(s.title, s.title);\r
10360                                 if (!s.onclick) {\r
10361                                         s.onclick = function(v) {\r
10362                                                 ed.execCommand(s.cmd, s.ui || false, s.value);\r
10363                                         };\r
10364                                 }\r
10365                         });\r
10367                         ed.onRemove.add(function() {\r
10368                                 c.destroy();\r
10369                         });\r
10371                         // Fix for bug #1897785, #1898007\r
10372                         if (tinymce.isIE) {\r
10373                                 c.onShowMenu.add(function() {\r
10374                                         bm = ed.selection.getBookmark(1);\r
10375                                 });\r
10377                                 c.onHideMenu.add(function() {\r
10378                                         if (bm)\r
10379                                                 ed.selection.moveToBookmark(bm);\r
10380                                 });\r
10381                         }\r
10383                         return t.add(c);\r
10384                 },\r
10386                 createListBox : function(id, s, cc) {\r
10387                         var t = this, ed = t.editor, cmd, c, cls;\r
10389                         if (t.get(id))\r
10390                                 return null;\r
10392                         s.title = ed.translate(s.title);\r
10393                         s.scope = s.scope || ed;\r
10395                         if (!s.onselect) {\r
10396                                 s.onselect = function(v) {\r
10397                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10398                                 };\r
10399                         }\r
10401                         s = extend({\r
10402                                 title : s.title,\r
10403                                 'class' : 'mce_' + id,\r
10404                                 scope : s.scope,\r
10405                                 control_manager : t\r
10406                         }, s);\r
10408                         id = t.prefix + id;\r
10410                         if (ed.settings.use_native_selects)\r
10411                                 c = new tinymce.ui.NativeListBox(id, s);\r
10412                         else {\r
10413                                 cls = cc || t._cls.listbox || tinymce.ui.ListBox;\r
10414                                 c = new cls(id, s);\r
10415                         }\r
10417                         t.controls[id] = c;\r
10419                         // Fix focus problem in Safari\r
10420                         if (tinymce.isWebKit) {\r
10421                                 c.onPostRender.add(function(c, n) {\r
10422                                         // Store bookmark on mousedown\r
10423                                         Event.add(n, 'mousedown', function() {\r
10424                                                 ed.bookmark = ed.selection.getBookmark('simple');\r
10425                                         });\r
10427                                         // Restore on focus, since it might be lost\r
10428                                         Event.add(n, 'focus', function() {\r
10429                                                 ed.selection.moveToBookmark(ed.bookmark);\r
10430                                                 ed.bookmark = null;\r
10431                                         });\r
10432                                 });\r
10433                         }\r
10435                         if (c.hideMenu)\r
10436                                 ed.onMouseDown.add(c.hideMenu, c);\r
10438                         return t.add(c);\r
10439                 },\r
10441                 createButton : function(id, s, cc) {\r
10442                         var t = this, ed = t.editor, o, c, cls;\r
10444                         if (t.get(id))\r
10445                                 return null;\r
10447                         s.title = ed.translate(s.title);\r
10448                         s.label = ed.translate(s.label);\r
10449                         s.scope = s.scope || ed;\r
10451                         if (!s.onclick && !s.menu_button) {\r
10452                                 s.onclick = function() {\r
10453                                         ed.execCommand(s.cmd, s.ui || false, s.value);\r
10454                                 };\r
10455                         }\r
10457                         s = extend({\r
10458                                 title : s.title,\r
10459                                 'class' : 'mce_' + id,\r
10460                                 unavailable_prefix : ed.getLang('unavailable', ''),\r
10461                                 scope : s.scope,\r
10462                                 control_manager : t\r
10463                         }, s);\r
10465                         id = t.prefix + id;\r
10467                         if (s.menu_button) {\r
10468                                 cls = cc || t._cls.menubutton || tinymce.ui.MenuButton;\r
10469                                 c = new cls(id, s);\r
10470                                 ed.onMouseDown.add(c.hideMenu, c);\r
10471                         } else {\r
10472                                 cls = t._cls.button || tinymce.ui.Button;\r
10473                                 c = new cls(id, s);\r
10474                         }\r
10476                         return t.add(c);\r
10477                 },\r
10479                 createMenuButton : function(id, s) {\r
10480                         s = s || {};\r
10481                         s.menu_button = 1;\r
10483                         return this.createButton(id, s);\r
10484                 },\r
10486                 createSplitButton : function(id, s, cc) {\r
10487                         var t = this, ed = t.editor, cmd, c, cls;\r
10489                         if (t.get(id))\r
10490                                 return null;\r
10492                         s.title = ed.translate(s.title);\r
10493                         s.scope = s.scope || ed;\r
10495                         if (!s.onclick) {\r
10496                                 s.onclick = function(v) {\r
10497                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10498                                 };\r
10499                         }\r
10501                         if (!s.onselect) {\r
10502                                 s.onselect = function(v) {\r
10503                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10504                                 };\r
10505                         }\r
10507                         s = extend({\r
10508                                 title : s.title,\r
10509                                 'class' : 'mce_' + id,\r
10510                                 scope : s.scope,\r
10511                                 control_manager : t\r
10512                         }, s);\r
10514                         id = t.prefix + id;\r
10515                         cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton;\r
10516                         c = t.add(new cls(id, s));\r
10517                         ed.onMouseDown.add(c.hideMenu, c);\r
10519                         return c;\r
10520                 },\r
10522                 createColorSplitButton : function(id, s, cc) {\r
10523                         var t = this, ed = t.editor, cmd, c, cls, bm;\r
10525                         if (t.get(id))\r
10526                                 return null;\r
10528                         s.title = ed.translate(s.title);\r
10529                         s.scope = s.scope || ed;\r
10531                         if (!s.onclick) {\r
10532                                 s.onclick = function(v) {\r
10533                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10534                                 };\r
10535                         }\r
10537                         if (!s.onselect) {\r
10538                                 s.onselect = function(v) {\r
10539                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10540                                 };\r
10541                         }\r
10543                         s = extend({\r
10544                                 title : s.title,\r
10545                                 'class' : 'mce_' + id,\r
10546                                 'menu_class' : ed.getParam('skin') + 'Skin',\r
10547                                 scope : s.scope,\r
10548                                 more_colors_title : ed.getLang('more_colors')\r
10549                         }, s);\r
10551                         id = t.prefix + id;\r
10552                         cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton;\r
10553                         c = new cls(id, s);\r
10554                         ed.onMouseDown.add(c.hideMenu, c);\r
10556                         // Remove the menu element when the editor is removed\r
10557                         ed.onRemove.add(function() {\r
10558                                 c.destroy();\r
10559                         });\r
10561                         // Fix for bug #1897785, #1898007\r
10562                         if (tinymce.isIE) {\r
10563                                 c.onShowMenu.add(function() {\r
10564                                         bm = ed.selection.getBookmark(1);\r
10565                                 });\r
10567                                 c.onHideMenu.add(function() {\r
10568                                         if (bm) {\r
10569                                                 ed.selection.moveToBookmark(bm);\r
10570                                                 bm = 0;\r
10571                                         }\r
10572                                 });\r
10573                         }\r
10575                         return t.add(c);\r
10576                 },\r
10578                 createToolbar : function(id, s, cc) {\r
10579                         var c, t = this, cls;\r
10581                         id = t.prefix + id;\r
10582                         cls = cc || t._cls.toolbar || tinymce.ui.Toolbar;\r
10583                         c = new cls(id, s);\r
10585                         if (t.get(id))\r
10586                                 return null;\r
10588                         return t.add(c);\r
10589                 },\r
10591                 createSeparator : function(cc) {\r
10592                         var cls = cc || this._cls.separator || tinymce.ui.Separator;\r
10594                         return new cls();\r
10595                 },\r
10597                 setControlType : function(n, c) {\r
10598                         return this._cls[n.toLowerCase()] = c;\r
10599                 },\r
10601                 destroy : function() {\r
10602                         each(this.controls, function(c) {\r
10603                                 c.destroy();\r
10604                         });\r
10606                         this.controls = null;\r
10607                 }\r
10609                 });\r
10610 })();\r
10612 /* file:jscripts/tiny_mce/classes/WindowManager.js */\r
10614 (function() {\r
10615         var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;\r
10617         tinymce.create('tinymce.WindowManager', {\r
10618                 WindowManager : function(ed) {\r
10619                         var t = this;\r
10621                         t.editor = ed;\r
10622                         t.onOpen = new Dispatcher(t);\r
10623                         t.onClose = new Dispatcher(t);\r
10624                         t.params = {};\r
10625                         t.features = {};\r
10626                 },\r
10628                 open : function(s, p) {\r
10629                         var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort(), u;\r
10631                         // Default some options\r
10632                         s = s || {};\r
10633                         p = p || {};\r
10634                         sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window\r
10635                         sh = isOpera ? vp.h : screen.height;\r
10636                         s.name = s.name || 'mc_' + new Date().getTime();\r
10637                         s.width = parseInt(s.width || 320);\r
10638                         s.height = parseInt(s.height || 240);\r
10639                         s.resizable = true;\r
10640                         s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0);\r
10641                         s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0);\r
10642                         p.inline = false;\r
10643                         p.mce_width = s.width;\r
10644                         p.mce_height = s.height;\r
10645                         p.mce_auto_focus = s.auto_focus;\r
10647                         if (mo) {\r
10648                                 if (isIE) {\r
10649                                         s.center = true;\r
10650                                         s.help = false;\r
10651                                         s.dialogWidth = s.width + 'px';\r
10652                                         s.dialogHeight = s.height + 'px';\r
10653                                         s.scroll = s.scrollbars || false;\r
10654                                 }\r
10655                         }\r
10657                         // Build features string\r
10658                         each(s, function(v, k) {\r
10659                                 if (tinymce.is(v, 'boolean'))\r
10660                                         v = v ? 'yes' : 'no';\r
10662                                 if (!/^(name|url)$/.test(k)) {\r
10663                                         if (isIE && mo)\r
10664                                                 f += (f ? ';' : '') + k + ':' + v;\r
10665                                         else\r
10666                                                 f += (f ? ',' : '') + k + '=' + v;\r
10667                                 }\r
10668                         });\r
10670                         t.features = s;\r
10671                         t.params = p;\r
10672                         t.onOpen.dispatch(t, s, p);\r
10674                         u = s.url || s.file;\r
10675                         if (tinymce.relaxedDomain)\r
10676                                 u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;\r
10678                         u = tinymce._addVer(u);\r
10680                         try {\r
10681                                 if (isIE && mo) {\r
10682                                         w = 1;\r
10683                                         window.showModalDialog(u, window, f);\r
10684                                 } else\r
10685                                         w = window.open(u, s.name, f);\r
10686                         } catch (ex) {\r
10687                                 // Ignore\r
10688                         }\r
10690                         if (!w)\r
10691                                 alert(t.editor.getLang('popup_blocked'));\r
10692                 },\r
10694                 close : function(w) {\r
10695                         w.close();\r
10696                         this.onClose.dispatch(this);\r
10697                 },\r
10699                 createInstance : function(cl, a, b, c, d, e) {\r
10700                         var f = tinymce.resolve(cl);\r
10702                         return new f(a, b, c, d, e);\r
10703                 },\r
10705                 confirm : function(t, cb, s, w) {\r
10706                         w = w || window;\r
10708                         cb.call(s || this, w.confirm(this._decode(this.editor.getLang(t, t))));\r
10709                 },\r
10711                 alert : function(tx, cb, s, w) {\r
10712                         var t = this;\r
10714                         w = w || window;\r
10715                         w.alert(t._decode(t.editor.getLang(tx, tx)));\r
10717                         if (cb)\r
10718                                 cb.call(s || t);\r
10719                 },\r
10721                 // Internal functions\r
10723                 _decode : function(s) {\r
10724                         return tinymce.DOM.decode(s).replace(/\\n/g, '\n');\r
10725                 }\r
10727                 });\r
10728 }());