]> git.donarmstrong.com Git - roundcube.git/blob - program/js/tiny_mce/tiny_mce_src.js
Imported Upstream version 0.2~alpha
[roundcube.git] / program / js / tiny_mce / tiny_mce_src.js
1 \r
2 /* file:jscripts/tiny_mce/classes/tinymce.js */\r
3 \r
4 var tinymce = {\r
5         majorVersion : '3',\r
6         minorVersion : '0.6.2',\r
7         releaseDate : '2008-04-07',\r
8 \r
9         _init : function() {\r
10                 var t = this, ua = navigator.userAgent, i, nl, n, base;\r
11 \r
12                 // Browser checks\r
13                 t.isOpera = window.opera && opera.buildNumber;\r
14                 t.isWebKit = /WebKit/.test(ua);\r
15                 t.isOldWebKit = t.isWebKit && !window.getSelection().getRangeAt;\r
16                 t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(navigator.appName);\r
17                 t.isIE6 = t.isIE && /MSIE [56]/.test(ua);\r
18                 t.isGecko = !t.isWebKit && /Gecko/.test(ua);\r
19                 t.isMac = ua.indexOf('Mac') != -1;\r
20 \r
21                 // TinyMCE .NET webcontrol might be setting the values for TinyMCE\r
22                 if (window.tinyMCEPreInit) {\r
23                         t.suffix = tinyMCEPreInit.suffix;\r
24                         t.baseURL = tinyMCEPreInit.base;\r
25                         return;\r
26                 }\r
27 \r
28                 // Get suffix and base\r
29                 t.suffix = '';\r
30 \r
31                 // If base element found, add that infront of baseURL\r
32                 nl = document.getElementsByTagName('base');\r
33                 for (i=0; i<nl.length; i++) {\r
34                         if (nl[i].href)\r
35                                 base = nl[i].href;\r
36                 }\r
37 \r
38                 function getBase(n) {\r
39                         if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) {\r
40                                 if (/_(src|dev)\.js/g.test(n.src))\r
41                                         t.suffix = '_src';\r
42 \r
43                                 t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));\r
44 \r
45                                 // If path to script is relative and a base href was found add that one infront\r
46                                 if (base && t.baseURL.indexOf('://') == -1)\r
47                                         t.baseURL = base + t.baseURL;\r
48 \r
49                                 return t.baseURL;\r
50                         }\r
51 \r
52                         return null;\r
53                 };\r
54 \r
55                 // Check document\r
56                 nl = document.getElementsByTagName('script');\r
57                 for (i=0; i<nl.length; i++) {\r
58                         if (getBase(nl[i]))\r
59                                 return;\r
60                 }\r
61 \r
62                 // Check head\r
63                 n = document.getElementsByTagName('head')[0];\r
64                 if (n) {\r
65                         nl = n.getElementsByTagName('script');\r
66                         for (i=0; i<nl.length; i++) {\r
67                                 if (getBase(nl[i]))\r
68                                         return;\r
69                         }\r
70                 }\r
71 \r
72                 return;\r
73         },\r
74 \r
75         is : function(o, t) {\r
76                 var n = typeof(o);\r
77 \r
78                 if (!t)\r
79                         return n != 'undefined';\r
80 \r
81                 if (t == 'array' && (o instanceof Array))\r
82                         return true;\r
83 \r
84                 return n == t;\r
85         },\r
86 \r
87         // #if !jquery\r
88 \r
89         each : function(o, cb, s) {\r
90                 var n, l;\r
91 \r
92                 if (!o)\r
93                         return 0;\r
94 \r
95                 s = s || o;\r
96 \r
97                 if (typeof(o.length) != 'undefined') {\r
98                         // Indexed arrays, needed for Safari\r
99                         for (n=0, l = o.length; n<l; n++) {\r
100                                 if (cb.call(s, o[n], n, o) === false)\r
101                                         return 0;\r
102                         }\r
103                 } else {\r
104                         // Hashtables\r
105                         for (n in o) {\r
106                                 if (o.hasOwnProperty(n)) {\r
107                                         if (cb.call(s, o[n], n, o) === false)\r
108                                                 return 0;\r
109                                 }\r
110                         }\r
111                 }\r
112 \r
113                 return 1;\r
114         },\r
115 \r
116         map : function(a, f) {\r
117                 var o = [];\r
118 \r
119                 tinymce.each(a, function(v) {\r
120                         o.push(f(v));\r
121                 });\r
122 \r
123                 return o;\r
124         },\r
125 \r
126         grep : function(a, f) {\r
127                 var o = [];\r
128 \r
129                 tinymce.each(a, function(v) {\r
130                         if (!f || f(v))\r
131                                 o.push(v);\r
132                 });\r
133 \r
134                 return o;\r
135         },\r
136 \r
137         inArray : function(a, v) {\r
138                 var i, l;\r
139 \r
140                 if (a) {\r
141                         for (i = 0, l = a.length; i < l; i++) {\r
142                                 if (a[i] === v)\r
143                                         return i;\r
144                         }\r
145                 }\r
146 \r
147                 return -1;\r
148         },\r
149 \r
150         extend : function(o, e) {\r
151                 var i, a = arguments;\r
152 \r
153                 for (i=1; i<a.length; i++) {\r
154                         e = a[i];\r
155 \r
156                         tinymce.each(e, function(v, n) {\r
157                                 if (typeof(v) !== 'undefined')\r
158                                         o[n] = v;\r
159                         });\r
160                 }\r
161 \r
162                 return o;\r
163         },\r
164 \r
165         trim : function(s) {\r
166                 return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');\r
167         },\r
168 \r
169         // #endif\r
170 \r
171         create : function(s, p) {\r
172                 var t = this, sp, ns, cn, scn, c, de = 0;\r
173 \r
174                 // Parse : <prefix> <class>:<super class>\r
175                 s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);\r
176                 cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name\r
177 \r
178                 // Create namespace for new class\r
179                 ns = t.createNS(s[3].replace(/\.\w+$/, ''));\r
180 \r
181                 // Class already exists\r
182                 if (ns[cn])\r
183                         return;\r
184 \r
185                 // Make pure static class\r
186                 if (s[2] == 'static') {\r
187                         ns[cn] = p;\r
188 \r
189                         if (this.onCreate)\r
190                                 this.onCreate(s[2], s[3], ns[cn]);\r
191 \r
192                         return;\r
193                 }\r
194 \r
195                 // Create default constructor\r
196                 if (!p[cn]) {\r
197                         p[cn] = function() {};\r
198                         de = 1;\r
199                 }\r
200 \r
201                 // Add constructor and methods\r
202                 ns[cn] = p[cn];\r
203                 t.extend(ns[cn].prototype, p);\r
204 \r
205                 // Extend\r
206                 if (s[5]) {\r
207                         sp = t.resolve(s[5]).prototype;\r
208                         scn = s[5].match(/\.(\w+)$/i)[1]; // Class name\r
209 \r
210                         // Extend constructor\r
211                         c = ns[cn];\r
212                         if (de) {\r
213                                 // Add passthrough constructor\r
214                                 ns[cn] = function() {\r
215                                         return sp[scn].apply(this, arguments);\r
216                                 };\r
217                         } else {\r
218                                 // Add inherit constructor\r
219                                 ns[cn] = function() {\r
220                                         this.parent = sp[scn];\r
221                                         return c.apply(this, arguments);\r
222                                 };\r
223                         }\r
224                         ns[cn].prototype[cn] = ns[cn];\r
225 \r
226                         // Add super methods\r
227                         t.each(sp, function(f, n) {\r
228                                 ns[cn].prototype[n] = sp[n];\r
229                         });\r
230 \r
231                         // Add overridden methods\r
232                         t.each(p, function(f, n) {\r
233                                 // Extend methods if needed\r
234                                 if (sp[n]) {\r
235                                         ns[cn].prototype[n] = function() {\r
236                                                 this.parent = sp[n];\r
237                                                 return f.apply(this, arguments);\r
238                                         };\r
239                                 } else {\r
240                                         if (n != cn)\r
241                                                 ns[cn].prototype[n] = f;\r
242                                 }\r
243                         });\r
244                 }\r
245 \r
246                 // Add static methods\r
247                 t.each(p['static'], function(f, n) {\r
248                         ns[cn][n] = f;\r
249                 });\r
250 \r
251                 if (this.onCreate)\r
252                         this.onCreate(s[2], s[3], ns[cn].prototype);\r
253         },\r
254 \r
255         walk : function(o, f, n, s) {\r
256                 s = s || this;\r
257 \r
258                 if (o) {\r
259                         if (n)\r
260                                 o = o[n];\r
261 \r
262                         tinymce.each(o, function(o, i) {\r
263                                 if (f.call(s, o, i, n) === false)\r
264                                         return false;\r
265 \r
266                                 tinymce.walk(o, f, n, s);\r
267                         });\r
268                 }\r
269         },\r
270 \r
271         createNS : function(n, o) {\r
272                 var i, v;\r
273 \r
274                 o = o || window;\r
275 \r
276                 n = n.split('.');\r
277                 for (i=0; i<n.length; i++) {\r
278                         v = n[i];\r
279 \r
280                         if (!o[v])\r
281                                 o[v] = {};\r
282 \r
283                         o = o[v];\r
284                 }\r
285 \r
286                 return o;\r
287         },\r
288 \r
289         resolve : function(n, o) {\r
290                 var i, l;\r
291 \r
292                 o = o || window;\r
293 \r
294                 n = n.split('.');\r
295                 for (i=0, l = n.length; i<l; i++) {\r
296                         o = o[n[i]];\r
297 \r
298                         if (!o)\r
299                                 break;\r
300                 }\r
301 \r
302                 return o;\r
303         },\r
304 \r
305         addUnload : function(f, s) {\r
306                 var t = this, w = window, unload;\r
307 \r
308                 f = {func : f, scope : s || this};\r
309 \r
310                 if (!t.unloads) {\r
311                         unload = function() {\r
312                                 var li = t.unloads, o, n;\r
313 \r
314                                 // Call unload handlers\r
315                                 for (n in li) {\r
316                                         o = li[n];\r
317 \r
318                                         if (o && o.func)\r
319                                                 o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy\r
320                                 }\r
321 \r
322                                 // Detach unload function\r
323                                 if (w.detachEvent)\r
324                                         w.detachEvent('onunload', unload);\r
325                                 else if (w.removeEventListener)\r
326                                         w.removeEventListener('unload', unload, false);\r
327 \r
328                                 // Destroy references\r
329                                 o = li = w = unload = null;\r
330 \r
331                                 // Run garbarge collector on IE\r
332                                 if (window.CollectGarbage)\r
333                                         window.CollectGarbage();\r
334                         };\r
335 \r
336                         // Attach unload handler\r
337                         if (w.attachEvent)\r
338                                 w.attachEvent('onunload', unload);\r
339                         else if (w.addEventListener)\r
340                                 w.addEventListener('unload', unload, false);\r
341 \r
342                         // Setup initial unload handler array\r
343                         t.unloads = [f];\r
344                 } else\r
345                         t.unloads.push(f);\r
346 \r
347                 return f;\r
348         },\r
349 \r
350         removeUnload : function(f) {\r
351                 var u = this.unloads, r = null;\r
352 \r
353                 tinymce.each(u, function(o, i) {\r
354                         if (o && o.func == f) {\r
355                                 u.splice(i, 1);\r
356                                 r = f;\r
357                                 return false;\r
358                         }\r
359                 });\r
360 \r
361                 return r;\r
362         },\r
363 \r
364         explode : function(s, d) {\r
365                 return tinymce.map(s.split(d || ','), tinymce.trim);\r
366         }\r
367 \r
368         };\r
369 \r
370 // Required for GZip AJAX loading\r
371 window.tinymce = tinymce;\r
372 \r
373 // Initialize the API\r
374 tinymce._init();\r
375 \r
376 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */\r
377 \r
378 \r
379 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */\r
380 \r
381 \r
382 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */\r
383 \r
384 tinymce.create('tinymce.util.Dispatcher', {\r
385         scope : null,\r
386         listeners : null,\r
387 \r
388         Dispatcher : function(s) {\r
389                 this.scope = s || this;\r
390                 this.listeners = [];\r
391         },\r
392 \r
393         add : function(cb, s) {\r
394                 this.listeners.push({cb : cb, scope : s || this.scope});\r
395 \r
396                 return cb;\r
397         },\r
398 \r
399         addToTop : function(cb, s) {\r
400                 this.listeners.unshift({cb : cb, scope : s || this.scope});\r
401 \r
402                 return cb;\r
403         },\r
404 \r
405         remove : function(cb) {\r
406                 var l = this.listeners, o = null;\r
407 \r
408                 tinymce.each(l, function(c, i) {\r
409                         if (cb == c.cb) {\r
410                                 o = cb;\r
411                                 l.splice(i, 1);\r
412                                 return false;\r
413                         }\r
414                 });\r
415 \r
416                 return o;\r
417         },\r
418 \r
419         dispatch : function() {\r
420                 var s, a = arguments, i, li = this.listeners, c;\r
421 \r
422                 // Needs to be a real loop since the listener count might change while looping\r
423                 // And this is also more efficient\r
424                 for (i = 0; i<li.length; i++) {\r
425                         c = li[i];\r
426                         s = c.cb.apply(c.scope, a);\r
427 \r
428                         if (s === false)\r
429                                 break;\r
430                 }\r
431 \r
432                 return s;\r
433         }\r
434 \r
435         });\r
436 \r
437 /* file:jscripts/tiny_mce/classes/util/URI.js */\r
438 \r
439 (function() {\r
440         var each = tinymce.each;\r
441 \r
442         tinymce.create('tinymce.util.URI', {\r
443                 URI : function(u, s) {\r
444                         var t = this, o, a, b;\r
445 \r
446                         // Default settings\r
447                         s = t.settings = s || {};\r
448 \r
449                         // Strange app protocol or local anchor\r
450                         if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {\r
451                                 t.source = u;\r
452                                 return;\r
453                         }\r
454 \r
455                         // Absolute path with no host, fake host and protocol\r
456                         if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)\r
457                                 u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;\r
458 \r
459                         // Relative path\r
460                         if (u.indexOf('://') === -1 && u.indexOf('//') !== 0)\r
461                                 u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);\r
462 \r
463                         // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)\r
464                         u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something\r
465                         u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);\r
466                         each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {\r
467                                 var s = u[i];\r
468 \r
469                                 // Zope 3 workaround, they use @@something\r
470                                 if (s)\r
471                                         s = s.replace(/\(mce_at\)/g, '@@');\r
472 \r
473                                 t[v] = s;\r
474                         });\r
475 \r
476                         if (b = s.base_uri) {\r
477                                 if (!t.protocol)\r
478                                         t.protocol = b.protocol;\r
479 \r
480                                 if (!t.userInfo)\r
481                                         t.userInfo = b.userInfo;\r
482 \r
483                                 if (!t.port && t.host == 'mce_host')\r
484                                         t.port = b.port;\r
485 \r
486                                 if (!t.host || t.host == 'mce_host')\r
487                                         t.host = b.host;\r
488 \r
489                                 t.source = '';\r
490                         }\r
491 \r
492                         //t.path = t.path || '/';\r
493                 },\r
494 \r
495                 setPath : function(p) {\r
496                         var t = this;\r
497 \r
498                         p = /^(.*?)\/?(\w+)?$/.exec(p);\r
499 \r
500                         // Update path parts\r
501                         t.path = p[0];\r
502                         t.directory = p[1];\r
503                         t.file = p[2];\r
504 \r
505                         // Rebuild source\r
506                         t.source = '';\r
507                         t.getURI();\r
508                 },\r
509 \r
510                 toRelative : function(u) {\r
511                         var t = this, o;\r
512 \r
513                         u = new tinymce.util.URI(u, {base_uri : t});\r
514 \r
515                         // Not on same domain/port or protocol\r
516                         if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)\r
517                                 return u.getURI();\r
518 \r
519                         o = t.toRelPath(t.path, u.path);\r
520 \r
521                         // Add query\r
522                         if (u.query)\r
523                                 o += '?' + u.query;\r
524 \r
525                         // Add anchor\r
526                         if (u.anchor)\r
527                                 o += '#' + u.anchor;\r
528 \r
529                         return o;\r
530                 },\r
531         \r
532                 toAbsolute : function(u, nh) {\r
533                         var u = new tinymce.util.URI(u, {base_uri : this});\r
534 \r
535                         return u.getURI(this.host == u.host ? nh : 0);\r
536                 },\r
537 \r
538                 toRelPath : function(base, path) {\r
539                         var items, bp = 0, out = '', i;\r
540 \r
541                         // Split the paths\r
542                         base = base.substring(0, base.lastIndexOf('/'));\r
543                         base = base.split('/');\r
544                         items = path.split('/');\r
545 \r
546                         if (base.length >= items.length) {\r
547                                 for (i = 0; i < base.length; i++) {\r
548                                         if (i >= items.length || base[i] != items[i]) {\r
549                                                 bp = i + 1;\r
550                                                 break;\r
551                                         }\r
552                                 }\r
553                         }\r
554 \r
555                         if (base.length < items.length) {\r
556                                 for (i = 0; i < items.length; i++) {\r
557                                         if (i >= base.length || base[i] != items[i]) {\r
558                                                 bp = i + 1;\r
559                                                 break;\r
560                                         }\r
561                                 }\r
562                         }\r
563 \r
564                         if (bp == 1)\r
565                                 return path;\r
566 \r
567                         for (i = 0; i < base.length - (bp - 1); i++)\r
568                                 out += "../";\r
569 \r
570                         for (i = bp - 1; i < items.length; i++) {\r
571                                 if (i != bp - 1)\r
572                                         out += "/" + items[i];\r
573                                 else\r
574                                         out += items[i];\r
575                         }\r
576 \r
577                         return out;\r
578                 },\r
579 \r
580                 toAbsPath : function(base, path) {\r
581                         var i, nb = 0, o = [];\r
582 \r
583                         // Split paths\r
584                         base = base.split('/');\r
585                         path = path.split('/');\r
586 \r
587                         // Remove empty chunks\r
588                         each(base, function(k) {\r
589                                 if (k)\r
590                                         o.push(k);\r
591                         });\r
592 \r
593                         base = o;\r
594 \r
595                         // Merge relURLParts chunks\r
596                         for (i = path.length - 1, o = []; i >= 0; i--) {\r
597                                 // Ignore empty or .\r
598                                 if (path[i].length == 0 || path[i] == ".")\r
599                                         continue;\r
600 \r
601                                 // Is parent\r
602                                 if (path[i] == '..') {\r
603                                         nb++;\r
604                                         continue;\r
605                                 }\r
606 \r
607                                 // Move up\r
608                                 if (nb > 0) {\r
609                                         nb--;\r
610                                         continue;\r
611                                 }\r
612 \r
613                                 o.push(path[i]);\r
614                         }\r
615 \r
616                         i = base.length - nb;\r
617 \r
618                         // If /a/b/c or /\r
619                         if (i <= 0)\r
620                                 return '/' + o.reverse().join('/');\r
621 \r
622                         return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');\r
623                 },\r
624 \r
625                 getURI : function(nh) {\r
626                         var s, t = this;\r
627 \r
628                         // Rebuild source\r
629                         if (!t.source || nh) {\r
630                                 s = '';\r
631 \r
632                                 if (!nh) {\r
633                                         if (t.protocol)\r
634                                                 s += t.protocol + '://';\r
635 \r
636                                         if (t.userInfo)\r
637                                                 s += t.userInfo + '@';\r
638 \r
639                                         if (t.host)\r
640                                                 s += t.host;\r
641 \r
642                                         if (t.port)\r
643                                                 s += ':' + t.port;\r
644                                 }\r
645 \r
646                                 if (t.path)\r
647                                         s += t.path;\r
648 \r
649                                 if (t.query)\r
650                                         s += '?' + t.query;\r
651 \r
652                                 if (t.anchor)\r
653                                         s += '#' + t.anchor;\r
654 \r
655                                 t.source = s;\r
656                         }\r
657 \r
658                         return t.source;\r
659                 }\r
660 \r
661                 });\r
662 })();\r
663 \r
664 /* file:jscripts/tiny_mce/classes/util/Cookie.js */\r
665 \r
666 (function() {\r
667         var each = tinymce.each;\r
668 \r
669         tinymce.create('static tinymce.util.Cookie', {\r
670                 getHash : function(n) {\r
671                         var v = this.get(n), h;\r
672 \r
673                         if (v) {\r
674                                 each(v.split('&'), function(v) {\r
675                                         v = v.split('=');\r
676                                         h = h || {};\r
677                                         h[unescape(v[0])] = unescape(v[1]);\r
678                                 });\r
679                         }\r
680 \r
681                         return h;\r
682                 },\r
683 \r
684                 setHash : function(n, v, e, p, d, s) {\r
685                         var o = '';\r
686 \r
687                         each(v, function(v, k) {\r
688                                 o += (!o ? '' : '&') + escape(k) + '=' + escape(v);\r
689                         });\r
690 \r
691                         this.set(n, o, e, p, d, s);\r
692                 },\r
693 \r
694                 get : function(n) {\r
695                         var c = document.cookie, e, p = n + "=", b;\r
696 \r
697                         // Strict mode\r
698                         if (!c)\r
699                                 return;\r
700 \r
701                         b = c.indexOf("; " + p);\r
702 \r
703                         if (b == -1) {\r
704                                 b = c.indexOf(p);\r
705 \r
706                                 if (b != 0)\r
707                                         return null;\r
708                         } else\r
709                                 b += 2;\r
710 \r
711                         e = c.indexOf(";", b);\r
712 \r
713                         if (e == -1)\r
714                                 e = c.length;\r
715 \r
716                         return unescape(c.substring(b + p.length, e));\r
717                 },\r
718 \r
719                 set : function(n, v, e, p, d, s) {\r
720                         document.cookie = n + "=" + escape(v) +\r
721                                 ((e) ? "; expires=" + e.toGMTString() : "") +\r
722                                 ((p) ? "; path=" + escape(p) : "") +\r
723                                 ((d) ? "; domain=" + d : "") +\r
724                                 ((s) ? "; secure" : "");\r
725                 },\r
726 \r
727                 remove : function(n, p) {\r
728                         var d = new Date();\r
729 \r
730                         d.setTime(d.getTime() - 1000);\r
731 \r
732                         this.set(n, '', d, p, d);\r
733                 }\r
734 \r
735                 });\r
736 })();\r
737 \r
738 /* file:jscripts/tiny_mce/classes/util/JSON.js */\r
739 \r
740 tinymce.create('static tinymce.util.JSON', {\r
741         serialize : function(o) {\r
742                 var i, v, s = tinymce.util.JSON.serialize, t;\r
743 \r
744                 if (o == null)\r
745                         return 'null';\r
746 \r
747                 t = typeof o;\r
748 \r
749                 if (t == 'string') {\r
750                         v = '\bb\tt\nn\ff\rr\""\'\'\\\\';\r
751 \r
752                         return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g, function(a, b) {\r
753                                 i = v.indexOf(b);\r
754 \r
755                                 if (i + 1)\r
756                                         return '\\' + v.charAt(i + 1);\r
757 \r
758                                 a = b.charCodeAt().toString(16);\r
759 \r
760                                 return '\\u' + '0000'.substring(a.length) + a;\r
761                         }) + '"';\r
762                 }\r
763 \r
764                 if (t == 'object') {\r
765                         if (o instanceof Array) {\r
766                                         for (i=0, v = '['; i<o.length; i++)\r
767                                                 v += (i > 0 ? ',' : '') + s(o[i]);\r
768 \r
769                                         return v + ']';\r
770                                 }\r
771 \r
772                                 v = '{';\r
773 \r
774                                 for (i in o)\r
775                                         v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';\r
776 \r
777                                 return v + '}';\r
778                 }\r
779 \r
780                 return '' + o;\r
781         },\r
782 \r
783         parse : function(s) {\r
784                 try {\r
785                         return eval('(' + s + ')');\r
786                 } catch (ex) {\r
787                         // Ignore\r
788                 }\r
789         }\r
790 \r
791         });\r
792 \r
793 /* file:jscripts/tiny_mce/classes/util/XHR.js */\r
794 \r
795 tinymce.create('static tinymce.util.XHR', {\r
796         send : function(o) {\r
797                 var x, t, w = window, c = 0;\r
798 \r
799                 // Default settings\r
800                 o.scope = o.scope || this;\r
801                 o.success_scope = o.success_scope || o.scope;\r
802                 o.error_scope = o.error_scope || o.scope;\r
803                 o.async = o.async === false ? false : true;\r
804                 o.data = o.data || '';\r
805 \r
806                 function get(s) {\r
807                         x = 0;\r
808 \r
809                         try {\r
810                                 x = new ActiveXObject(s);\r
811                         } catch (ex) {\r
812                         }\r
813 \r
814                         return x;\r
815                 };\r
816 \r
817                 x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');\r
818 \r
819                 if (x) {\r
820                         if (x.overrideMimeType)\r
821                                 x.overrideMimeType(o.content_type);\r
822 \r
823                         x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);\r
824 \r
825                         if (o.content_type)\r
826                                 x.setRequestHeader('Content-Type', o.content_type);\r
827 \r
828                         x.send(o.data);\r
829 \r
830                         // Wait for response, onReadyStateChange can not be used since it leaks memory in IE\r
831                         t = w.setInterval(function() {\r
832                                 if (x.readyState == 4 || c++ > 10000) {\r
833                                         w.clearInterval(t);\r
834 \r
835                                         if (o.success && c < 10000 && x.status == 200)\r
836                                                 o.success.call(o.success_scope, '' + x.responseText, x, o);\r
837                                         else if (o.error)\r
838                                                 o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);\r
839 \r
840                                         x = null;\r
841                                 }\r
842                         }, 10);\r
843                 }\r
844 \r
845                 }\r
846 });\r
847 \r
848 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */\r
849 \r
850 (function() {\r
851         var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;\r
852 \r
853         tinymce.create('tinymce.util.JSONRequest', {\r
854                 JSONRequest : function(s) {\r
855                         this.settings = extend({\r
856                         }, s);\r
857                         this.count = 0;\r
858                 },\r
859 \r
860                 send : function(o) {\r
861                         var ecb = o.error, scb = o.success;\r
862 \r
863                         o = extend(this.settings, o);\r
864 \r
865                         o.success = function(c, x) {\r
866                                 c = JSON.parse(c);\r
867 \r
868                                 if (typeof(c) == 'undefined') {\r
869                                         c = {\r
870                                                 error : 'JSON Parse error.'\r
871                                         };\r
872                                 }\r
873 \r
874                                 if (c.error)\r
875                                         ecb.call(o.error_scope || o.scope, c.error, x);\r
876                                 else\r
877                                         scb.call(o.success_scope || o.scope, c.result);\r
878                         };\r
879 \r
880                         o.error = function(ty, x) {\r
881                                 ecb.call(o.error_scope || o.scope, ty, x);\r
882                         };\r
883 \r
884                         o.data = JSON.serialize({\r
885                                 id : o.id || 'c' + (this.count++),\r
886                                 method : o.method,\r
887                                 params : o.params\r
888                         });\r
889 \r
890                         // JSON content type for Ruby on rails. Bug: #1883287\r
891                         o.content_type = 'application/json';\r
892 \r
893                         XHR.send(o);\r
894                 },\r
895 \r
896                 'static' : {\r
897                         sendRPC : function(o) {\r
898                                 return new tinymce.util.JSONRequest().send(o);\r
899                         }\r
900                 }\r
901 \r
902                 });\r
903 }());\r
904 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */\r
905 \r
906 (function() {\r
907         // Shorten names\r
908         var each = tinymce.each, is = tinymce.is;\r
909         var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE;\r
910 \r
911         tinymce.create('tinymce.dom.DOMUtils', {\r
912                 doc : null,\r
913                 root : null,\r
914                 files : null,\r
915                 listeners : {},\r
916                 pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,\r
917                 cache : {},\r
918                 idPattern : /^#[\w]+$/,\r
919                 elmPattern : /^[\w_*]+$/,\r
920                 elmClassPattern : /^([\w_]*)\.([\w_]+)$/,\r
921 \r
922                 DOMUtils : function(d, s) {\r
923                         var t = this;\r
924 \r
925                         t.doc = d;\r
926                         t.win = window;\r
927                         t.files = {};\r
928                         t.cssFlicker = false;\r
929                         t.counter = 0;\r
930                         t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; \r
931                         t.stdMode = d.documentMode === 8;\r
932 \r
933                         this.settings = s = tinymce.extend({\r
934                                 keep_values : false,\r
935                                 hex_colors : 1,\r
936                                 process_html : 1\r
937                         }, s);\r
938 \r
939                         // Fix IE6SP2 flicker and check it failed for pre SP2\r
940                         if (tinymce.isIE6) {\r
941                                 try {\r
942                                         d.execCommand('BackgroundImageCache', false, true);\r
943                                 } catch (e) {\r
944                                         t.cssFlicker = true;\r
945                                 }\r
946                         }\r
947 \r
948                         tinymce.addUnload(t.destroy, t);\r
949                 },\r
950 \r
951                 getRoot : function() {\r
952                         var t = this, s = t.settings;\r
953 \r
954                         return (s && t.get(s.root_element)) || t.doc.body;\r
955                 },\r
956 \r
957                 getViewPort : function(w) {\r
958                         var d, b;\r
959 \r
960                         w = !w ? this.win : w;\r
961                         d = w.document;\r
962                         b = this.boxModel ? d.documentElement : d.body;\r
963 \r
964                         // Returns viewport size excluding scrollbars\r
965                         return {\r
966                                 x : w.pageXOffset || b.scrollLeft,\r
967                                 y : w.pageYOffset || b.scrollTop,\r
968                                 w : w.innerWidth || b.clientWidth,\r
969                                 h : w.innerHeight || b.clientHeight\r
970                         };\r
971                 },\r
972 \r
973                 getRect : function(e) {\r
974                         var p, t = this, w, h;\r
975 \r
976                         e = t.get(e);\r
977                         p = t.getPos(e);\r
978                         w = t.getStyle(e, 'width');\r
979                         h = t.getStyle(e, 'height');\r
980 \r
981                         // Non pixel value, then force offset/clientWidth\r
982                         if (w.indexOf('px') === -1)\r
983                                 w = 0;\r
984 \r
985                         // Non pixel value, then force offset/clientWidth\r
986                         if (h.indexOf('px') === -1)\r
987                                 h = 0;\r
988 \r
989                         return {\r
990                                 x : p.x,\r
991                                 y : p.y,\r
992                                 w : parseInt(w) || e.offsetWidth || e.clientWidth,\r
993                                 h : parseInt(h) || e.offsetHeight || e.clientHeight\r
994                         };\r
995                 },\r
996 \r
997                 getParent : function(n, f, r) {\r
998                         var na, se = this.settings;\r
999 \r
1000                         n = this.get(n);\r
1001 \r
1002                         if (se.strict_root)\r
1003                                 r = r || this.getRoot();\r
1004 \r
1005                         // Wrap node name as func\r
1006                         if (is(f, 'string')) {\r
1007                                 na = f.toUpperCase();\r
1008 \r
1009                                 f = function(n) {\r
1010                                         var s = false;\r
1011 \r
1012                                         // Any element\r
1013                                         if (n.nodeType == 1 && na === '*') {\r
1014                                                 s = true;\r
1015                                                 return false;\r
1016                                         }\r
1017 \r
1018                                         each(na.split(','), function(v) {\r
1019                                                 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName == v)) {\r
1020                                                         s = true;\r
1021                                                         return false; // Break loop\r
1022                                                 }\r
1023                                         });\r
1024 \r
1025                                         return s;\r
1026                                 };\r
1027                         }\r
1028 \r
1029                         while (n) {\r
1030                                 if (n == r)\r
1031                                         return null;\r
1032 \r
1033                                 if (f(n))\r
1034                                         return n;\r
1035 \r
1036                                 n = n.parentNode;\r
1037                         }\r
1038 \r
1039                         return null;\r
1040                 },\r
1041 \r
1042                 get : function(e) {\r
1043                         var n;\r
1044 \r
1045                         if (this.doc && typeof(e) == 'string') {\r
1046                                 n = e;\r
1047                                 e = this.doc.getElementById(e);\r
1048 \r
1049                                 // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick\r
1050                                 if (e && e.id !== n)\r
1051                                         return this.doc.getElementsByName(n)[1];\r
1052                         }\r
1053 \r
1054                         return e;\r
1055                 },\r
1056 \r
1057                 // #if !jquery\r
1058 \r
1059                 select : function(pa, s) {\r
1060                         var t = this, cs, c, pl, o = [], x, i, l, n;\r
1061 \r
1062                         s = t.get(s) || t.doc;\r
1063 \r
1064                         // Look for native support and use that if it's found\r
1065                         if (s.querySelectorAll) {\r
1066                                 // Element scope then use temp id\r
1067                                 // We need to do this to be compatible with other implementations\r
1068                                 // See bug report: http://bugs.webkit.org/show_bug.cgi?id=17461\r
1069                                 if (s != t.doc) {\r
1070                                         i = s.id;\r
1071                                         s.id = '_mc_tmp';\r
1072                                         pa = '#_mc_tmp ' + pa;\r
1073                                 }\r
1074 \r
1075                                 // Select elements\r
1076                                 l = tinymce.grep(s.querySelectorAll(pa));\r
1077 \r
1078                                 // Restore old id\r
1079                                 s.id = i;\r
1080 \r
1081                                 return l;\r
1082                         }\r
1083 \r
1084                         if (t.settings.strict) {\r
1085                                 function get(s, n) {\r
1086                                         return s.getElementsByTagName(n.toLowerCase());\r
1087                                 };\r
1088                         } else {\r
1089                                 function get(s, n) {\r
1090                                         return s.getElementsByTagName(n);\r
1091                                 };\r
1092                         }\r
1093 \r
1094                         // Simple element pattern. For example: "p" or "*"\r
1095                         if (t.elmPattern.test(pa)) {\r
1096                                 x = get(s, pa);\r
1097 \r
1098                                 for (i = 0, l = x.length; i<l; i++)\r
1099                                         o.push(x[i]);\r
1100 \r
1101                                 return o;\r
1102                         }\r
1103 \r
1104                         // Simple class pattern. For example: "p.class" or ".class"\r
1105                         if (t.elmClassPattern.test(pa)) {\r
1106                                 pl = t.elmClassPattern.exec(pa);\r
1107                                 x = get(s, pl[1] || '*');\r
1108                                 c = ' ' + pl[2] + ' ';\r
1109 \r
1110                                 for (i = 0, l = x.length; i<l; i++) {\r
1111                                         n = x[i];\r
1112 \r
1113                                         if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1)\r
1114                                                 o.push(n);\r
1115                                 }\r
1116 \r
1117                                 return o;\r
1118                         }\r
1119 \r
1120                         function collect(n) {\r
1121                                 if (!n.mce_save) {\r
1122                                         n.mce_save = 1;\r
1123                                         o.push(n);\r
1124                                 }\r
1125                         };\r
1126 \r
1127                         function collectIE(n) {\r
1128                                 if (!n.getAttribute('mce_save')) {\r
1129                                         n.setAttribute('mce_save', '1');\r
1130                                         o.push(n);\r
1131                                 }\r
1132                         };\r
1133 \r
1134                         function find(n, f, r) {\r
1135                                 var i, l, nl = get(r, n);\r
1136 \r
1137                                 for (i = 0, l = nl.length; i < l; i++)\r
1138                                         f(nl[i]);\r
1139                         };\r
1140 \r
1141                         each(pa.split(','), function(v, i) {\r
1142                                 v = tinymce.trim(v);\r
1143 \r
1144                                 // Simple element pattern, most common in TinyMCE\r
1145                                 if (t.elmPattern.test(v)) {\r
1146                                         each(get(s, v), function(n) {\r
1147                                                 collect(n);\r
1148                                         });\r
1149 \r
1150                                         return;\r
1151                                 }\r
1152 \r
1153                                 // Simple element pattern with class, fairly common in TinyMCE\r
1154                                 if (t.elmClassPattern.test(v)) {\r
1155                                         x = t.elmClassPattern.exec(v);\r
1156 \r
1157                                         each(get(s, x[1]), function(n) {\r
1158                                                 if (t.hasClass(n, x[2]))\r
1159                                                         collect(n);\r
1160                                         });\r
1161 \r
1162                                         return;\r
1163                                 }\r
1164 \r
1165                                 if (!(cs = t.cache[pa])) {\r
1166                                         cs = 'x=(function(cf, s) {';\r
1167                                         pl = v.split(' ');\r
1168 \r
1169                                         each(pl, function(v) {\r
1170                                                 var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v);\r
1171 \r
1172                                                 // Find elements\r
1173                                                 p[1] = p[1] || '*';\r
1174                                                 cs += 'find("' + p[1] + '", function(n) {';\r
1175 \r
1176                                                 // Check id\r
1177                                                 if (p[2])\r
1178                                                         cs += 'if (n.id !== "' + p[2] + '") return;';\r
1179 \r
1180                                                 // Check classes\r
1181                                                 if (p[3]) {\r
1182                                                         cs += 'var c = " " + n.className + " ";';\r
1183                                                         cs += 'if (';\r
1184                                                         c = '';\r
1185                                                         each(p[3].split('.'), function(v) {\r
1186                                                                 if (v)\r
1187                                                                         c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1';\r
1188                                                         });\r
1189                                                         cs += c + ') return;';\r
1190                                                 }\r
1191                                         });\r
1192 \r
1193                                         cs += 'cf(n);';\r
1194 \r
1195                                         for (i = pl.length - 1; i >= 0; i--)\r
1196                                                 cs += '}, ' + (i ? 'n' : 's') + ');';\r
1197 \r
1198                                         cs += '})';\r
1199 \r
1200                                         // Compile CSS pattern function\r
1201                                         t.cache[pa] = cs = eval(cs);\r
1202                                 }\r
1203 \r
1204                                 // Run selector function\r
1205                                 cs(isIE ? collectIE : collect, s);\r
1206                         });\r
1207 \r
1208                         // Cleanup\r
1209                         each(o, function(n) {\r
1210                                 if (isIE)\r
1211                                         n.removeAttribute('mce_save');\r
1212                                 else\r
1213                                         delete n.mce_save;\r
1214                         });\r
1215 \r
1216                         return o;\r
1217                 },\r
1218 \r
1219                 // #endif\r
1220 \r
1221                 add : function(p, n, a, h, c) {\r
1222                         var t = this;\r
1223 \r
1224                         return this.run(p, function(p) {\r
1225                                 var e, k;\r
1226 \r
1227                                 e = is(n, 'string') ? t.doc.createElement(n) : n;\r
1228 \r
1229                                 if (a) {\r
1230                                         for (k in a) {\r
1231                                                 if (a.hasOwnProperty(k) && !is(a[k], 'object'))\r
1232                                                         t.setAttrib(e, k, '' + a[k]);\r
1233                                         }\r
1234 \r
1235                                         if (a.style && !is(a.style, 'string')) {\r
1236                                                 each(a.style, function(v, n) {\r
1237                                                         t.setStyle(e, n, v);\r
1238                                                 });\r
1239                                         }\r
1240                                 }\r
1241 \r
1242                                 if (h) {\r
1243                                         if (h.nodeType)\r
1244                                                 e.appendChild(h);\r
1245                                         else\r
1246                                                 t.setHTML(e, h);\r
1247                                 }\r
1248 \r
1249                                 return !c ? p.appendChild(e) : e;\r
1250                         });\r
1251                 },\r
1252 \r
1253                 create : function(n, a, h) {\r
1254                         return this.add(this.doc.createElement(n), n, a, h, 1);\r
1255                 },\r
1256 \r
1257                 createHTML : function(n, a, h) {\r
1258                         var o = '', t = this, k;\r
1259 \r
1260                         o += '<' + n;\r
1261 \r
1262                         for (k in a) {\r
1263                                 if (a.hasOwnProperty(k))\r
1264                                         o += ' ' + k + '="' + t.encode(a[k]) + '"';\r
1265                         }\r
1266 \r
1267                         if (tinymce.is(h))\r
1268                                 return o + '>' + h + '</' + n + '>';\r
1269 \r
1270                         return o + ' />';\r
1271                 },\r
1272 \r
1273                 remove : function(n, k) {\r
1274                         return this.run(n, function(n) {\r
1275                                 var p, g;\r
1276 \r
1277                                 p = n.parentNode;\r
1278 \r
1279                                 if (!p)\r
1280                                         return null;\r
1281 \r
1282                                 if (k) {\r
1283                                         each (n.childNodes, function(c) {\r
1284                                                 p.insertBefore(c.cloneNode(true), n);\r
1285                                         });\r
1286                                 }\r
1287 \r
1288                                 // Fix IE psuedo leak\r
1289                 /*              if (isIE) {\r
1290                                         p = n.cloneNode(true);\r
1291                                         n.outerHTML = '';\r
1292 \r
1293                                         return p;\r
1294                                 }*/\r
1295 \r
1296                                 return p.removeChild(n);\r
1297                         });\r
1298                 },\r
1299 \r
1300                 // #if !jquery\r
1301 \r
1302                 setStyle : function(n, na, v) {\r
1303                         var t = this;\r
1304 \r
1305                         return t.run(n, function(e) {\r
1306                                 var s, i;\r
1307 \r
1308                                 s = e.style;\r
1309 \r
1310                                 // Camelcase it, if needed\r
1311                                 na = na.replace(/-(\D)/g, function(a, b){\r
1312                                         return b.toUpperCase();\r
1313                                 });\r
1314 \r
1315                                 // Default px suffix on these\r
1316                                 if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))\r
1317                                         v += 'px';\r
1318 \r
1319                                 switch (na) {\r
1320                                         case 'opacity':\r
1321                                                 // IE specific opacity\r
1322                                                 if (isIE) {\r
1323                                                         s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";\r
1324 \r
1325                                                         if (!n.currentStyle || !n.currentStyle.hasLayout)\r
1326                                                                 s.display = 'inline-block';\r
1327                                                 }\r
1328 \r
1329                                                 // Fix for older browsers\r
1330                                                 s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || '';\r
1331                                                 break;\r
1332 \r
1333                                         case 'float':\r
1334                                                 isIE ? s.styleFloat = v : s.cssFloat = v;\r
1335                                                 break;\r
1336                                         \r
1337                                         default:\r
1338                                                 s[na] = v || '';\r
1339                                 }\r
1340 \r
1341                                 // Force update of the style data\r
1342                                 if (t.settings.update_styles)\r
1343                                         t.setAttrib(e, 'mce_style');\r
1344                         });\r
1345                 },\r
1346 \r
1347                 getStyle : function(n, na, c) {\r
1348                         n = this.get(n);\r
1349 \r
1350                         if (!n)\r
1351                                 return false;\r
1352 \r
1353                         // Gecko\r
1354                         if (this.doc.defaultView && c) {\r
1355                                 // Remove camelcase\r
1356                                 na = na.replace(/[A-Z]/g, function(a){\r
1357                                         return '-' + a;\r
1358                                 });\r
1359 \r
1360                                 try {\r
1361                                         return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);\r
1362                                 } catch (ex) {\r
1363                                         // Old safari might fail\r
1364                                         return null;\r
1365                                 }\r
1366                         }\r
1367 \r
1368                         // Camelcase it, if needed\r
1369                         na = na.replace(/-(\D)/g, function(a, b){\r
1370                                 return b.toUpperCase();\r
1371                         });\r
1372 \r
1373                         if (na == 'float')\r
1374                                 na = isIE ? 'styleFloat' : 'cssFloat';\r
1375 \r
1376                         // IE & Opera\r
1377                         if (n.currentStyle && c)\r
1378                                 return n.currentStyle[na];\r
1379 \r
1380                         return n.style[na];\r
1381                 },\r
1382 \r
1383                 setStyles : function(e, o) {\r
1384                         var t = this, s = t.settings, ol;\r
1385 \r
1386                         ol = s.update_styles;\r
1387                         s.update_styles = 0;\r
1388 \r
1389                         each(o, function(v, n) {\r
1390                                 t.setStyle(e, n, v);\r
1391                         });\r
1392 \r
1393                         // Update style info\r
1394                         s.update_styles = ol;\r
1395                         if (s.update_styles)\r
1396                                 t.setAttrib(e, s.cssText);\r
1397                 },\r
1398 \r
1399                 setAttrib : function(e, n, v) {\r
1400                         var t = this;\r
1401 \r
1402                         // Strict XML mode\r
1403                         if (t.settings.strict)\r
1404                                 n = n.toLowerCase();\r
1405 \r
1406                         return this.run(e, function(e) {\r
1407                                 var s = t.settings;\r
1408 \r
1409                                 switch (n) {\r
1410                                         case "style":\r
1411                                                 if (s.keep_values) {\r
1412                                                         if (v)\r
1413                                                                 e.setAttribute('mce_style', v, 2);\r
1414                                                         else\r
1415                                                                 e.removeAttribute('mce_style', 2);\r
1416                                                 }\r
1417 \r
1418                                                 e.style.cssText = v;\r
1419                                                 break;\r
1420 \r
1421                                         case "class":\r
1422                                                 e.className = v || ''; // Fix IE null bug\r
1423                                                 break;\r
1424 \r
1425                                         case "src":\r
1426                                         case "href":\r
1427                                                 if (s.keep_values) {\r
1428                                                         if (s.url_converter)\r
1429                                                                 v = s.url_converter.call(s.url_converter_scope || t, v, n, e);\r
1430 \r
1431                                                         t.setAttrib(e, 'mce_' + n, v, 2);\r
1432                                                 }\r
1433 \r
1434                                                 break;\r
1435                                 }\r
1436 \r
1437                                 if (is(v) && v !== null && v.length !== 0)\r
1438                                         e.setAttribute(n, '' + v, 2);\r
1439                                 else\r
1440                                         e.removeAttribute(n, 2);\r
1441                         });\r
1442                 },\r
1443 \r
1444                 setAttribs : function(e, o) {\r
1445                         var t = this;\r
1446 \r
1447                         return this.run(e, function(e) {\r
1448                                 each(o, function(v, n) {\r
1449                                         t.setAttrib(e, n, v);\r
1450                                 });\r
1451                         });\r
1452                 },\r
1453 \r
1454                 // #endif\r
1455 \r
1456                 getAttrib : function(e, n, dv) {\r
1457                         var v, t = this;\r
1458 \r
1459                         e = t.get(e);\r
1460 \r
1461                         if (!e)\r
1462                                 return false;\r
1463 \r
1464                         if (!is(dv))\r
1465                                 dv = "";\r
1466 \r
1467                         // Try the mce variant for these\r
1468                         if (/^(src|href|style|coords)$/.test(n)) {\r
1469                                 v = e.getAttribute("mce_" + n);\r
1470 \r
1471                                 if (v)\r
1472                                         return v;\r
1473                         }\r
1474 \r
1475                         v = e.getAttribute(n, 2);\r
1476 \r
1477                         if (!v) {\r
1478                                 switch (n) {\r
1479                                         case 'class':\r
1480                                                 v = e.className;\r
1481                                                 break;\r
1482 \r
1483                                         default:\r
1484                                                 // Fix for IE crash Bug: #1884376 probably due to invalid DOM structure\r
1485                                                 if (isIE && n === 'name' && e.nodeName === 'A') {\r
1486                                                         v = e.name;\r
1487                                                         break;\r
1488                                                 }\r
1489 \r
1490                                                 v = e.attributes[n];\r
1491                                                 v = v && is(v.nodeValue) ? v.nodeValue : v;\r
1492                                 }\r
1493                         }\r
1494 \r
1495                         switch (n) {\r
1496                                 case 'style':\r
1497                                         v = v || e.style.cssText;\r
1498 \r
1499                                         if (v) {\r
1500                                                 v = t.serializeStyle(t.parseStyle(v));\r
1501 \r
1502                                                 if (t.settings.keep_values)\r
1503                                                         e.setAttribute('mce_style', v);\r
1504                                         }\r
1505 \r
1506                                         break;\r
1507                         }\r
1508 \r
1509                         // Remove Apple and WebKit stuff\r
1510                         if (isWebKit && n === "class" && v)\r
1511                                 v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');\r
1512 \r
1513                         // Handle IE issues\r
1514                         if (isIE) {\r
1515                                 switch (n) {\r
1516                                         case 'rowspan':\r
1517                                         case 'colspan':\r
1518                                                 // IE returns 1 as default value\r
1519                                                 if (v === 1)\r
1520                                                         v = '';\r
1521 \r
1522                                                 break;\r
1523 \r
1524                                         case 'size':\r
1525                                                 // IE returns +0 as default value for size\r
1526                                                 if (v === '+0')\r
1527                                                         v = '';\r
1528 \r
1529                                                 break;\r
1530 \r
1531                                         case 'hspace':\r
1532                                                 // IE returns -1 as default value\r
1533                                                 if (v === -1)\r
1534                                                         v = '';\r
1535 \r
1536                                                 break;\r
1537 \r
1538                                         case 'tabindex':\r
1539                                                 // IE returns 32768 as default value\r
1540                                                 if (v === 32768)\r
1541                                                         v = '';\r
1542 \r
1543                                                 break;\r
1544 \r
1545                                         case 'shape':\r
1546                                                 v = v.toLowerCase();\r
1547                                                 break;\r
1548 \r
1549                                         default:\r
1550                                                 // IE has odd anonymous function for event attributes\r
1551                                                 if (n.indexOf('on') === 0 && v)\r
1552                                                         v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');\r
1553                                 }\r
1554                         }\r
1555 \r
1556                         return (v && v != '') ? '' + v : dv;\r
1557                 },\r
1558 \r
1559                 getPos : function(n) {\r
1560                         var t = this, x = 0, y = 0, e, d = t.doc, r;\r
1561 \r
1562                         n = t.get(n);\r
1563 \r
1564                         // Use getBoundingClientRect on IE, Opera has it but it's not perfect\r
1565                         if (n && isIE) {\r
1566                                 n = n.getBoundingClientRect();\r
1567                                 e = t.boxModel ? d.documentElement : d.body;\r
1568                                 x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border\r
1569                                 x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;\r
1570                                 n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset\r
1571 \r
1572                                 return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
1573                         }\r
1574 \r
1575                         r = n;\r
1576                         while (r) {\r
1577                                 x += r.offsetLeft || 0;\r
1578                                 y += r.offsetTop || 0;\r
1579                                 r = r.offsetParent;\r
1580                         }\r
1581 \r
1582                         r = n;\r
1583                         while (r) {\r
1584                                 // Opera 9.25 bug fix, fixed in 9.50\r
1585                                 if (!/^table-row|inline.*/i.test(t.getStyle(r, "display", 1))) {\r
1586                                         x -= r.scrollLeft || 0;\r
1587                                         y -= r.scrollTop || 0;\r
1588                                 }\r
1589 \r
1590                                 r = r.parentNode;\r
1591 \r
1592                                 if (r == d.body)\r
1593                                         break;\r
1594                         }\r
1595 \r
1596                         return {x : x, y : y};\r
1597                 },\r
1598 \r
1599                 parseStyle : function(st) {\r
1600                         var t = this, s = t.settings, o = {};\r
1601 \r
1602                         if (!st)\r
1603                                 return o;\r
1604 \r
1605                         function compress(p, s, ot) {\r
1606                                 var t, r, b, l;\r
1607 \r
1608                                 // Get values and check it it needs compressing\r
1609                                 t = o[p + '-top' + s];\r
1610                                 if (!t)\r
1611                                         return;\r
1612 \r
1613                                 r = o[p + '-right' + s];\r
1614                                 if (t != r)\r
1615                                         return;\r
1616 \r
1617                                 b = o[p + '-bottom' + s];\r
1618                                 if (r != b)\r
1619                                         return;\r
1620 \r
1621                                 l = o[p + '-left' + s];\r
1622                                 if (b != l)\r
1623                                         return;\r
1624 \r
1625                                 // Compress\r
1626                                 o[ot] = l;\r
1627                                 delete o[p + '-top' + s];\r
1628                                 delete o[p + '-right' + s];\r
1629                                 delete o[p + '-bottom' + s];\r
1630                                 delete o[p + '-left' + s];\r
1631                         };\r
1632 \r
1633                         function compress2(ta, a, b, c) {\r
1634                                 var t;\r
1635 \r
1636                                 t = o[a];\r
1637                                 if (!t)\r
1638                                         return;\r
1639 \r
1640                                 t = o[b];\r
1641                                 if (!t)\r
1642                                         return;\r
1643 \r
1644                                 t = o[c];\r
1645                                 if (!t)\r
1646                                         return;\r
1647 \r
1648                                 // Compress\r
1649                                 o[ta] = o[a] + ' ' + o[b] + ' ' + o[c];\r
1650                                 delete o[a];\r
1651                                 delete o[b];\r
1652                                 delete o[c];\r
1653                         };\r
1654 \r
1655                         each(st.split(';'), function(v) {\r
1656                                 var sv, ur = [];\r
1657 \r
1658                                 if (v) {\r
1659                                         v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';});\r
1660                                         v = v.split(':');\r
1661                                         sv = tinymce.trim(v[1]);\r
1662                                         sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];});\r
1663 \r
1664                                         sv = sv.replace(/rgb\([^\)]+\)/g, function(v) {\r
1665                                                 return t.toHex(v);\r
1666                                         });\r
1667 \r
1668                                         if (s.url_converter) {\r
1669                                                 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) {\r
1670                                                         return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null)) + ')';\r
1671                                                 });\r
1672                                         }\r
1673 \r
1674                                         o[tinymce.trim(v[0]).toLowerCase()] = sv;\r
1675                                 }\r
1676                         });\r
1677 \r
1678                         compress("border", "", "border");\r
1679                         compress("border", "-width", "border-width");\r
1680                         compress("border", "-color", "border-color");\r
1681                         compress("border", "-style", "border-style");\r
1682                         compress("padding", "", "padding");\r
1683                         compress("margin", "", "margin");\r
1684                         compress2('border', 'border-width', 'border-style', 'border-color');\r
1685 \r
1686                         if (isIE) {\r
1687                                 // Remove pointless border\r
1688                                 if (o.border == 'medium none')\r
1689                                         o.border = '';\r
1690                         }\r
1691 \r
1692                         return o;\r
1693                 },\r
1694 \r
1695                 serializeStyle : function(o) {\r
1696                         var s = '';\r
1697 \r
1698                         each(o, function(v, k) {\r
1699                                 if (k && v) {\r
1700                                         switch (k) {\r
1701                                                 case 'color':\r
1702                                                 case 'background-color':\r
1703                                                         v = v.toLowerCase();\r
1704                                                         break;\r
1705                                         }\r
1706 \r
1707                                         s += (s ? ' ' : '') + k + ': ' + v + ';';\r
1708                                 }\r
1709                         });\r
1710 \r
1711                         return s;\r
1712                 },\r
1713 \r
1714                 loadCSS : function(u) {\r
1715                         var t = this, d = t.doc;\r
1716 \r
1717                         if (!u)\r
1718                                 u = '';\r
1719 \r
1720                         each(u.split(','), function(u) {\r
1721                                 if (t.files[u])\r
1722                                         return;\r
1723 \r
1724                                 t.files[u] = true;\r
1725                                 t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : u});\r
1726                         });\r
1727                 },\r
1728 \r
1729                 // #if !jquery\r
1730 \r
1731                 addClass : function(e, c) {\r
1732                         return this.run(e, function(e) {\r
1733                                 var o;\r
1734 \r
1735                                 if (!c)\r
1736                                         return 0;\r
1737 \r
1738                                 if (this.hasClass(e, c))\r
1739                                         return e.className;\r
1740 \r
1741                                 o = this.removeClass(e, c);\r
1742 \r
1743                                 return e.className = (o != '' ? (o + ' ') : '') + c;\r
1744                         });\r
1745                 },\r
1746 \r
1747                 removeClass : function(e, c) {\r
1748                         var t = this, re;\r
1749 \r
1750                         return t.run(e, function(e) {\r
1751                                 var v;\r
1752 \r
1753                                 if (t.hasClass(e, c)) {\r
1754                                         if (!re)\r
1755                                                 re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");\r
1756 \r
1757                                         v = e.className.replace(re, ' ');\r
1758 \r
1759                                         return e.className = tinymce.trim(v != ' ' ? v : '');\r
1760                                 }\r
1761 \r
1762                                 return e.className;\r
1763                         });\r
1764                 },\r
1765 \r
1766                 hasClass : function(n, c) {\r
1767                         n = this.get(n);\r
1768 \r
1769                         if (!n || !c)\r
1770                                 return false;\r
1771 \r
1772                         return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;\r
1773                 },\r
1774 \r
1775                 show : function(e) {\r
1776                         return this.setStyle(e, 'display', 'block');\r
1777                 },\r
1778 \r
1779                 hide : function(e) {\r
1780                         return this.setStyle(e, 'display', 'none');\r
1781                 },\r
1782 \r
1783                 isHidden : function(e) {\r
1784                         e = this.get(e);\r
1785 \r
1786                         return e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
1787                 },\r
1788 \r
1789                 // #endif\r
1790 \r
1791                 uniqueId : function(p) {\r
1792                         return (!p ? 'mce_' : p) + (this.counter++);\r
1793                 },\r
1794 \r
1795                 setHTML : function(e, h) {\r
1796                         var t = this;\r
1797 \r
1798                         return this.run(e, function(e) {\r
1799                                 var x, i, nl, n, p, x;\r
1800 \r
1801                                 h = t.processHTML(h);\r
1802 \r
1803                                 if (isIE) {\r
1804                                         function set() {\r
1805                                                 try {\r
1806                                                         // IE will remove comments from the beginning\r
1807                                                         // unless you padd the contents with something\r
1808                                                         e.innerHTML = '<br />' + h;\r
1809                                                         e.removeChild(e.firstChild);\r
1810                                                 } catch (ex) {\r
1811                                                         // 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
1812                                                         // This seems to fix this problem\r
1813 \r
1814                                                         // Remove all child nodes\r
1815                                                         while (e.firstChild)\r
1816                                                                 e.firstChild.removeNode();\r
1817 \r
1818                                                         // Create new div with HTML contents and a BR infront to keep comments\r
1819                                                         x = t.create('div');\r
1820                                                         x.innerHTML = '<br />' + h;\r
1821 \r
1822                                                         // Add all children from div to target\r
1823                                                         each (x.childNodes, function(n, i) {\r
1824                                                                 // Skip br element\r
1825                                                                 if (i)\r
1826                                                                         e.appendChild(n);\r
1827                                                         });\r
1828                                                 }\r
1829                                         };\r
1830 \r
1831                                         // IE has a serious bug when it comes to paragraphs it can produce an invalid\r
1832                                         // DOM tree if contents like this <p><ul><li>Item 1</li></ul></p> is inserted\r
1833                                         // It seems to be that IE doesn't like a root block element placed inside another root block element\r
1834                                         if (t.settings.fix_ie_paragraphs)\r
1835                                                 h = h.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi, '<p$1 mce_keep="true">&nbsp;</p>');\r
1836 \r
1837                                         set();\r
1838 \r
1839                                         if (t.settings.fix_ie_paragraphs) {\r
1840                                                 // Check for odd paragraphs this is a sign of a broken DOM\r
1841                                                 nl = e.getElementsByTagName("p");\r
1842                                                 for (i = nl.length - 1, x = 0; i >= 0; i--) {\r
1843                                                         n = nl[i];\r
1844 \r
1845                                                         if (!n.hasChildNodes()) {\r
1846                                                                 if (!n.mce_keep) {\r
1847                                                                         x = 1; // Is broken\r
1848                                                                         break;\r
1849                                                                 }\r
1850 \r
1851                                                                 n.removeAttribute('mce_keep');\r
1852                                                         }\r
1853                                                 }\r
1854                                         }\r
1855 \r
1856                                         // Time to fix the madness IE left us\r
1857                                         if (x) {\r
1858                                                 // So if we replace the p elements with divs and mark them and then replace them back to paragraphs\r
1859                                                 // after we use innerHTML we can fix the DOM tree\r
1860                                                 h = h.replace(/<p([^>]+)>|<p>/g, '<div$1 mce_tmp="1">');\r
1861                                                 h = h.replace(/<\/p>/g, '</div>');\r
1862 \r
1863                                                 // Set the new HTML with DIVs\r
1864                                                 set();\r
1865 \r
1866                                                 // Replace all DIV elements with he mce_tmp attibute back to paragraphs\r
1867                                                 // This is needed since IE has a annoying bug see above for details\r
1868                                                 // This is a slow process but it has to be done. :(\r
1869                                                 if (t.settings.fix_ie_paragraphs) {\r
1870                                                         nl = e.getElementsByTagName("DIV");\r
1871                                                         for (i = nl.length - 1; i >= 0; i--) {\r
1872                                                                 n = nl[i];\r
1873 \r
1874                                                                 // Is it a temp div\r
1875                                                                 if (n.mce_tmp) {\r
1876                                                                         // Create new paragraph\r
1877                                                                         p = t.doc.createElement('p');\r
1878 \r
1879                                                                         // Copy all attributes\r
1880                                                                         n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) {\r
1881                                                                                 var v;\r
1882 \r
1883                                                                                 if (b !== 'mce_tmp') {\r
1884                                                                                         v = n.getAttribute(b);\r
1885 \r
1886                                                                                         if (!v && b === 'class')\r
1887                                                                                                 v = n.className;\r
1888 \r
1889                                                                                         p.setAttribute(b, v);\r
1890                                                                                 }\r
1891                                                                         });\r
1892 \r
1893                                                                         // Append all children to new paragraph\r
1894                                                                         for (x = 0; x<n.childNodes.length; x++)\r
1895                                                                                 p.appendChild(n.childNodes[x].cloneNode(true));\r
1896 \r
1897                                                                         // Replace div with new paragraph\r
1898                                                                         n.swapNode(p);\r
1899                                                                 }\r
1900                                                         }\r
1901                                                 }\r
1902                                         }\r
1903                                 } else\r
1904                                         e.innerHTML = h;\r
1905 \r
1906                                 return h;\r
1907                         });\r
1908                 },\r
1909 \r
1910                 processHTML : function(h) {\r
1911                         var t = this, s = t.settings;\r
1912 \r
1913                         if (!s.process_html)\r
1914                                 return h;\r
1915 \r
1916                         // Convert strong and em to b and i in FF since it can't handle them\r
1917                         if (tinymce.isGecko) {\r
1918                                 h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');\r
1919                                 h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');\r
1920                         }\r
1921 \r
1922                         // Fix some issues\r
1923                         h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open\r
1924 \r
1925                         // Store away src and href in mce_src and mce_href since browsers mess them up\r
1926                         if (s.keep_values) {\r
1927                                 // Wrap scripts in comments for serialization purposes\r
1928                                 if (h.indexOf('<script') !== -1) {\r
1929                                         h = h.replace(/<script>/g, '<script type="text/javascript">');\r
1930                                         h = h.replace(/<script(|[^>]+)>(\s*<!--|\/\/\s*<\[CDATA\[)?[\r\n]*/g, '<mce:script$1><!--\n');\r
1931                                         h = h.replace(/\s*(\/\/\s*-->|\/\/\s*]]>)?<\/script>/g, '\n// --></mce:script>');\r
1932                                         h = h.replace(/<mce:script(|[^>]+)><!--\n\/\/ --><\/mce:script>/g, '<mce:script$1></mce:script>');\r
1933                                 }\r
1934 \r
1935                                 // Process all tags with src, href or style\r
1936                                 h = h.replace(/<([\w:]+) [^>]*(src|href|style|coords)[^>]*>/gi, function(a, n) {\r
1937                                         function handle(m, b, c) {\r
1938                                                 var u = c;\r
1939 \r
1940                                                 // Tag already got a mce_ version\r
1941                                                 if (a.indexOf('mce_' + b) != -1)\r
1942                                                         return m;\r
1943 \r
1944                                                 if (b == 'style') {\r
1945                                                         // Why did I need this one?\r
1946                                                         //if (isIE)\r
1947                                                         //      u = t.serializeStyle(t.parseStyle(u));\r
1948 \r
1949                                                         if (s.hex_colors) {\r
1950                                                                 u = u.replace(/rgb\([^\)]+\)/g, function(v) {\r
1951                                                                         return t.toHex(v);\r
1952                                                                 });\r
1953                                                         }\r
1954 \r
1955                                                         if (s.url_converter) {\r
1956                                                                 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {\r
1957                                                                         return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';\r
1958                                                                 });\r
1959                                                         }\r
1960                                                 } else if (b != 'coords') {\r
1961                                                         if (s.url_converter)\r
1962                                                                 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));\r
1963                                                 }\r
1964 \r
1965                                                 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"';\r
1966                                         };\r
1967 \r
1968                                         a = a.replace(/ (src|href|style|coords)=[\"]([^\"]+)[\"]/gi, handle); // W3C\r
1969                                         a = a.replace(/ (src|href|style|coords)=[\']([^\']+)[\']/gi, handle); // W3C\r
1970 \r
1971                                         return a.replace(/ (src|href|style|coords)=([^\s\"\'>]+)/gi, handle); // IE\r
1972                                 });\r
1973                         }\r
1974 \r
1975                         return h;\r
1976                 },\r
1977 \r
1978                 getOuterHTML : function(e) {\r
1979                         var d;\r
1980 \r
1981                         e = this.get(e);\r
1982 \r
1983                         if (!e)\r
1984                                 return null;\r
1985 \r
1986                         if (isIE)\r
1987                                 return e.outerHTML;\r
1988 \r
1989                         d = (e.ownerDocument || this.doc).createElement("body");\r
1990                         d.appendChild(e.cloneNode(true));\r
1991 \r
1992                         return d.innerHTML;\r
1993                 },\r
1994 \r
1995                 setOuterHTML : function(e, h, d) {\r
1996                         var t = this;\r
1997 \r
1998                         return this.run(e, function(e) {\r
1999                                 var n, tp;\r
2000 \r
2001                                 e = t.get(e);\r
2002                                 d = d || e.ownerDocument || t.doc;\r
2003 \r
2004                                 if (isIE && e.nodeType == 1)\r
2005                                         e.outerHTML = h;\r
2006                                 else {\r
2007                                         tp = d.createElement("body");\r
2008                                         tp.innerHTML = h;\r
2009 \r
2010                                         n = tp.lastChild;\r
2011                                         while (n) {\r
2012                                                 t.insertAfter(n.cloneNode(true), e);\r
2013                                                 n = n.previousSibling;\r
2014                                         }\r
2015 \r
2016                                         t.remove(e);\r
2017                                 }\r
2018                         });\r
2019                 },\r
2020 \r
2021                 decode : function(s) {\r
2022                         var e;\r
2023 \r
2024                         // Look for entities to decode\r
2025                         if (/&[^;]+;/.test(s)) {\r
2026                                 // Decode the entities using a div element not super efficient but less code\r
2027                                 e = this.doc.createElement("div");\r
2028                                 e.innerHTML = s;\r
2029 \r
2030                                 return !e.firstChild ? s : e.firstChild.nodeValue;\r
2031                         }\r
2032 \r
2033                         return s;\r
2034                 },\r
2035 \r
2036                 encode : function(s) {\r
2037                         return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) {\r
2038                                 switch (c) {\r
2039                                         case '&':\r
2040                                                 return '&amp;';\r
2041 \r
2042                                         case '"':\r
2043                                                 return '&quot;';\r
2044 \r
2045                                         case '<':\r
2046                                                 return '&lt;';\r
2047 \r
2048                                         case '>':\r
2049                                                 return '&gt;';\r
2050                                 }\r
2051 \r
2052                                 return c;\r
2053                         }) : s;\r
2054                 },\r
2055 \r
2056                 // #if !jquery\r
2057 \r
2058                 insertAfter : function(n, r) {\r
2059                         var t = this;\r
2060 \r
2061                         r = t.get(r);\r
2062 \r
2063                         return this.run(n, function(n) {\r
2064                                 var p, ns;\r
2065 \r
2066                                 p = r.parentNode;\r
2067                                 ns = r.nextSibling;\r
2068 \r
2069                                 if (ns)\r
2070                                         p.insertBefore(n, ns);\r
2071                                 else\r
2072                                         p.appendChild(n);\r
2073 \r
2074                                 return n;\r
2075                         });\r
2076                 },\r
2077 \r
2078                 // #endif\r
2079 \r
2080                 isBlock : function(n) {\r
2081                         if (n.nodeType && n.nodeType !== 1)\r
2082                                 return false;\r
2083 \r
2084                         n = n.nodeName || n;\r
2085 \r
2086                         return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);\r
2087                 },\r
2088 \r
2089                 // #if !jquery\r
2090 \r
2091                 replace : function(n, o, k) {\r
2092                         if (is(o, 'array'))\r
2093                                 n = n.cloneNode(true);\r
2094 \r
2095                         return this.run(o, function(o) {\r
2096                                 if (k) {\r
2097                                         each(o.childNodes, function(c) {\r
2098                                                 n.appendChild(c.cloneNode(true));\r
2099                                         });\r
2100                                 }\r
2101 \r
2102                                 // Fix IE psuedo leak for elements since replacing elements if fairly common\r
2103                                 if (isIE && o.nodeType === 1) {\r
2104                                         o.parentNode.insertBefore(n, o);\r
2105                                         o.outerHTML = '';\r
2106                                         return n;\r
2107                                 }\r
2108 \r
2109                                 return o.parentNode.replaceChild(n, o);\r
2110                         });\r
2111                 },\r
2112 \r
2113                 // #endif\r
2114 \r
2115                 toHex : function(s) {\r
2116                         var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);\r
2117 \r
2118                         function hex(s) {\r
2119                                 s = parseInt(s).toString(16);\r
2120 \r
2121                                 return s.length > 1 ? s : '0' + s; // 0 -> 00\r
2122                         };\r
2123 \r
2124                         if (c) {\r
2125                                 s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]);\r
2126 \r
2127                                 return s;\r
2128                         }\r
2129 \r
2130                         return s;\r
2131                 },\r
2132 \r
2133                 getClasses : function() {\r
2134                         var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov;\r
2135 \r
2136                         if (t.classes)\r
2137                                 return t.classes;\r
2138 \r
2139                         function addClasses(s) {\r
2140                                 // IE style imports\r
2141                                 each(s.imports, function(r) {\r
2142                                         addClasses(r);\r
2143                                 });\r
2144 \r
2145                                 each(s.cssRules || s.rules, function(r) {\r
2146                                         // Real type or fake it on IE\r
2147                                         switch (r.type || 1) {\r
2148                                                 // Rule\r
2149                                                 case 1:\r
2150                                                         if (r.selectorText) {\r
2151                                                                 each(r.selectorText.split(','), function(v) {\r
2152                                                                         v = v.replace(/^\s*|\s*$|^\s\./g, "");\r
2153 \r
2154                                                                         // Is internal or it doesn't contain a class\r
2155                                                                         if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v))\r
2156                                                                                 return;\r
2157 \r
2158                                                                         // Remove everything but class name\r
2159                                                                         ov = v;\r
2160                                                                         v = v.replace(/.*\.([a-z0-9_\-]+).*/i, '$1');\r
2161 \r
2162                                                                         // Filter classes\r
2163                                                                         if (f && !(v = f(v, ov)))\r
2164                                                                                 return;\r
2165 \r
2166                                                                         if (!lo[v]) {\r
2167                                                                                 cl.push({'class' : v});\r
2168                                                                                 lo[v] = 1;\r
2169                                                                         }\r
2170                                                                 });\r
2171                                                         }\r
2172                                                         break;\r
2173 \r
2174                                                 // Import\r
2175                                                 case 3:\r
2176                                                         addClasses(r.styleSheet);\r
2177                                                         break;\r
2178                                         }\r
2179                                 });\r
2180                         };\r
2181 \r
2182                         try {\r
2183                                 each(t.doc.styleSheets, addClasses);\r
2184                         } catch (ex) {\r
2185                                 // Ignore\r
2186                         }\r
2187 \r
2188                         if (cl.length > 0)\r
2189                                 t.classes = cl;\r
2190 \r
2191                         return cl;\r
2192                 },\r
2193 \r
2194                 run : function(e, f, s) {\r
2195                         var t = this, o;\r
2196 \r
2197                         if (t.doc && typeof(e) === 'string')\r
2198                                 e = t.doc.getElementById(e);\r
2199 \r
2200                         if (!e)\r
2201                                 return false;\r
2202 \r
2203                         s = s || this;\r
2204                         if (!e.nodeType && (e.length || e.length === 0)) {\r
2205                                 o = [];\r
2206 \r
2207                                 each(e, function(e, i) {\r
2208                                         if (e) {\r
2209                                                 if (typeof(e) == 'string')\r
2210                                                         e = t.doc.getElementById(e);\r
2211 \r
2212                                                 o.push(f.call(s, e, i));\r
2213                                         }\r
2214                                 });\r
2215 \r
2216                                 return o;\r
2217                         }\r
2218 \r
2219                         return f.call(s, e);\r
2220                 },\r
2221 \r
2222                 getAttribs : function(n) {\r
2223                         var o;\r
2224 \r
2225                         n = this.get(n);\r
2226 \r
2227                         if (!n)\r
2228                                 return [];\r
2229 \r
2230                         if (isIE) {\r
2231                                 o = [];\r
2232 \r
2233                                 // Object will throw exception in IE\r
2234                                 if (n.nodeName == 'OBJECT')\r
2235                                         return n.attributes;\r
2236 \r
2237                                 // It's crazy that this is faster in IE but it's because it returns all attributes all the time\r
2238                                 n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
2239                                         o.push({specified : 1, nodeName : b});\r
2240                                 });\r
2241 \r
2242                                 return o;\r
2243                         }\r
2244 \r
2245                         return n.attributes;\r
2246                 },\r
2247 \r
2248                 destroy : function(s) {\r
2249                         var t = this;\r
2250 \r
2251                         t.win = t.doc = t.root = null;\r
2252 \r
2253                         // Manual destroy then remove unload handler\r
2254                         if (!s)\r
2255                                 tinymce.removeUnload(t.destroy);\r
2256                 }\r
2257 \r
2258                 /*\r
2259                 walk : function(n, f, s) {\r
2260                         var d = this.doc, w;\r
2261 \r
2262                         if (d.createTreeWalker) {\r
2263                                 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
2264 \r
2265                                 while ((n = w.nextNode()) != null)\r
2266                                         f.call(s || this, n);\r
2267                         } else\r
2268                                 tinymce.walk(n, f, 'childNodes', s);\r
2269                 }\r
2270                 */\r
2271 \r
2272                 /*\r
2273                 toRGB : function(s) {\r
2274                         var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s);\r
2275 \r
2276                         if (c) {\r
2277                                 // #FFF -> #FFFFFF\r
2278                                 if (!is(c[3]))\r
2279                                         c[3] = c[2] = c[1];\r
2280 \r
2281                                 return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")";\r
2282                         }\r
2283 \r
2284                         return s;\r
2285                 }\r
2286                 */\r
2287 \r
2288                 });\r
2289 \r
2290         // Setup page DOM\r
2291         tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});\r
2292 })();\r
2293 \r
2294 /* file:jscripts/tiny_mce/classes/dom/Event.js */\r
2295 \r
2296 (function() {\r
2297         // Shorten names\r
2298         var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
2299 \r
2300         tinymce.create('static tinymce.dom.Event', {\r
2301                 inits : [],\r
2302                 events : [],\r
2303 \r
2304                 // #if !jquery\r
2305 \r
2306                 add : function(o, n, f, s) {\r
2307                         var cb, t = this, el = t.events, r;\r
2308 \r
2309                         // Handle array\r
2310                         if (o && o instanceof Array) {\r
2311                                 r = [];\r
2312 \r
2313                                 each(o, function(o) {\r
2314                                         o = DOM.get(o);\r
2315                                         r.push(t.add(o, n, f, s));\r
2316                                 });\r
2317 \r
2318                                 return r;\r
2319                         }\r
2320 \r
2321                         o = DOM.get(o);\r
2322 \r
2323                         if (!o)\r
2324                                 return;\r
2325 \r
2326                         // Setup event callback\r
2327                         cb = function(e) {\r
2328                                 e = e || window.event;\r
2329 \r
2330                                 // Patch in target in IE it's W3C valid\r
2331                                 if (e && !e.target && isIE)\r
2332                                         e.target = e.srcElement;\r
2333 \r
2334                                 if (!s)\r
2335                                         return f(e);\r
2336 \r
2337                                 return f.call(s, e);\r
2338                         };\r
2339 \r
2340                         if (n == 'unload') {\r
2341                                 tinymce.unloads.unshift({func : cb});\r
2342                                 return cb;\r
2343                         }\r
2344 \r
2345                         if (n == 'init') {\r
2346                                 if (t.domLoaded)\r
2347                                         cb();\r
2348                                 else\r
2349                                         t.inits.push(cb);\r
2350 \r
2351                                 return cb;\r
2352                         }\r
2353 \r
2354                         // Store away listener reference\r
2355                         el.push({\r
2356                                 obj : o,\r
2357                                 name : n,\r
2358                                 func : f,\r
2359                                 cfunc : cb,\r
2360                                 scope : s\r
2361                         });\r
2362 \r
2363                         t._add(o, n, cb);\r
2364 \r
2365                         return f;\r
2366                 },\r
2367 \r
2368                 remove : function(o, n, f) {\r
2369                         var t = this, a = t.events, s = false, r;\r
2370 \r
2371                         // Handle array\r
2372                         if (o && o instanceof Array) {\r
2373                                 r = [];\r
2374 \r
2375                                 each(o, function(o) {\r
2376                                         o = DOM.get(o);\r
2377                                         r.push(t.remove(o, n, f));\r
2378                                 });\r
2379 \r
2380                                 return r;\r
2381                         }\r
2382 \r
2383                         o = DOM.get(o);\r
2384 \r
2385                         each(a, function(e, i) {\r
2386                                 if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {\r
2387                                         a.splice(i, 1);\r
2388                                         t._remove(o, n, e.cfunc);\r
2389                                         s = true;\r
2390                                         return false;\r
2391                                 }\r
2392                         });\r
2393 \r
2394                         return s;\r
2395                 },\r
2396 \r
2397                 clear : function(o) {\r
2398                         var t = this, a = t.events, i, e;\r
2399 \r
2400                         if (o) {\r
2401                                 o = DOM.get(o);\r
2402 \r
2403                                 for (i = a.length - 1; i >= 0; i--) {\r
2404                                         e = a[i];\r
2405 \r
2406                                         if (e.obj === o) {\r
2407                                                 t._remove(e.obj, e.name, e.cfunc);\r
2408                                                 e.obj = e.cfunc = null;\r
2409                                                 a.splice(i, 1);\r
2410                                         }\r
2411                                 }\r
2412                         }\r
2413                 },\r
2414 \r
2415                 // #endif\r
2416 \r
2417                 cancel : function(e) {\r
2418                         if (!e)\r
2419                                 return false;\r
2420 \r
2421                         this.stop(e);\r
2422                         return this.prevent(e);\r
2423                 },\r
2424 \r
2425                 stop : function(e) {\r
2426                         if (e.stopPropagation)\r
2427                                 e.stopPropagation();\r
2428                         else\r
2429                                 e.cancelBubble = true;\r
2430 \r
2431                         return false;\r
2432                 },\r
2433 \r
2434                 prevent : function(e) {\r
2435                         if (e.preventDefault)\r
2436                                 e.preventDefault();\r
2437                         else\r
2438                                 e.returnValue = false;\r
2439 \r
2440                         return false;\r
2441                 },\r
2442 \r
2443                 _unload : function() {\r
2444                         var t = Event;\r
2445 \r
2446                         each(t.events, function(e, i) {\r
2447                                 t._remove(e.obj, e.name, e.cfunc);\r
2448                                 e.obj = e.cfunc = null;\r
2449                         });\r
2450 \r
2451                         t.events = [];\r
2452                         t = null;\r
2453                 },\r
2454 \r
2455                 _add : function(o, n, f) {\r
2456                         if (o.attachEvent)\r
2457                                 o.attachEvent('on' + n, f);\r
2458                         else if (o.addEventListener)\r
2459                                 o.addEventListener(n, f, false);\r
2460                         else\r
2461                                 o['on' + n] = f;\r
2462                 },\r
2463 \r
2464                 _remove : function(o, n, f) {\r
2465                         if (o) {\r
2466                                 try {\r
2467                                         if (o.detachEvent)\r
2468                                                 o.detachEvent('on' + n, f);\r
2469                                         else if (o.removeEventListener)\r
2470                                                 o.removeEventListener(n, f, false);\r
2471                                         else\r
2472                                                 o['on' + n] = null;\r
2473                                 } catch (ex) {\r
2474                                         // Might fail with permission denined on IE so we just ignore that\r
2475                                 }\r
2476                         }\r
2477                 },\r
2478 \r
2479                 _pageInit : function() {\r
2480                         var e = Event;\r
2481 \r
2482                         e._remove(window, 'DOMContentLoaded', e._pageInit);\r
2483                         e.domLoaded = true;\r
2484 \r
2485                         each(e.inits, function(c) {\r
2486                                 c();\r
2487                         });\r
2488 \r
2489                         e.inits = [];\r
2490                 },\r
2491 \r
2492                 _wait : function() {\r
2493                         var t;\r
2494 \r
2495                         // No need since the document is already loaded\r
2496                         if (window.tinyMCE_GZ && tinyMCE_GZ.loaded)\r
2497                                 return;\r
2498 \r
2499                         if (isIE && document.location.protocol != 'https:') {\r
2500                                 // Fake DOMContentLoaded on IE\r
2501                                 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');\r
2502                                 DOM.get("__ie_onload").onreadystatechange = function() {\r
2503                                         if (this.readyState == "complete") {\r
2504                                                 Event._pageInit();\r
2505                                                 DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak\r
2506                                         }\r
2507                                 };\r
2508                         } else {\r
2509                                 Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);\r
2510 \r
2511                                 if (isIE || isWebKit) {\r
2512                                         t = setInterval(function() {\r
2513                                                 if (/loaded|complete/.test(document.readyState)) {\r
2514                                                         clearInterval(t);\r
2515                                                         Event._pageInit();\r
2516                                                 }\r
2517                                         }, 10);\r
2518                                 }\r
2519                         }\r
2520                 }\r
2521 \r
2522                 });\r
2523 \r
2524         // Shorten name\r
2525         Event = tinymce.dom.Event;\r
2526 \r
2527         // Dispatch DOM content loaded event for IE and Safari\r
2528         Event._wait();\r
2529         tinymce.addUnload(Event._unload);\r
2530 })();\r
2531 \r
2532 /* file:jscripts/tiny_mce/classes/dom/Element.js */\r
2533 \r
2534 (function() {\r
2535         var each = tinymce.each;\r
2536 \r
2537         tinymce.create('tinymce.dom.Element', {\r
2538                 Element : function(id, s) {\r
2539                         var t = this, dom, el;\r
2540 \r
2541                         s = s || {};\r
2542                         t.id = id;\r
2543                         t.dom = dom = s.dom || tinymce.DOM;\r
2544                         t.settings = s;\r
2545 \r
2546                         // Only IE leaks DOM references, this is a lot faster\r
2547                         if (!tinymce.isIE)\r
2548                                 el = t.dom.get(t.id);\r
2549 \r
2550                         each([\r
2551                                 'getPos',\r
2552                                 'getRect',\r
2553                                 'getParent',\r
2554                                 'add',\r
2555                                 'setStyle',\r
2556                                 'getStyle',\r
2557                                 'setStyles',\r
2558                                 'setAttrib',\r
2559                                 'setAttribs',\r
2560                                 'getAttrib',\r
2561                                 'addClass',\r
2562                                 'removeClass',\r
2563                                 'hasClass',\r
2564                                 'getOuterHTML',\r
2565                                 'setOuterHTML',\r
2566                                 'remove',\r
2567                                 'show',\r
2568                                 'hide',\r
2569                                 'isHidden',\r
2570                                 'setHTML',\r
2571                                 'get'\r
2572                         ], function(k) {\r
2573                                 t[k] = function() {\r
2574                                         var a = arguments, o;\r
2575 \r
2576                                         // Opera fails\r
2577                                         if (tinymce.isOpera) {\r
2578                                                 a = [id];\r
2579 \r
2580                                                 each(arguments, function(v) {\r
2581                                                         a.push(v);\r
2582                                                 });\r
2583                                         } else\r
2584                                                 Array.prototype.unshift.call(a, el || id);\r
2585 \r
2586                                         o = dom[k].apply(dom, a);\r
2587                                         t.update(k);\r
2588 \r
2589                                         return o;\r
2590                                 };\r
2591                         });\r
2592                 },\r
2593 \r
2594                 on : function(n, f, s) {\r
2595                         return tinymce.dom.Event.add(this.id, n, f, s);\r
2596                 },\r
2597 \r
2598                 getXY : function() {\r
2599                         return {\r
2600                                 x : parseInt(this.getStyle('left')),\r
2601                                 y : parseInt(this.getStyle('top'))\r
2602                         };\r
2603                 },\r
2604 \r
2605                 getSize : function() {\r
2606                         var n = this.dom.get(this.id);\r
2607 \r
2608                         return {\r
2609                                 w : parseInt(this.getStyle('width') || n.clientWidth),\r
2610                                 h : parseInt(this.getStyle('height') || n.clientHeight)\r
2611                         };\r
2612                 },\r
2613 \r
2614                 moveTo : function(x, y) {\r
2615                         this.setStyles({left : x, top : y});\r
2616                 },\r
2617 \r
2618                 moveBy : function(x, y) {\r
2619                         var p = this.getXY();\r
2620 \r
2621                         this.moveTo(p.x + x, p.y + y);\r
2622                 },\r
2623 \r
2624                 resizeTo : function(w, h) {\r
2625                         this.setStyles({width : w, height : h});\r
2626                 },\r
2627 \r
2628                 resizeBy : function(w, h) {\r
2629                         var s = this.getSize();\r
2630 \r
2631                         this.resizeTo(s.w + w, s.h + h);\r
2632                 },\r
2633 \r
2634                 update : function(k) {\r
2635                         var t = this, b, dom = t.dom;\r
2636 \r
2637                         if (tinymce.isIE6 && t.settings.blocker) {\r
2638                                 k = k || '';\r
2639 \r
2640                                 // Ignore getters\r
2641                                 if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0)\r
2642                                         return;\r
2643 \r
2644                                 // Remove blocker on remove\r
2645                                 if (k == 'remove') {\r
2646                                         dom.remove(t.blocker);\r
2647                                         return;\r
2648                                 }\r
2649 \r
2650                                 if (!t.blocker) {\r
2651                                         t.blocker = dom.uniqueId();\r
2652                                         b = dom.add(t.settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'});\r
2653                                         dom.setStyle(b, 'opacity', 0);\r
2654                                 } else\r
2655                                         b = dom.get(t.blocker);\r
2656 \r
2657                                 dom.setStyle(b, 'left', t.getStyle('left', 1));\r
2658                                 dom.setStyle(b, 'top', t.getStyle('top', 1));\r
2659                                 dom.setStyle(b, 'width', t.getStyle('width', 1));\r
2660                                 dom.setStyle(b, 'height', t.getStyle('height', 1));\r
2661                                 dom.setStyle(b, 'display', t.getStyle('display', 1));\r
2662                                 dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);\r
2663                         }\r
2664                 }\r
2665 \r
2666                 });\r
2667 })();\r
2668 \r
2669 /* file:jscripts/tiny_mce/classes/dom/Selection.js */\r
2670 \r
2671 (function() {\r
2672         // Shorten names\r
2673         var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;\r
2674 \r
2675         tinymce.create('tinymce.dom.Selection', {\r
2676                 Selection : function(dom, win, serializer) {\r
2677                         var t = this;\r
2678 \r
2679                         t.dom = dom;\r
2680                         t.win = win;\r
2681                         t.serializer = serializer;\r
2682 \r
2683                         // Prevent leaks\r
2684                         tinymce.addUnload(t.destroy, t);\r
2685                 },\r
2686 \r
2687                 getContent : function(s) {\r
2688                         var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;\r
2689 \r
2690                         s = s || {};\r
2691                         wb = wa = '';\r
2692                         s.get = true;\r
2693                         s.format = s.format || 'html';\r
2694 \r
2695                         if (s.format == 'text')\r
2696                                 return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));\r
2697 \r
2698                         if (r.cloneContents) {\r
2699                                 n = r.cloneContents();\r
2700 \r
2701                                 if (n)\r
2702                                         e.appendChild(n);\r
2703                         } else if (is(r.item) || is(r.htmlText))\r
2704                                 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;\r
2705                         else\r
2706                                 e.innerHTML = r.toString();\r
2707 \r
2708                         // Keep whitespace before and after\r
2709                         if (/^\s/.test(e.innerHTML))\r
2710                                 wb = ' ';\r
2711 \r
2712                         if (/\s+$/.test(e.innerHTML))\r
2713                                 wa = ' ';\r
2714 \r
2715                         s.getInner = true;\r
2716 \r
2717                         return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
2718                 },\r
2719 \r
2720                 setContent : function(h, s) {\r
2721                         var t = this, r = t.getRng(), d;\r
2722 \r
2723                         s = s || {format : 'html'};\r
2724                         s.set = true;\r
2725                         h = t.dom.processHTML(h);\r
2726 \r
2727                         if (r.insertNode) {\r
2728                                 d = t.win.document;\r
2729 \r
2730                                 // Gecko has a bug where if you insert &nbsp; using InsertHTML it will insert a space instead\r
2731                                 // So we simply check if the input is HTML or text and then insert text using the insertNode method\r
2732                                 if (tinymce.isGecko && h.indexOf('<') == -1) {\r
2733                                         r.deleteContents();\r
2734                                         r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>'));\r
2735                                         t.select(t.dom.get('__caret'));\r
2736                                         t.getRng().deleteContents();\r
2737                                         return;\r
2738                                 }\r
2739 \r
2740                                 // Use insert HTML if it exists (places cursor after content)\r
2741                                 try {\r
2742                                         // This might fail with an exception see bug #1893736\r
2743                                         if (d.queryCommandEnabled('InsertHTML'))\r
2744                                                 return d.execCommand('InsertHTML', false, h);\r
2745                                 } catch (ex) {\r
2746                                         // Use old school method\r
2747                                         r.deleteContents();\r
2748                                         r.insertNode(t.getRng().createContextualFragment(h));\r
2749                                 }\r
2750                         } else {\r
2751                                 if (r.item)\r
2752                                         r.item(0).outerHTML = h;\r
2753                                 else\r
2754                                         r.pasteHTML(h);\r
2755                         }\r
2756                 },\r
2757 \r
2758                 getStart : function() {\r
2759                         var t = this, r = t.getRng(), e;\r
2760 \r
2761                         if (isIE) {\r
2762                                 if (r.item)\r
2763                                         return r.item(0);\r
2764 \r
2765                                 r = r.duplicate();\r
2766                                 r.collapse(1);\r
2767                                 e = r.parentElement();\r
2768 \r
2769                                 if (e.nodeName == 'BODY')\r
2770                                         return e.firstChild;\r
2771 \r
2772                                 return e;\r
2773                         } else {\r
2774                                 e = r.startContainer;\r
2775 \r
2776                                 if (e.nodeName == 'BODY')\r
2777                                         return e.firstChild;\r
2778 \r
2779                                 return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
2780                         }\r
2781                 },\r
2782 \r
2783                 getEnd : function() {\r
2784                         var t = this, r = t.getRng(), e;\r
2785 \r
2786                         if (isIE) {\r
2787                                 if (r.item)\r
2788                                         return r.item(0);\r
2789 \r
2790                                 r = r.duplicate();\r
2791                                 r.collapse(0);\r
2792                                 e = r.parentElement();\r
2793 \r
2794                                 if (e.nodeName == 'BODY')\r
2795                                         return e.lastChild;\r
2796 \r
2797                                 return e;\r
2798                         } else {\r
2799                                 e = r.endContainer;\r
2800 \r
2801                                 if (e.nodeName == 'BODY')\r
2802                                         return e.lastChild;\r
2803 \r
2804                                 return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
2805                         }\r
2806                 },\r
2807 \r
2808                 getBookmark : function(si) {\r
2809                         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
2810                         sx = vp.x;\r
2811                         sy = vp.y;\r
2812 \r
2813                         // Simple bookmark fast but not as persistent\r
2814                         if (si == 'simple')\r
2815                                 return {rng : r, scrollX : sx, scrollY : sy};\r
2816 \r
2817                         // Handle IE\r
2818                         if (isIE) {\r
2819                                 // Control selection\r
2820                                 if (r.item) {\r
2821                                         e = r.item(0);\r
2822 \r
2823                                         each(t.dom.select(e.nodeName), function(n, i) {\r
2824                                                 if (e == n) {\r
2825                                                         sp = i;\r
2826                                                         return false;\r
2827                                                 }\r
2828                                         });\r
2829 \r
2830                                         return {\r
2831                                                 tag : e.nodeName,\r
2832                                                 index : sp,\r
2833                                                 scrollX : sx,\r
2834                                                 scrollY : sy\r
2835                                         };\r
2836                                 }\r
2837 \r
2838                                 // Text selection\r
2839                                 tr = t.dom.doc.body.createTextRange();\r
2840                                 tr.moveToElementText(ro);\r
2841                                 tr.collapse(true);\r
2842                                 bp = Math.abs(tr.move('character', c));\r
2843 \r
2844                                 tr = r.duplicate();\r
2845                                 tr.collapse(true);\r
2846                                 sp = Math.abs(tr.move('character', c));\r
2847 \r
2848                                 tr = r.duplicate();\r
2849                                 tr.collapse(false);\r
2850                                 le = Math.abs(tr.move('character', c)) - sp;\r
2851 \r
2852                                 return {\r
2853                                         start : sp - bp,\r
2854                                         length : le,\r
2855                                         scrollX : sx,\r
2856                                         scrollY : sy\r
2857                                 };\r
2858                         }\r
2859 \r
2860                         // Handle W3C\r
2861                         e = t.getNode();\r
2862                         s = t.getSel();\r
2863 \r
2864                         if (!s)\r
2865                                 return null;\r
2866 \r
2867                         // Image selection\r
2868                         if (e && e.nodeName == 'IMG') {\r
2869                                 return {\r
2870                                         scrollX : sx,\r
2871                                         scrollY : sy\r
2872                                 };\r
2873                         }\r
2874 \r
2875                         // Text selection\r
2876 \r
2877                         function getPos(r, sn, en) {\r
2878                                 var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};\r
2879 \r
2880                                 while ((n = w.nextNode()) != null) {\r
2881                                         if (n == sn)\r
2882                                                 d.start = p;\r
2883 \r
2884                                         if (n == en) {\r
2885                                                 d.end = p;\r
2886                                                 return d;\r
2887                                         }\r
2888 \r
2889                                         p += tinymce.trim(n.nodeValue || '').length;\r
2890                                 }\r
2891 \r
2892                                 return null;\r
2893                         };\r
2894 \r
2895                         // Caret or selection\r
2896                         if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) {\r
2897                                 e = getPos(ro, s.anchorNode, s.focusNode);\r
2898 \r
2899                                 if (!e)\r
2900                                         return {scrollX : sx, scrollY : sy};\r
2901 \r
2902                                 // Count whitespace before\r
2903                                 (s.anchorNode.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;});\r
2904 \r
2905                                 return {\r
2906                                         start : Math.max(e.start + s.anchorOffset - wb, 0),\r
2907                                         end : Math.max(e.end + s.focusOffset - wb, 0),\r
2908                                         scrollX : sx,\r
2909                                         scrollY : sy,\r
2910                                         beg : s.anchorOffset - wb == 0\r
2911                                 };\r
2912                         } else {\r
2913                                 e = getPos(ro, r.startContainer, r.endContainer);\r
2914 \r
2915                                 // Count whitespace before start and end container\r
2916                                 (r.startContainer.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;});\r
2917                                 (r.endContainer.nodeValue || '').replace(/^\s+/, function(a) {wa = a.length;});\r
2918 \r
2919                                 if (!e)\r
2920                                         return {scrollX : sx, scrollY : sy};\r
2921 \r
2922                                 return {\r
2923                                         start : Math.max(e.start + r.startOffset - wb, 0),\r
2924                                         end : Math.max(e.end + r.endOffset - wa, 0),\r
2925                                         scrollX : sx,\r
2926                                         scrollY : sy,\r
2927                                         beg : r.startOffset - wb == 0\r
2928                                 };\r
2929                         }\r
2930                 },\r
2931 \r
2932                 moveToBookmark : function(b) {\r
2933                         var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd, nvl, nv;\r
2934 \r
2935                         function getPos(r, sp, ep) {\r
2936                                 var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}, o, v, wa, wb;\r
2937 \r
2938                                 while ((n = w.nextNode()) != null) {\r
2939                                         wa = wb = 0;\r
2940 \r
2941                                         nv = n.nodeValue || '';\r
2942                                         nv.replace(/^\s+[^\s]/, function(a) {wb = a.length - 1;});\r
2943                                         nv.replace(/[^\s]\s+$/, function(a) {wa = a.length - 1;});\r
2944 \r
2945                                         nvl = tinymce.trim(nv).length;\r
2946                                         p += nvl;\r
2947 \r
2948                                         if (p >= sp && !d.startNode) {\r
2949                                                 o = sp - (p - nvl);\r
2950 \r
2951                                                 // Fix for odd quirk in FF\r
2952                                                 if (b.beg && o >= nvl)\r
2953                                                         continue;\r
2954 \r
2955                                                 d.startNode = n;\r
2956                                                 d.startOffset = o + wb;\r
2957                                         }\r
2958 \r
2959                                         if (p >= ep) {\r
2960                                                 d.endNode = n;\r
2961                                                 d.endOffset = ep - (p - nvl) + wb;\r
2962                                                 return d;\r
2963                                         }\r
2964                                 }\r
2965 \r
2966                                 return null;\r
2967                         };\r
2968 \r
2969                         if (!b)\r
2970                                 return false;\r
2971 \r
2972                         t.win.scrollTo(b.scrollX, b.scrollY);\r
2973 \r
2974                         // Handle explorer\r
2975                         if (isIE) {\r
2976                                 // Handle simple\r
2977                                 if (r = b.rng) {\r
2978                                         try {\r
2979                                                 r.select();\r
2980                                         } catch (ex) {\r
2981                                                 // Ignore\r
2982                                         }\r
2983 \r
2984                                         return true;\r
2985                                 }\r
2986 \r
2987                                 t.win.focus();\r
2988 \r
2989                                 // Handle control bookmark\r
2990                                 if (b.tag) {\r
2991                                         r = ro.createControlRange();\r
2992 \r
2993                                         each(t.dom.select(b.tag), function(n, i) {\r
2994                                                 if (i == b.index)\r
2995                                                         r.addElement(n);\r
2996                                         });\r
2997                                 } else {\r
2998                                         // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs\r
2999                                         try {\r
3000                                                 // Incorrect bookmark\r
3001                                                 if (b.start < 0)\r
3002                                                         return true;\r
3003 \r
3004                                                 r = s.createRange();\r
3005                                                 r.moveToElementText(ro);\r
3006                                                 r.collapse(true);\r
3007                                                 r.moveStart('character', b.start);\r
3008                                                 r.moveEnd('character', b.length);\r
3009                                         } catch (ex2) {\r
3010                                                 return true;\r
3011                                         }\r
3012                                 }\r
3013 \r
3014                                 try {\r
3015                                         r.select();\r
3016                                 } catch (ex) {\r
3017                                         // Needed for some odd IE bug #1843306\r
3018                                 }\r
3019 \r
3020                                 return true;\r
3021                         }\r
3022 \r
3023                         // Handle W3C\r
3024                         if (!s)\r
3025                                 return false;\r
3026 \r
3027                         // Handle simple\r
3028                         if (b.rng) {\r
3029                                 s.removeAllRanges();\r
3030                                 s.addRange(b.rng);\r
3031                         } else {\r
3032                                 if (is(b.start) && is(b.end)) {\r
3033                                         try {\r
3034                                                 sd = getPos(ro, b.start, b.end);\r
3035 \r
3036                                                 if (sd) {\r
3037                                                         r = t.dom.doc.createRange();\r
3038                                                         r.setStart(sd.startNode, sd.startOffset);\r
3039                                                         r.setEnd(sd.endNode, sd.endOffset);\r
3040                                                         s.removeAllRanges();\r
3041                                                         s.addRange(r);\r
3042                                                 }\r
3043 \r
3044                                                 if (!tinymce.isOpera)\r
3045                                                         t.win.focus();\r
3046                                         } catch (ex) {\r
3047                                                 // Ignore\r
3048                                         }\r
3049                                 }\r
3050                         }\r
3051                 },\r
3052 \r
3053                 select : function(n, c) {\r
3054                         var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;\r
3055 \r
3056                         function first(n) {\r
3057                                 return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;\r
3058                         };\r
3059 \r
3060                         function last(n) {\r
3061                                 var c, o, w;\r
3062 \r
3063                                 if (!n)\r
3064                                         return null;\r
3065 \r
3066                                 w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
3067                                 while (c = w.nextNode())\r
3068                                         o = c;\r
3069 \r
3070                                 return o;\r
3071                         };\r
3072 \r
3073                         if (isIE) {\r
3074                                 try {\r
3075                                         b = d.body;\r
3076 \r
3077                                         if (/^(IMG|TABLE)$/.test(n.nodeName)) {\r
3078                                                 r = b.createControlRange();\r
3079                                                 r.addElement(n);\r
3080                                         } else {\r
3081                                                 r = b.createTextRange();\r
3082                                                 r.moveToElementText(n);\r
3083                                         }\r
3084 \r
3085                                         r.select();\r
3086                                 } catch (ex) {\r
3087                                         // Throws illigal agrument in IE some times\r
3088                                 }\r
3089                         } else {\r
3090                                 if (c) {\r
3091                                         fn = first(n);\r
3092                                         ln = last(n);\r
3093 \r
3094                                         if (fn && ln) {\r
3095                                                 //console.debug(fn, ln);\r
3096                                                 r = d.createRange();\r
3097                                                 r.setStart(fn, 0);\r
3098                                                 r.setEnd(ln, ln.nodeValue.length);\r
3099                                         } else\r
3100                                                 r.selectNode(n);\r
3101                                 } else\r
3102                                         r.selectNode(n);\r
3103 \r
3104                                 t.setRng(r);\r
3105                         }\r
3106 \r
3107                         return n;\r
3108                 },\r
3109 \r
3110                 isCollapsed : function() {\r
3111                         var t = this, r = t.getRng(), s = t.getSel();\r
3112 \r
3113                         if (!r || r.item)\r
3114                                 return false;\r
3115 \r
3116                         return !s || r.boundingWidth == 0 || s.isCollapsed;\r
3117                 },\r
3118 \r
3119                 collapse : function(b) {\r
3120                         var t = this, r = t.getRng(), n;\r
3121 \r
3122                         // Control range on IE\r
3123                         if (r.item) {\r
3124                                 n = r.item(0);\r
3125                                 r = this.win.document.body.createTextRange();\r
3126                                 r.moveToElementText(n);\r
3127                         }\r
3128 \r
3129                         r.collapse(!!b);\r
3130                         t.setRng(r);\r
3131                 },\r
3132 \r
3133                 getSel : function() {\r
3134                         var t = this, w = this.win;\r
3135 \r
3136                         return w.getSelection ? w.getSelection() : w.document.selection;\r
3137                 },\r
3138 \r
3139                 getRng : function() {\r
3140                         var t = this, s = t.getSel(), r;\r
3141 \r
3142                         try {\r
3143                                 if (s)\r
3144                                         r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());\r
3145                         } catch (ex) {\r
3146                                 // IE throws unspecified error here if TinyMCE is placed in a frame/iframe\r
3147                         }\r
3148 \r
3149                         // No range found then create an empty one\r
3150                         // This can occur when the editor is placed in a hidden container element on Gecko\r
3151                         // Or on IE when there was an exception\r
3152                         if (!r)\r
3153                                 r = isIE ? t.win.document.body.createTextRange() : t.win.document.createRange();\r
3154 \r
3155                         return r;\r
3156                 },\r
3157 \r
3158                 setRng : function(r) {\r
3159                         var s;\r
3160 \r
3161                         if (!isIE) {\r
3162                                 s = this.getSel();\r
3163 \r
3164                                 if (s) {\r
3165                                         s.removeAllRanges();\r
3166                                         s.addRange(r);\r
3167                                 }\r
3168                         } else {\r
3169                                 try {\r
3170                                         r.select();\r
3171                                 } catch (ex) {\r
3172                                         // Needed for some odd IE bug #1843306\r
3173                                 }\r
3174                         }\r
3175                 },\r
3176 \r
3177                 setNode : function(n) {\r
3178                         var t = this;\r
3179 \r
3180                         t.setContent(t.dom.getOuterHTML(n));\r
3181 \r
3182                         return n;\r
3183                 },\r
3184 \r
3185                 getNode : function() {\r
3186                         var t = this, r = t.getRng(), s = t.getSel(), e;\r
3187 \r
3188                         if (!isIE) {\r
3189                                 // Range maybe lost after the editor is made visible again\r
3190                                 if (!r)\r
3191                                         return t.dom.getRoot();\r
3192 \r
3193                                 e = r.commonAncestorContainer;\r
3194 \r
3195                                 // Handle selection a image or other control like element such as anchors\r
3196                                 if (!r.collapsed) {\r
3197                                         if (r.startContainer == r.endContainer || (tinymce.isWebKit && r.startContainer == r.endContainer.parentNode)) {\r
3198                                                 if (r.startOffset - r.endOffset < 2 || tinymce.isWebKit) {\r
3199                                                         if (r.startContainer.hasChildNodes())\r
3200                                                                 e = r.startContainer.childNodes[r.startOffset];\r
3201                                                 }\r
3202                                         }\r
3203                                 }\r
3204 \r
3205                                 return t.dom.getParent(e, function(n) {\r
3206                                         return n.nodeType == 1;\r
3207                                 });\r
3208                         }\r
3209 \r
3210                         return r.item ? r.item(0) : r.parentElement();\r
3211                 },\r
3212 \r
3213                 destroy : function(s) {\r
3214                         var t = this;\r
3215 \r
3216                         t.win = null;\r
3217 \r
3218                         // Manual destroy then remove unload handler\r
3219                         if (!s)\r
3220                                 tinymce.removeUnload(t.destroy);\r
3221                 }\r
3222 \r
3223                 });\r
3224 })();\r
3225 \r
3226 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */\r
3227 \r
3228 (function() {\r
3229         tinymce.create('tinymce.dom.XMLWriter', {\r
3230                 node : null,\r
3231 \r
3232                 XMLWriter : function(s) {\r
3233                         // Get XML document\r
3234                         function getXML() {\r
3235                                 var i = document.implementation;\r
3236 \r
3237                                 if (!i || !i.createDocument) {\r
3238                                         // Try IE objects\r
3239                                         try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {}\r
3240                                         try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {}\r
3241                                 } else\r
3242                                         return i.createDocument('', '', null);\r
3243                         };\r
3244 \r
3245                         this.doc = getXML();\r
3246                         \r
3247                         // Since Opera and WebKit doesn't escape > into &gt; we need to do it our self to normalize the output for all browsers\r
3248                         this.valid = tinymce.isOpera || tinymce.isWebKit;\r
3249 \r
3250                         this.reset();\r
3251                 },\r
3252 \r
3253                 reset : function() {\r
3254                         var t = this, d = t.doc;\r
3255 \r
3256                         if (d.firstChild)\r
3257                                 d.removeChild(d.firstChild);\r
3258 \r
3259                         t.node = d.appendChild(d.createElement("html"));\r
3260                 },\r
3261 \r
3262                 writeStartElement : function(n) {\r
3263                         var t = this;\r
3264 \r
3265                         t.node = t.node.appendChild(t.doc.createElement(n));\r
3266                 },\r
3267 \r
3268                 writeAttribute : function(n, v) {\r
3269                         if (this.valid)\r
3270                                 v = v.replace(/>/g, '%MCGT%');\r
3271 \r
3272                         this.node.setAttribute(n, v);\r
3273                 },\r
3274 \r
3275                 writeEndElement : function() {\r
3276                         this.node = this.node.parentNode;\r
3277                 },\r
3278 \r
3279                 writeFullEndElement : function() {\r
3280                         var t = this, n = t.node;\r
3281 \r
3282                         n.appendChild(t.doc.createTextNode(""));\r
3283                         t.node = n.parentNode;\r
3284                 },\r
3285 \r
3286                 writeText : function(v) {\r
3287                         if (this.valid)\r
3288                                 v = v.replace(/>/g, '%MCGT%');\r
3289 \r
3290                         this.node.appendChild(this.doc.createTextNode(v));\r
3291                 },\r
3292 \r
3293                 writeCDATA : function(v) {\r
3294                         this.node.appendChild(this.doc.createCDATA(v));\r
3295                 },\r
3296 \r
3297                 writeComment : function(v) {\r
3298                         this.node.appendChild(this.doc.createComment(v));\r
3299                 },\r
3300 \r
3301                 getContent : function() {\r
3302                         var h;\r
3303 \r
3304                         h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);\r
3305                         h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, '');\r
3306                         h = h.replace(/ ?\/>/g, ' />');\r
3307 \r
3308                         if (this.valid)\r
3309                                 h = h.replace(/\%MCGT%/g, '&gt;');\r
3310 \r
3311                         return h;\r
3312                 }\r
3313 \r
3314                 });\r
3315 })();\r
3316 \r
3317 /* file:jscripts/tiny_mce/classes/dom/StringWriter.js */\r
3318 \r
3319 (function() {\r
3320         tinymce.create('tinymce.dom.StringWriter', {\r
3321                 str : null,\r
3322                 tags : null,\r
3323                 count : 0,\r
3324                 settings : null,\r
3325                 indent : null,\r
3326 \r
3327                 StringWriter : function(s) {\r
3328                         this.settings = tinymce.extend({\r
3329                                 indent_char : ' ',\r
3330                                 indentation : 1\r
3331                         }, s);\r
3332 \r
3333                         this.reset();\r
3334                 },\r
3335 \r
3336                 reset : function() {\r
3337                         this.indent = '';\r
3338                         this.str = "";\r
3339                         this.tags = [];\r
3340                         this.count = 0;\r
3341                 },\r
3342 \r
3343                 writeStartElement : function(n) {\r
3344                         this._writeAttributesEnd();\r
3345                         this.writeRaw('<' + n);\r
3346                         this.tags.push(n);\r
3347                         this.inAttr = true;\r
3348                         this.count++;\r
3349                         this.elementCount = this.count;\r
3350                 },\r
3351 \r
3352                 writeAttribute : function(n, v) {\r
3353                         var t = this;\r
3354 \r
3355                         t.writeRaw(" " + t.encode(n) + '="' + t.encode(v) + '"');\r
3356                 },\r
3357 \r
3358                 writeEndElement : function() {\r
3359                         var n;\r
3360 \r
3361                         if (this.tags.length > 0) {\r
3362                                 n = this.tags.pop();\r
3363 \r
3364                                 if (this._writeAttributesEnd(1))\r
3365                                         this.writeRaw('</' + n + '>');\r
3366 \r
3367                                 if (this.settings.indentation > 0)\r
3368                                         this.writeRaw('\n');\r
3369                         }\r
3370                 },\r
3371 \r
3372                 writeFullEndElement : function() {\r
3373                         if (this.tags.length > 0) {\r
3374                                 this._writeAttributesEnd();\r
3375                                 this.writeRaw('</' + this.tags.pop() + '>');\r
3376 \r
3377                                 if (this.settings.indentation > 0)\r
3378                                         this.writeRaw('\n');\r
3379                         }\r
3380                 },\r
3381 \r
3382                 writeText : function(v) {\r
3383                         this._writeAttributesEnd();\r
3384                         this.writeRaw(this.encode(v));\r
3385                         this.count++;\r
3386                 },\r
3387 \r
3388                 writeCDATA : function(v) {\r
3389                         this._writeAttributesEnd();\r
3390                         this.writeRaw('<![CDATA[' + v + ']]>');\r
3391                         this.count++;\r
3392                 },\r
3393 \r
3394                 writeComment : function(v) {\r
3395                         this._writeAttributesEnd();\r
3396                         this.writeRaw('<!-- ' + v + '-->');\r
3397                         this.count++;\r
3398                 },\r
3399 \r
3400                 writeRaw : function(v) {\r
3401                         this.str += v;\r
3402                 },\r
3403 \r
3404                 encode : function(s) {\r
3405                         return s.replace(/[<>&"]/g, function(v) {\r
3406                                 switch (v) {\r
3407                                         case '<':\r
3408                                                 return '&lt;';\r
3409 \r
3410                                         case '>':\r
3411                                                 return '&gt;';\r
3412 \r
3413                                         case '&':\r
3414                                                 return '&amp;';\r
3415 \r
3416                                         case '"':\r
3417                                                 return '&quot;';\r
3418                                 }\r
3419 \r
3420                                 return v;\r
3421                         });\r
3422                 },\r
3423 \r
3424                 getContent : function() {\r
3425                         return this.str;\r
3426                 },\r
3427 \r
3428                 _writeAttributesEnd : function(s) {\r
3429                         if (!this.inAttr)\r
3430                                 return;\r
3431 \r
3432                         this.inAttr = false;\r
3433 \r
3434                         if (s && this.elementCount == this.count) {\r
3435                                 this.writeRaw(' />');\r
3436                                 return false;\r
3437                         }\r
3438 \r
3439                         this.writeRaw('>');\r
3440 \r
3441                         return true;\r
3442                 }\r
3443 \r
3444                 });\r
3445 })();\r
3446 \r
3447 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */\r
3448 \r
3449 (function() {\r
3450         // Shorten names\r
3451         var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;\r
3452 \r
3453         // Returns only attribites that have values not all attributes in IE\r
3454         function getIEAtts(n) {\r
3455                 var o = [];\r
3456 \r
3457                 // Object will throw exception in IE\r
3458                 if (n.nodeName == 'OBJECT')\r
3459                         return n.attributes;\r
3460 \r
3461                 n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
3462                         o.push({specified : 1, nodeName : b});\r
3463                 });\r
3464 \r
3465                 return o;\r
3466         };\r
3467 \r
3468         function wildcardToRE(s) {\r
3469                 return s.replace(/([?+*])/g, '.$1');\r
3470         };\r
3471 \r
3472         tinymce.create('tinymce.dom.Serializer', {\r
3473                 Serializer : function(s) {\r
3474                         var t = this;\r
3475 \r
3476                         t.key = 0;\r
3477                         t.onPreProcess = new Dispatcher(t);\r
3478                         t.onPostProcess = new Dispatcher(t);\r
3479 \r
3480                         if (tinymce.relaxedDomain && tinymce.isGecko) {\r
3481                                 // Gecko has a bug where we can't create a new XML document if domain relaxing is used\r
3482                                 t.writer = new tinymce.dom.StringWriter();\r
3483                         } else {\r
3484                                 try {\r
3485                                         t.writer = new tinymce.dom.XMLWriter();\r
3486                                 } catch (ex) {\r
3487                                         // IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter\r
3488                                         t.writer = new tinymce.dom.StringWriter();\r
3489                                 }\r
3490                         }\r
3491 \r
3492                         // Default settings\r
3493                         t.settings = s = extend({\r
3494                                 dom : tinymce.DOM,\r
3495                                 valid_nodes : 0,\r
3496                                 node_filter : 0,\r
3497                                 attr_filter : 0,\r
3498                                 invalid_attrs : /^(mce_|_moz_)/,\r
3499                                 closed : /(br|hr|input|meta|img|link|param)/,\r
3500                                 entity_encoding : 'named',\r
3501                                 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
3502                                 valid_elements : '*[*]',\r
3503                                 extended_valid_elements : 0,\r
3504                                 valid_child_elements : 0,\r
3505                                 invalid_elements : 0,\r
3506                                 fix_table_elements : 0,\r
3507                                 fix_list_elements : true,\r
3508                                 fix_content_duplication : true,\r
3509                                 convert_fonts_to_spans : false,\r
3510                                 font_size_classes : 0,\r
3511                                 font_size_style_values : 0,\r
3512                                 apply_source_formatting : 0,\r
3513                                 indent_mode : 'simple',\r
3514                                 indent_char : '\t',\r
3515                                 indent_levels : 1,\r
3516                                 remove_linebreaks : 1\r
3517                         }, s);\r
3518 \r
3519                         t.dom = s.dom;\r
3520 \r
3521                         if (s.fix_list_elements) {\r
3522                                 t.onPreProcess.add(function(se, o) {\r
3523                                         var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np;\r
3524 \r
3525                                         function prevNode(e, n) {\r
3526                                                 var a = n.split(','), i;\r
3527 \r
3528                                                 while ((e = e.previousSibling) != null) {\r
3529                                                         for (i=0; i<a.length; i++) {\r
3530                                                                 if (e.nodeName == a[i])\r
3531                                                                         return e;\r
3532                                                         }\r
3533                                                 }\r
3534 \r
3535                                                 return null;\r
3536                                         };\r
3537 \r
3538                                         for (x=0; x<a.length; x++) {\r
3539                                                 nl = t.dom.select(a[x], o.node);\r
3540 \r
3541                                                 for (i=0; i<nl.length; i++) {\r
3542                                                         n = nl[i];\r
3543                                                         p = n.parentNode;\r
3544 \r
3545                                                         if (r.test(p.nodeName)) {\r
3546                                                                 np = prevNode(n, 'LI');\r
3547 \r
3548                                                                 if (!np) {\r
3549                                                                         np = t.dom.create('li');\r
3550                                                                         np.innerHTML = '&nbsp;';\r
3551                                                                         np.appendChild(n);\r
3552                                                                         p.insertBefore(np, p.firstChild);\r
3553                                                                 } else\r
3554                                                                         np.appendChild(n);\r
3555                                                         }\r
3556                                                 }\r
3557                                         }\r
3558                                 });\r
3559                         }\r
3560 \r
3561                         if (s.fix_table_elements) {\r
3562                                 t.onPreProcess.add(function(se, o) {\r
3563                                         each(t.dom.select('table', o.node), function(e) {\r
3564                                                 var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), pa2, n, tm, pl = [], i, ns;\r
3565 \r
3566                                                 if (pa) {\r
3567                                                         pa2 = pa.cloneNode(false);\r
3568 \r
3569                                                         pl.push(e);\r
3570                                                         for (n = e; n = n.parentNode;) {\r
3571                                                                 pl.push(n);\r
3572 \r
3573                                                                 if (n == pa)\r
3574                                                                         break;\r
3575                                                         }\r
3576 \r
3577                                                         tm = pa2;\r
3578                                                         for (i = pl.length - 1; i >= 0; i--) {\r
3579                                                                 if (i == pl.length - 1) {\r
3580                                                                         while (ns = pl[i - 1].nextSibling)\r
3581                                                                                 tm.appendChild(ns.parentNode.removeChild(ns));\r
3582                                                                 } else {\r
3583                                                                         n = pl[i].cloneNode(false);\r
3584 \r
3585                                                                         if (i != 0) {\r
3586                                                                                 while (ns = pl[i - 1].nextSibling)\r
3587                                                                                         n.appendChild(ns.parentNode.removeChild(ns));\r
3588                                                                         }\r
3589 \r
3590                                                                         tm = tm.appendChild(n);\r
3591                                                                 }\r
3592                                                         }\r
3593 \r
3594                                                         e = t.dom.insertAfter(e.parentNode.removeChild(e), pa);\r
3595                                                         t.dom.insertAfter(e, pa);\r
3596                                                         t.dom.insertAfter(pa2, e);\r
3597                                                 }\r
3598                                         });\r
3599                                 });\r
3600                         }\r
3601                 },\r
3602 \r
3603                 setEntities : function(s) {\r
3604                         var t = this, a, i, l = {}, re = '', v;\r
3605 \r
3606                         // No need to setup more than once\r
3607                         if (t.entityLookup)\r
3608                                 return;\r
3609 \r
3610                         // Build regex and lookup array\r
3611                         a = s.split(',');\r
3612                         for (i = 0; i < a.length; i += 2) {\r
3613                                 v = a[i];\r
3614 \r
3615                                 // Don't add default &amp; &quot; etc.\r
3616                                 if (v == 34 || v == 38 || v == 60 || v == 62)\r
3617                                         continue;\r
3618 \r
3619                                 l[String.fromCharCode(a[i])] = a[i + 1];\r
3620 \r
3621                                 v = parseInt(a[i]).toString(16);\r
3622                                 re += '\\u' + '0000'.substring(v.length) + v;\r
3623                         }\r
3624 \r
3625                         if (!re) {\r
3626                                 t.settings.entity_encoding = 'raw';\r
3627                                 return;\r
3628                         }\r
3629 \r
3630                         t.entitiesRE = new RegExp('[' + re + ']', 'g');\r
3631                         t.entityLookup = l;\r
3632                 },\r
3633 \r
3634                 setValidChildRules : function(s) {\r
3635                         this.childRules = null;\r
3636                         this.addValidChildRules(s);\r
3637                 },\r
3638 \r
3639                 addValidChildRules : function(s) {\r
3640                         var t = this, inst, intr, bloc;\r
3641 \r
3642                         if (!s)\r
3643                                 return;\r
3644 \r
3645                         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
3646                         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
3647                         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
3648 \r
3649                         each(s.split(','), function(s) {\r
3650                                 var p = s.split(/\[|\]/), re;\r
3651 \r
3652                                 s = '';\r
3653                                 each(p[1].split('|'), function(v) {\r
3654                                         if (s)\r
3655                                                 s += '|';\r
3656 \r
3657                                         switch (v) {\r
3658                                                 case '%itrans':\r
3659                                                         v = intr;\r
3660                                                         break;\r
3661 \r
3662                                                 case '%itrans_na':\r
3663                                                         v = intr.substring(2);\r
3664                                                         break;\r
3665 \r
3666                                                 case '%istrict':\r
3667                                                         v = inst;\r
3668                                                         break;\r
3669 \r
3670                                                 case '%istrict_na':\r
3671                                                         v = inst.substring(2);\r
3672                                                         break;\r
3673 \r
3674                                                 case '%btrans':\r
3675                                                         v = bloc;\r
3676                                                         break;\r
3677 \r
3678                                                 case '%bstrict':\r
3679                                                         v = bloc;\r
3680                                                         break;\r
3681                                         }\r
3682 \r
3683                                         s += v;\r
3684                                 });\r
3685                                 re = new RegExp('^(' + s.toLowerCase() + ')$', 'i');\r
3686 \r
3687                                 each(p[0].split('/'), function(s) {\r
3688                                         t.childRules = t.childRules || {};\r
3689                                         t.childRules[s] = re;\r
3690                                 });\r
3691                         });\r
3692 \r
3693                         // Build regex\r
3694                         s = '';\r
3695                         each(t.childRules, function(v, k) {\r
3696                                 if (s)\r
3697                                         s += '|';\r
3698 \r
3699                                 s += k;\r
3700                         });\r
3701 \r
3702                         t.parentElementsRE = new RegExp('^(' + s.toLowerCase() + ')$', 'i');\r
3703 \r
3704                         /*console.debug(t.parentElementsRE.toString());\r
3705                         each(t.childRules, function(v) {\r
3706                                 console.debug(v.toString());\r
3707                         });*/\r
3708                 },\r
3709 \r
3710                 setRules : function(s) {\r
3711                         var t = this;\r
3712 \r
3713                         t._setup();\r
3714                         t.rules = {};\r
3715                         t.wildRules = [];\r
3716                         t.validElements = {};\r
3717 \r
3718                         return t.addRules(s);\r
3719                 },\r
3720 \r
3721                 addRules : function(s) {\r
3722                         var t = this, dr;\r
3723 \r
3724                         if (!s)\r
3725                                 return;\r
3726 \r
3727                         t._setup();\r
3728 \r
3729                         each(s.split(','), function(s) {\r
3730                                 var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = [];\r
3731 \r
3732                                 // Extend with default rules\r
3733                                 if (dr)\r
3734                                         at = tinymce.extend([], dr.attribs);\r
3735 \r
3736                                 // Parse attributes\r
3737                                 if (p.length > 1) {\r
3738                                         each(p[1].split('|'), function(s) {\r
3739                                                 var ar = {}, i;\r
3740 \r
3741                                                 at = at || [];\r
3742 \r
3743                                                 // Parse attribute rule\r
3744                                                 s = s.replace(/::/g, '~');\r
3745                                                 s = /^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(s);\r
3746                                                 s[2] = s[2].replace(/~/g, ':');\r
3747 \r
3748                                                 // Add required attributes\r
3749                                                 if (s[1] == '!') {\r
3750                                                         ra = ra || [];\r
3751                                                         ra.push(s[2]);\r
3752                                                 }\r
3753 \r
3754                                                 // Remove inherited attributes\r
3755                                                 if (s[1] == '-') {\r
3756                                                         for (i = 0; i <at.length; i++) {\r
3757                                                                 if (at[i].name == s[2]) {\r
3758                                                                         at.splice(i, 1);\r
3759                                                                         return;\r
3760                                                                 }\r
3761                                                         }\r
3762                                                 }\r
3763 \r
3764                                                 switch (s[3]) {\r
3765                                                         // Add default attrib values\r
3766                                                         case '=':\r
3767                                                                 ar.defaultVal = s[4] || '';\r
3768                                                                 break;\r
3769 \r
3770                                                         // Add forced attrib values\r
3771                                                         case ':':\r
3772                                                                 ar.forcedVal = s[4];\r
3773                                                                 break;\r
3774 \r
3775                                                         // Add validation values\r
3776                                                         case '<':\r
3777                                                                 ar.validVals = s[4].split('?');\r
3778                                                                 break;\r
3779                                                 }\r
3780 \r
3781                                                 if (/[*.?]/.test(s[2])) {\r
3782                                                         wat = wat || [];\r
3783                                                         ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$');\r
3784                                                         wat.push(ar);\r
3785                                                 } else {\r
3786                                                         ar.name = s[2];\r
3787                                                         at.push(ar);\r
3788                                                 }\r
3789 \r
3790                                                 va.push(s[2]);\r
3791                                         });\r
3792                                 }\r
3793 \r
3794                                 // Handle element names\r
3795                                 each(tn, function(s, i) {\r
3796                                         var pr = s.charAt(0), x = 1, ru = {};\r
3797 \r
3798                                         // Extend with default rule data\r
3799                                         if (dr) {\r
3800                                                 if (dr.noEmpty)\r
3801                                                         ru.noEmpty = dr.noEmpty;\r
3802 \r
3803                                                 if (dr.fullEnd)\r
3804                                                         ru.fullEnd = dr.fullEnd;\r
3805 \r
3806                                                 if (dr.padd)\r
3807                                                         ru.padd = dr.padd;\r
3808                                         }\r
3809 \r
3810                                         // Handle prefixes\r
3811                                         switch (pr) {\r
3812                                                 case '-':\r
3813                                                         ru.noEmpty = true;\r
3814                                                         break;\r
3815 \r
3816                                                 case '+':\r
3817                                                         ru.fullEnd = true;\r
3818                                                         break;\r
3819 \r
3820                                                 case '#':\r
3821                                                         ru.padd = true;\r
3822                                                         break;\r
3823 \r
3824                                                 default:\r
3825                                                         x = 0;\r
3826                                         }\r
3827 \r
3828                                         tn[i] = s = s.substring(x);\r
3829                                         t.validElements[s] = 1;\r
3830 \r
3831                                         // Add element name or element regex\r
3832                                         if (/[*.?]/.test(tn[0])) {\r
3833                                                 ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$');\r
3834                                                 t.wildRules = t.wildRules || {};\r
3835                                                 t.wildRules.push(ru);\r
3836                                         } else {\r
3837                                                 ru.name = tn[0];\r
3838 \r
3839                                                 // Store away default rule\r
3840                                                 if (tn[0] == '@')\r
3841                                                         dr = ru;\r
3842 \r
3843                                                 t.rules[s] = ru;\r
3844                                         }\r
3845 \r
3846                                         ru.attribs = at;\r
3847 \r
3848                                         if (ra)\r
3849                                                 ru.requiredAttribs = ra;\r
3850 \r
3851                                         if (wat) {\r
3852                                                 // Build valid attributes regexp\r
3853                                                 s = '';\r
3854                                                 each(va, function(v) {\r
3855                                                         if (s)\r
3856                                                                 s += '|';\r
3857 \r
3858                                                         s += '(' + wildcardToRE(v) + ')';\r
3859                                                 });\r
3860                                                 ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$');\r
3861                                                 ru.wildAttribs = wat;\r
3862                                         }\r
3863                                 });\r
3864                         });\r
3865 \r
3866                         // Build valid elements regexp\r
3867                         s = '';\r
3868                         each(t.validElements, function(v, k) {\r
3869                                 if (s)\r
3870                                         s += '|';\r
3871 \r
3872                                 if (k != '@')\r
3873                                         s += k;\r
3874                         });\r
3875                         t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$');\r
3876 \r
3877                         //console.debug(t.validElementsRE.toString());\r
3878                         //console.dir(t.rules);\r
3879                         //console.dir(t.wildRules);\r
3880                 },\r
3881 \r
3882                 findRule : function(n) {\r
3883                         var t = this, rl = t.rules, i, r;\r
3884 \r
3885                         t._setup();\r
3886 \r
3887                         // Exact match\r
3888                         r = rl[n];\r
3889                         if (r)\r
3890                                 return r;\r
3891 \r
3892                         // Try wildcards\r
3893                         rl = t.wildRules;\r
3894                         for (i = 0; i < rl.length; i++) {\r
3895                                 if (rl[i].nameRE.test(n))\r
3896                                         return rl[i];\r
3897                         }\r
3898 \r
3899                         return null;\r
3900                 },\r
3901 \r
3902                 findAttribRule : function(ru, n) {\r
3903                         var i, wa = ru.wildAttribs;\r
3904 \r
3905                         for (i = 0; i < wa.length; i++) {\r
3906                                 if (wa[i].nameRE.test(n))\r
3907                                         return wa[i];\r
3908                         }\r
3909 \r
3910                         return null;\r
3911                 },\r
3912 \r
3913                 serialize : function(n, o) {\r
3914                         var h, t = this;\r
3915 \r
3916                         t._setup();\r
3917                         o = o || {};\r
3918                         o.format = o.format || 'html';\r
3919                         t.processObj = o;\r
3920                         n = n.cloneNode(true);\r
3921                         t.key = '' + (parseInt(t.key) + 1);\r
3922 \r
3923                         // Pre process\r
3924                         if (!o.no_events) {\r
3925                                 o.node = n;\r
3926                                 t.onPreProcess.dispatch(t, o);\r
3927                         }\r
3928 \r
3929                         // Serialize HTML DOM into a string\r
3930                         t.writer.reset();\r
3931                         t._serializeNode(n, o.getInner);\r
3932 \r
3933                         // Post process\r
3934                         o.content = t.writer.getContent();\r
3935 \r
3936                         if (!o.no_events)\r
3937                                 t.onPostProcess.dispatch(t, o);\r
3938 \r
3939                         t._postProcess(o);\r
3940                         o.node = null;\r
3941 \r
3942                         return tinymce.trim(o.content);\r
3943                 },\r
3944 \r
3945                 // Internal functions\r
3946 \r
3947                 _postProcess : function(o) {\r
3948                         var t = this, s = t.settings, h = o.content, sc = [], p, l;\r
3949 \r
3950                         if (o.format == 'html') {\r
3951                                 // Protect some elements\r
3952                                 p = t._protect({\r
3953                                         content : h,\r
3954                                         patterns : [\r
3955                                                 /(<script[^>]*>)(.*?)(<\/script>)/g,\r
3956                                                 /(<style[^>]*>)(.*?)(<\/style>)/g,\r
3957                                                 /(<pre[^>]*>)(.*?)(<\/pre>)/g\r
3958                                         ]\r
3959                                 });\r
3960 \r
3961                                 h = p.content;\r
3962 \r
3963                                 // Entity encode\r
3964                                 if (s.entity_encoding !== 'raw') {\r
3965                                         if (s.entity_encoding.indexOf('named') != -1) {\r
3966                                                 t.setEntities(s.entities);\r
3967                                                 l = t.entityLookup;\r
3968 \r
3969                                                 h = h.replace(t.entitiesRE, function(a) {\r
3970                                                         var v;\r
3971 \r
3972                                                         if (v = l[a])\r
3973                                                                 a = '&' + v + ';';\r
3974 \r
3975                                                         return a;\r
3976                                                 });\r
3977                                         }\r
3978 \r
3979                                         if (s.entity_encoding.indexOf('numeric') != -1) {\r
3980                                                 h = h.replace(/[\u007E-\uFFFF]/g, function(a) {\r
3981                                                         return '&#' + a.charCodeAt(0) + ';';\r
3982                                                 });\r
3983                                         }\r
3984                                 }\r
3985 \r
3986                                 // Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor\r
3987 /*                              if (o.set)\r
3988                                         h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');\r
3989                                 else\r
3990                                         h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');*/\r
3991 \r
3992                                 // Since Gecko and Safari keeps whitespace in the DOM we need to\r
3993                                 // remove it inorder to match other browsers. But I think Gecko and Safari is right.\r
3994                                 // This process is only done when getting contents out from the editor.\r
3995                                 if (!o.set) {\r
3996                                         // We need to replace paragraph whitespace with an nbsp before indentation to keep the \u00a0 char\r
3997                                         h = h.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g, s.entity_encoding == 'numeric' ? '<p$1>&#160;</p>' : '<p$1>&nbsp;</p>');\r
3998 \r
3999                                         if (s.remove_linebreaks) {\r
4000                                                 h = h.replace(/\r?\n|\r/g, ' ');\r
4001                                                 h = h.replace(/(<[^>]+>)\s+/g, '$1 ');\r
4002                                                 h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');\r
4003                                                 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
4004                                                 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
4005                                                 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
4006                                         }\r
4007 \r
4008                                         // Simple indentation\r
4009                                         if (s.apply_source_formatting && s.indent_mode == 'simple') {\r
4010                                                 // Add line breaks before and after block elements\r
4011                                                 h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');\r
4012                                                 h = h.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');\r
4013                                                 h = h.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');\r
4014                                                 h = h.replace(/\n\n/g, '\n');\r
4015                                         }\r
4016                                 }\r
4017 \r
4018                                 h = t._unprotect(h, p);\r
4019 \r
4020                                 // Restore the \u00a0 character if raw mode is enabled\r
4021                                 if (s.entity_encoding == 'raw')\r
4022                                         h = h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g, '<p$1>\u00a0</p>');\r
4023                         }\r
4024 \r
4025                         o.content = h;\r
4026                 },\r
4027 \r
4028                 _serializeNode : function(n, inn) {\r
4029                         var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;\r
4030 \r
4031                         if (!s.node_filter || s.node_filter(n)) {\r
4032                                 switch (n.nodeType) {\r
4033                                         case 1: // Element\r
4034                                                 if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))\r
4035                                                         return;\r
4036 \r
4037                                                 iv = false;\r
4038                                                 hc = n.hasChildNodes();\r
4039                                                 nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase();\r
4040 \r
4041                                                 // Add correct prefix on IE\r
4042                                                 if (isIE) {\r
4043                                                         if (n.scopeName !== 'HTML' && n.scopeName !== 'html')\r
4044                                                                 nn = n.scopeName + ':' + nn;\r
4045                                                 }\r
4046 \r
4047                                                 // Remove mce prefix on IE needed for the abbr element\r
4048                                                 if (nn.indexOf('mce:') === 0)\r
4049                                                         nn = nn.substring(4);\r
4050 \r
4051                                                 // Check if valid\r
4052                                                 if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {\r
4053                                                         iv = true;\r
4054                                                         break;\r
4055                                                 }\r
4056 \r
4057                                                 if (isIE) {\r
4058                                                         // Fix IE content duplication (DOM can have multiple copies of the same node)\r
4059                                                         if (s.fix_content_duplication) {\r
4060                                                                 if (n.mce_serialized == t.key)\r
4061                                                                         return;\r
4062 \r
4063                                                                 n.mce_serialized = t.key;\r
4064                                                         }\r
4065 \r
4066                                                         // IE sometimes adds a / infront of the node name\r
4067                                                         if (nn.charAt(0) == '/')\r
4068                                                                 nn = nn.substring(1);\r
4069                                                 } else if (isGecko) {\r
4070                                                         // Ignore br elements\r
4071                                                         if (n.nodeName === 'BR' && n.getAttribute('type') == '_moz')\r
4072                                                                 return;\r
4073                                                 }\r
4074 \r
4075                                                 // Check if valid child\r
4076                                                 if (t.childRules) {\r
4077                                                         if (t.parentElementsRE.test(t.elementName)) {\r
4078                                                                 if (!t.childRules[t.elementName].test(nn)) {\r
4079                                                                         iv = true;\r
4080                                                                         break;\r
4081                                                                 }\r
4082                                                         }\r
4083 \r
4084                                                         t.elementName = nn;\r
4085                                                 }\r
4086 \r
4087                                                 ru = t.findRule(nn);\r
4088                                                 nn = ru.name || nn;\r
4089 \r
4090                                                 // Skip empty nodes or empty node name in IE\r
4091                                                 if ((!hc && ru.noEmpty) || (isIE && !nn)) {\r
4092                                                         iv = true;\r
4093                                                         break;\r
4094                                                 }\r
4095 \r
4096                                                 // Check required\r
4097                                                 if (ru.requiredAttribs) {\r
4098                                                         a = ru.requiredAttribs;\r
4099 \r
4100                                                         for (i = a.length - 1; i >= 0; i--) {\r
4101                                                                 if (this.dom.getAttrib(n, a[i]) !== '')\r
4102                                                                         break;\r
4103                                                         }\r
4104 \r
4105                                                         // None of the required was there\r
4106                                                         if (i == -1) {\r
4107                                                                 iv = true;\r
4108                                                                 break;\r
4109                                                         }\r
4110                                                 }\r
4111 \r
4112                                                 w.writeStartElement(nn);\r
4113 \r
4114                                                 // Add ordered attributes\r
4115                                                 if (ru.attribs) {\r
4116                                                         for (i=0, at = ru.attribs, l = at.length; i<l; i++) {\r
4117                                                                 a = at[i];\r
4118                                                                 v = t._getAttrib(n, a);\r
4119 \r
4120                                                                 if (v !== null)\r
4121                                                                         w.writeAttribute(a.name, v);\r
4122                                                         }\r
4123                                                 }\r
4124 \r
4125                                                 // Add wild attributes\r
4126                                                 if (ru.validAttribsRE) {\r
4127                                                         at = isIE ? getIEAtts(n) : n.attributes;\r
4128                                                         for (i=at.length-1; i>-1; i--) {\r
4129                                                                 no = at[i];\r
4130 \r
4131                                                                 if (no.specified) {\r
4132                                                                         a = no.nodeName.toLowerCase();\r
4133 \r
4134                                                                         if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a))\r
4135                                                                                 continue;\r
4136 \r
4137                                                                         ar = t.findAttribRule(ru, a);\r
4138                                                                         v = t._getAttrib(n, ar, a);\r
4139 \r
4140                                                                         if (v !== null)\r
4141                                                                                 w.writeAttribute(a, v);\r
4142                                                                 }\r
4143                                                         }\r
4144                                                 }\r
4145 \r
4146                                                 // Padd empty nodes with a &nbsp;\r
4147                                                 if (!hc && ru.padd)\r
4148                                                         w.writeText('\u00a0');\r
4149 \r
4150                                                 break;\r
4151 \r
4152                                         case 3: // Text\r
4153                                                 // Check if valid child\r
4154                                                 if (t.childRules && t.parentElementsRE.test(t.elementName)) {\r
4155                                                         if (!t.childRules[t.elementName].test(n.nodeName))\r
4156                                                                 return;\r
4157                                                 }\r
4158 \r
4159                                                 return w.writeText(n.nodeValue);\r
4160 \r
4161                                         case 4: // CDATA\r
4162                                                 return w.writeCDATA(n.nodeValue);\r
4163 \r
4164                                         case 8: // Comment\r
4165                                                 return w.writeComment(n.nodeValue);\r
4166                                 }\r
4167                         } else if (n.nodeType == 1)\r
4168                                 hc = n.hasChildNodes();\r
4169 \r
4170                         if (hc) {\r
4171                                 cn = n.firstChild;\r
4172 \r
4173                                 while (cn) {\r
4174                                         t._serializeNode(cn);\r
4175                                         t.elementName = nn;\r
4176                                         cn = cn.nextSibling;\r
4177                                 }\r
4178                         }\r
4179 \r
4180                         // Write element end\r
4181                         if (!iv) {\r
4182                                 if (hc || !s.closed.test(nn))\r
4183                                         w.writeFullEndElement();\r
4184                                 else\r
4185                                         w.writeEndElement();\r
4186                         }\r
4187                 },\r
4188 \r
4189                 _protect : function(o) {\r
4190                         o.items = o.items || [];\r
4191 \r
4192                         function enc(s) {\r
4193                                 return s.replace(/[\r\n\\]/g, function(c) {\r
4194                                         if (c === '\n')\r
4195                                                 return '\\n';\r
4196                                         else if (c === '\\')\r
4197                                                 return '\\\\';\r
4198 \r
4199                                         return '\\r';\r
4200                                 });\r
4201                         };\r
4202 \r
4203                         function dec(s) {\r
4204                                 return s.replace(/\\[\\rn]/g, function(c) {\r
4205                                         if (c === '\\n')\r
4206                                                 return '\n';\r
4207                                         else if (c === '\\\\')\r
4208                                                 return '\\';\r
4209 \r
4210                                         return '\r';\r
4211                                 });\r
4212                         };\r
4213 \r
4214                         each(o.patterns, function(p) {\r
4215                                 o.content = dec(enc(o.content).replace(p, function(x, a, b, c) {\r
4216                                         o.items.push(dec(b));\r
4217                                         return a + '<!--mce:' + (o.items.length - 1) + '-->' + c;\r
4218                                 }));\r
4219                         });\r
4220 \r
4221                         return o;\r
4222                 },\r
4223 \r
4224                 _unprotect : function(h, o) {\r
4225                         h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) {\r
4226                                 return o.items[parseInt(b)];\r
4227                         });\r
4228 \r
4229                         o.items = [];\r
4230 \r
4231                         return h;\r
4232                 },\r
4233 \r
4234                 _setup : function() {\r
4235                         var t = this, s = this.settings;\r
4236 \r
4237                         if (t.done)\r
4238                                 return;\r
4239 \r
4240                         t.done = 1;\r
4241 \r
4242                         t.setRules(s.valid_elements);\r
4243                         t.addRules(s.extended_valid_elements);\r
4244                         t.addValidChildRules(s.valid_child_elements);\r
4245 \r
4246                         if (s.invalid_elements)\r
4247                                 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(',', '|').toLowerCase()) + ')$');\r
4248 \r
4249                         if (s.attrib_value_filter)\r
4250                                 t.attribValueFilter = s.attribValueFilter;\r
4251                 },\r
4252 \r
4253                 _getAttrib : function(n, a, na) {\r
4254                         var i, v;\r
4255 \r
4256                         na = na || a.name;\r
4257 \r
4258                         if (a.forcedVal && (v = a.forcedVal)) {\r
4259                                 if (v === '{$uid}')\r
4260                                         return this.dom.uniqueId();\r
4261 \r
4262                                 return v;\r
4263                         }\r
4264 \r
4265                         v = this.dom.getAttrib(n, na);\r
4266 \r
4267                         switch (na) {\r
4268                                 case 'rowspan':\r
4269                                 case 'colspan':\r
4270                                         // Whats the point? Remove usless attribute value\r
4271                                         if (v == '1')\r
4272                                                 v = '';\r
4273 \r
4274                                         break;\r
4275                         }\r
4276 \r
4277                         if (this.attribValueFilter)\r
4278                                 v = this.attribValueFilter(na, v, n);\r
4279 \r
4280                         if (a.validVals) {\r
4281                                 for (i = a.validVals.length - 1; i >= 0; i--) {\r
4282                                         if (v == a.validVals[i])\r
4283                                                 break;\r
4284                                 }\r
4285 \r
4286                                 if (i == -1)\r
4287                                         return null;\r
4288                         }\r
4289 \r
4290                         if (v === '' && typeof(a.defaultVal) != 'undefined') {\r
4291                                 v = a.defaultVal;\r
4292 \r
4293                                 if (v === '{$uid}')\r
4294                                         return this.dom.uniqueId();\r
4295 \r
4296                                 return v;\r
4297                         } else {\r
4298                                 // Remove internal mceItemXX classes when content is extracted from editor\r
4299                                 if (na == 'class' && this.processObj.get)\r
4300                                         v = v.replace(/\s?mceItem\w+\s?/g, '');\r
4301                         }\r
4302 \r
4303                         if (v === '')\r
4304                                 return null;\r
4305 \r
4306 \r
4307                         return v;\r
4308                 }\r
4309 \r
4310                 });\r
4311 })();\r
4312 \r
4313 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */\r
4314 \r
4315 (function() {\r
4316         var each = tinymce.each;\r
4317 \r
4318         tinymce.create('tinymce.dom.ScriptLoader', {\r
4319                 ScriptLoader : function(s) {\r
4320                         this.settings = s || {};\r
4321                         this.queue = [];\r
4322                         this.lookup = {};\r
4323                 },\r
4324 \r
4325                 isDone : function(u) {\r
4326                         return this.lookup[u] ? this.lookup[u].state == 2 : 0;\r
4327                 },\r
4328 \r
4329                 markDone : function(u) {\r
4330                         this.lookup[u] = {state : 2, url : u};\r
4331                 },\r
4332 \r
4333                 add : function(u, cb, s, pr) {\r
4334                         var t = this, lo = t.lookup, o;\r
4335 \r
4336                         if (o = lo[u]) {\r
4337                                 // Is loaded fire callback\r
4338                                 if (cb && o.state == 2)\r
4339                                         cb.call(s || this);\r
4340 \r
4341                                 return o;\r
4342                         }\r
4343 \r
4344                         o = {state : 0, url : u, func : cb, scope : s || this};\r
4345 \r
4346                         if (pr)\r
4347                                 t.queue.unshift(o);\r
4348                         else\r
4349                                 t.queue.push(o);\r
4350 \r
4351                         lo[u] = o;\r
4352 \r
4353                         return o;\r
4354                 },\r
4355 \r
4356                 load : function(u, cb, s) {\r
4357                         var t = this, o;\r
4358 \r
4359                         if (o = t.lookup[u]) {\r
4360                                 // Is loaded fire callback\r
4361                                 if (cb && o.state == 2)\r
4362                                         cb.call(s || t);\r
4363 \r
4364                                 return o;\r
4365                         }\r
4366 \r
4367                         function loadScript(u) {\r
4368                                 if (tinymce.dom.Event.domLoaded || t.settings.strict_mode) {\r
4369                                         tinymce.util.XHR.send({\r
4370                                                 url : u,\r
4371                                                 error : t.settings.error,\r
4372                                                 async : false,\r
4373                                                 success : function(co) {\r
4374                                                         t.eval(co);\r
4375                                                 }\r
4376                                         });\r
4377                                 } else\r
4378                                         document.write('<script type="text/javascript" src="' + u + '"></script>');\r
4379                         };\r
4380 \r
4381                         if (!tinymce.is(u, 'string')) {\r
4382                                 each(u, function(u) {\r
4383                                         loadScript(u);\r
4384                                 });\r
4385 \r
4386                                 if (cb)\r
4387                                         cb.call(s || t);\r
4388                         } else {\r
4389                                 loadScript(u);\r
4390 \r
4391                                 if (cb)\r
4392                                         cb.call(s || t);\r
4393                         }\r
4394                 },\r
4395 \r
4396                 loadQueue : function(cb, s) {\r
4397                         var t = this;\r
4398 \r
4399                         if (!t.queueLoading) {\r
4400                                 t.queueLoading = 1;\r
4401                                 t.queueCallbacks = [];\r
4402 \r
4403                                 t.loadScripts(t.queue, function() {\r
4404                                         t.queueLoading = 0;\r
4405 \r
4406                                         if (cb)\r
4407                                                 cb.call(s || t);\r
4408 \r
4409                                         each(t.queueCallbacks, function(o) {\r
4410                                                 o.func.call(o.scope);\r
4411                                         });\r
4412                                 });\r
4413                         } else if (cb)\r
4414                                 t.queueCallbacks.push({func : cb, scope : s || t});\r
4415                 },\r
4416 \r
4417                 eval : function(co) {\r
4418                         var w = window;\r
4419 \r
4420                         // Evaluate script\r
4421                         if (!w.execScript) {\r
4422                                 try {\r
4423                                         eval.call(w, co);\r
4424                                 } catch (ex) {\r
4425                                         eval(co, w); // Firefox 3.0a8\r
4426                                 }\r
4427                         } else\r
4428                                 w.execScript(co); // IE\r
4429                 },\r
4430 \r
4431                 loadScripts : function(sc, cb, s) {\r
4432                         var t = this, lo = t.lookup;\r
4433 \r
4434                         function done(o) {\r
4435                                 o.state = 2; // Has been loaded\r
4436 \r
4437                                 // Run callback\r
4438                                 if (o.func)\r
4439                                         o.func.call(o.scope || t);\r
4440                         };\r
4441 \r
4442                         function allDone() {\r
4443                                 var l;\r
4444 \r
4445                                 // Check if all files are loaded\r
4446                                 l = sc.length;\r
4447                                 each(sc, function(o) {\r
4448                                         o = lo[o.url];\r
4449 \r
4450                                         if (o.state === 2) {// It has finished loading\r
4451                                                 done(o);\r
4452                                                 l--;\r
4453                                         } else\r
4454                                                 load(o);\r
4455                                 });\r
4456 \r
4457                                 // They are all loaded\r
4458                                 if (l === 0 && cb) {\r
4459                                         cb.call(s || t);\r
4460                                         cb = 0;\r
4461                                 }\r
4462                         };\r
4463 \r
4464                         function load(o) {\r
4465                                 if (o.state > 0)\r
4466                                         return;\r
4467 \r
4468                                 o.state = 1; // Is loading\r
4469 \r
4470                                 tinymce.util.XHR.send({\r
4471                                         url : o.url,\r
4472                                         error : t.settings.error,\r
4473                                         success : function(co) {\r
4474                                                 t.eval(co);\r
4475                                                 done(o);\r
4476                                                 allDone();\r
4477                                         }\r
4478                                 });\r
4479                         };\r
4480 \r
4481                         each(sc, function(o) {\r
4482                                 var u = o.url;\r
4483 \r
4484                                 // Add to queue if needed\r
4485                                 if (!lo[u]) {\r
4486                                         lo[u] = o;\r
4487                                         t.queue.push(o);\r
4488                                 } else\r
4489                                         o = lo[u];\r
4490 \r
4491                                 // Is already loading or has been loaded\r
4492                                 if (o.state > 0)\r
4493                                         return;\r
4494 \r
4495                                 if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) {\r
4496                                         var ix, ol = '';\r
4497 \r
4498                                         // Add onload events\r
4499                                         if (cb || o.func) {\r
4500                                                 o.state = 1; // Is loading\r
4501 \r
4502                                                 ix = tinymce.dom.ScriptLoader._addOnLoad(function() {\r
4503                                                         done(o);\r
4504                                                         allDone();\r
4505                                                 });\r
4506 \r
4507                                                 if (tinymce.isIE)\r
4508                                                         ol = ' onreadystatechange="';\r
4509                                                 else\r
4510                                                         ol = ' onload="';\r
4511 \r
4512                                                 ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"';\r
4513                                         }\r
4514 \r
4515                                         document.write('<script type="text/javascript" src="' + u + '"' + ol + '></script>');\r
4516 \r
4517                                         if (!o.func)\r
4518                                                 done(o);\r
4519                                 } else\r
4520                                         load(o);\r
4521                         });\r
4522 \r
4523                         allDone();\r
4524                 },\r
4525 \r
4526                 // Static methods\r
4527                 'static' : {\r
4528                         _addOnLoad : function(f) {\r
4529                                 var t = this;\r
4530 \r
4531                                 t._funcs = t._funcs || [];\r
4532                                 t._funcs.push(f);\r
4533 \r
4534                                 return t._funcs.length - 1;\r
4535                         },\r
4536 \r
4537                         _onLoad : function(e, u, ix) {\r
4538                                 if (!tinymce.isIE || e.readyState == 'complete')\r
4539                                         this._funcs[ix].call(this);\r
4540                         }\r
4541                 }\r
4542 \r
4543                 });\r
4544 \r
4545         // Global script loader\r
4546         tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();\r
4547 })();\r
4548 \r
4549 /* file:jscripts/tiny_mce/classes/ui/Control.js */\r
4550 \r
4551 (function() {\r
4552         // Shorten class names\r
4553         var DOM = tinymce.DOM, is = tinymce.is;\r
4554 \r
4555         tinymce.create('tinymce.ui.Control', {\r
4556                 Control : function(id, s) {\r
4557                         this.id = id;\r
4558                         this.settings = s = s || {};\r
4559                         this.rendered = false;\r
4560                         this.onRender = new tinymce.util.Dispatcher(this);\r
4561                         this.classPrefix = '';\r
4562                         this.scope = s.scope || this;\r
4563                         this.disabled = 0;\r
4564                         this.active = 0;\r
4565                 },\r
4566 \r
4567                 setDisabled : function(s) {\r
4568                         var e;\r
4569 \r
4570                         if (s != this.disabled) {\r
4571                                 e = DOM.get(this.id);\r
4572 \r
4573                                 // Add accessibility title for unavailable actions\r
4574                                 if (e && this.settings.unavailable_prefix) {\r
4575                                         if (s) {\r
4576                                                 this.prevTitle = e.title;\r
4577                                                 e.title = this.settings.unavailable_prefix + ": " + e.title;\r
4578                                         } else\r
4579                                                 e.title = this.prevTitle;\r
4580                                 }\r
4581 \r
4582                                 this.setState('Disabled', s);\r
4583                                 this.setState('Enabled', !s);\r
4584                                 this.disabled = s;\r
4585                         }\r
4586                 },\r
4587 \r
4588                 isDisabled : function() {\r
4589                         return this.disabled;\r
4590                 },\r
4591 \r
4592                 setActive : function(s) {\r
4593                         if (s != this.active) {\r
4594                                 this.setState('Active', s);\r
4595                                 this.active = s;\r
4596                         }\r
4597                 },\r
4598 \r
4599                 isActive : function() {\r
4600                         return this.active;\r
4601                 },\r
4602 \r
4603                 setState : function(c, s) {\r
4604                         var n = DOM.get(this.id);\r
4605 \r
4606                         c = this.classPrefix + c;\r
4607 \r
4608                         if (s)\r
4609                                 DOM.addClass(n, c);\r
4610                         else\r
4611                                 DOM.removeClass(n, c);\r
4612                 },\r
4613 \r
4614                 isRendered : function() {\r
4615                         return this.rendered;\r
4616                 },\r
4617 \r
4618                 renderHTML : function() {\r
4619                 },\r
4620 \r
4621                 renderTo : function(n) {\r
4622                         DOM.setHTML(n, this.renderHTML());\r
4623                 },\r
4624 \r
4625                 postRender : function() {\r
4626                         var t = this, b;\r
4627 \r
4628                         // Set pending states\r
4629                         if (is(t.disabled)) {\r
4630                                 b = t.disabled;\r
4631                                 t.disabled = -1;\r
4632                                 t.setDisabled(b);\r
4633                         }\r
4634 \r
4635                         if (is(t.active)) {\r
4636                                 b = t.active;\r
4637                                 t.active = -1;\r
4638                                 t.setActive(b);\r
4639                         }\r
4640                 },\r
4641 \r
4642                 remove : function() {\r
4643                         DOM.remove(this.id);\r
4644                         this.destroy();\r
4645                 },\r
4646 \r
4647                 destroy : function() {\r
4648                         tinymce.dom.Event.clear(this.id);\r
4649                 }\r
4650 \r
4651                 });\r
4652 })();\r
4653 /* file:jscripts/tiny_mce/classes/ui/Container.js */\r
4654 \r
4655 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {\r
4656         Container : function(id, s) {\r
4657                 this.parent(id, s);\r
4658                 this.controls = [];\r
4659                 this.lookup = {};\r
4660         },\r
4661 \r
4662         add : function(c) {\r
4663                 this.lookup[c.id] = c;\r
4664                 this.controls.push(c);\r
4665 \r
4666                 return c;\r
4667         },\r
4668 \r
4669         get : function(n) {\r
4670                 return this.lookup[n];\r
4671         }\r
4672 \r
4673         });\r
4674 \r
4675 \r
4676 /* file:jscripts/tiny_mce/classes/ui/Separator.js */\r
4677 \r
4678 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {\r
4679         Separator : function(id, s) {\r
4680                 this.parent(id, s);\r
4681                 this.classPrefix = 'mceSeparator';\r
4682         },\r
4683 \r
4684         renderHTML : function() {\r
4685                 return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});\r
4686         }\r
4687 \r
4688         });\r
4689 \r
4690 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */\r
4691 \r
4692 (function() {\r
4693         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
4694 \r
4695         tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {\r
4696                 MenuItem : function(id, s) {\r
4697                         this.parent(id, s);\r
4698                         this.classPrefix = 'mceMenuItem';\r
4699                 },\r
4700 \r
4701                 setSelected : function(s) {\r
4702                         this.setState('Selected', s);\r
4703                         this.selected = s;\r
4704                 },\r
4705 \r
4706                 isSelected : function() {\r
4707                         return this.selected;\r
4708                 },\r
4709 \r
4710                 postRender : function() {\r
4711                         var t = this;\r
4712                         \r
4713                         t.parent();\r
4714 \r
4715                         // Set pending state\r
4716                         if (is(t.selected))\r
4717                                 t.setSelected(t.selected);\r
4718                 }\r
4719 \r
4720                 });\r
4721 })();\r
4722 \r
4723 /* file:jscripts/tiny_mce/classes/ui/Menu.js */\r
4724 \r
4725 (function() {\r
4726         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
4727 \r
4728         tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {\r
4729                 Menu : function(id, s) {\r
4730                         var t = this;\r
4731 \r
4732                         t.parent(id, s);\r
4733                         t.items = {};\r
4734                         t.collapsed = false;\r
4735                         t.menuCount = 0;\r
4736                         t.onAddItem = new tinymce.util.Dispatcher(this);\r
4737                 },\r
4738 \r
4739                 expand : function(d) {\r
4740                         var t = this;\r
4741 \r
4742                         if (d) {\r
4743                                 walk(t, function(o) {\r
4744                                         if (o.expand)\r
4745                                                 o.expand();\r
4746                                 }, 'items', t);\r
4747                         }\r
4748 \r
4749                         t.collapsed = false;\r
4750                 },\r
4751 \r
4752                 collapse : function(d) {\r
4753                         var t = this;\r
4754 \r
4755                         if (d) {\r
4756                                 walk(t, function(o) {\r
4757                                         if (o.collapse)\r
4758                                                 o.collapse();\r
4759                                 }, 'items', t);\r
4760                         }\r
4761 \r
4762                         t.collapsed = true;\r
4763                 },\r
4764 \r
4765                 isCollapsed : function() {\r
4766                         return this.collapsed;\r
4767                 },\r
4768 \r
4769                 add : function(o) {\r
4770                         if (!o.settings)\r
4771                                 o = new tinymce.ui.MenuItem(o.id || DOM.uniqueId(), o);\r
4772 \r
4773                         this.onAddItem.dispatch(this, o);\r
4774 \r
4775                         return this.items[o.id] = o;\r
4776                 },\r
4777 \r
4778                 addSeparator : function() {\r
4779                         return this.add({separator : true});\r
4780                 },\r
4781 \r
4782                 addMenu : function(o) {\r
4783                         if (!o.collapse)\r
4784                                 o = this.createMenu(o);\r
4785 \r
4786                         this.menuCount++;\r
4787 \r
4788                         return this.add(o);\r
4789                 },\r
4790 \r
4791                 hasMenus : function() {\r
4792                         return this.menuCount !== 0;\r
4793                 },\r
4794 \r
4795                 remove : function(o) {\r
4796                         delete this.items[o.id];\r
4797                 },\r
4798 \r
4799                 removeAll : function() {\r
4800                         var t = this;\r
4801 \r
4802                         walk(t, function(o) {\r
4803                                 if (o.removeAll)\r
4804                                         o.removeAll();\r
4805                                 else\r
4806                                         o.remove();\r
4807 \r
4808                                 o.destroy();\r
4809                         }, 'items', t);\r
4810 \r
4811                         t.items = {};\r
4812                 },\r
4813 \r
4814                 createMenu : function(o) {\r
4815                         var m = new tinymce.ui.Menu(o.id || DOM.uniqueId(), o);\r
4816 \r
4817                         m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem);\r
4818 \r
4819                         return m;\r
4820                 }\r
4821 \r
4822                 });\r
4823 })();\r
4824 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */\r
4825 \r
4826 (function() {\r
4827         var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;\r
4828 \r
4829         tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {\r
4830                 DropMenu : function(id, s) {\r
4831                         s = s || {};\r
4832                         s.container = s.container || DOM.doc.body;\r
4833                         s.offset_x = s.offset_x || 0;\r
4834                         s.offset_y = s.offset_y || 0;\r
4835                         s.vp_offset_x = s.vp_offset_x || 0;\r
4836                         s.vp_offset_y = s.vp_offset_y || 0;\r
4837 \r
4838                         if (is(s.icons) && !s.icons)\r
4839                                 s['class'] += ' mceNoIcons';\r
4840 \r
4841                         this.parent(id, s);\r
4842                         this.onShowMenu = new tinymce.util.Dispatcher(this);\r
4843                         this.onHideMenu = new tinymce.util.Dispatcher(this);\r
4844                         this.classPrefix = 'mceMenu';\r
4845 \r
4846                         // Fix for odd IE bug: #1903622\r
4847                         this.fixIE = tinymce.isIE && DOM.win.top != DOM.win;\r
4848                 },\r
4849 \r
4850                 createMenu : function(s) {\r
4851                         var t = this, cs = t.settings, m;\r
4852 \r
4853                         s.container = s.container || cs.container;\r
4854                         s.parent = t;\r
4855                         s.constrain = s.constrain || cs.constrain;\r
4856                         s['class'] = s['class'] || cs['class'];\r
4857                         s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x;\r
4858                         s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y;\r
4859                         m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s);\r
4860 \r
4861                         m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem);\r
4862 \r
4863                         return m;\r
4864                 },\r
4865 \r
4866                 update : function() {\r
4867                         var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;\r
4868 \r
4869                         tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth;\r
4870                         th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight;\r
4871 \r
4872                         if (!DOM.boxModel)\r
4873                                 t.element.setStyles({width : tw + 2, height : th + 2});\r
4874                         else\r
4875                                 t.element.setStyles({width : tw, height : th});\r
4876 \r
4877                         if (s.max_width)\r
4878                                 DOM.setStyle(co, 'width', tw);\r
4879 \r
4880                         if (s.max_height) {\r
4881                                 DOM.setStyle(co, 'height', th);\r
4882 \r
4883                                 if (tb.clientHeight < s.max_height)\r
4884                                         DOM.setStyle(co, 'overflow', 'hidden');\r
4885                         }\r
4886                 },\r
4887 \r
4888                 showMenu : function(x, y, px) {\r
4889                         var t = this, s = t.settings, co, vp = DOM.getViewPort(), w, h, mx, my, ot = 2, dm, tb, cp = t.classPrefix;\r
4890 \r
4891                         t.collapse(1);\r
4892 \r
4893                         if (t.isMenuVisible)\r
4894                                 return;\r
4895 \r
4896                         if (!t.rendered) {\r
4897                                 co = DOM.add(t.settings.container, t.renderNode());\r
4898 \r
4899                                 each(t.items, function(o) {\r
4900                                         o.postRender();\r
4901                                 });\r
4902 \r
4903                                 t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
4904                         } else\r
4905                                 co = DOM.get('menu_' + t.id);\r
4906 \r
4907                         // Move layer out of sight unless it's Opera since it scrolls to top of page due to an bug\r
4908                         if (!tinymce.isOpera)\r
4909                                 DOM.setStyles(co, {left : -0xFFFF , top : -0xFFFF});\r
4910 \r
4911                         DOM.show(co);\r
4912                         t.update();\r
4913 \r
4914                         x += s.offset_x || 0;\r
4915                         y += s.offset_y || 0;\r
4916                         vp.w -= 4;\r
4917                         vp.h -= 4;\r
4918 \r
4919                         // Move inside viewport if not submenu\r
4920                         if (s.constrain) {\r
4921                                 w = co.clientWidth - ot;\r
4922                                 h = co.clientHeight - ot;\r
4923                                 mx = vp.x + vp.w;\r
4924                                 my = vp.y + vp.h;\r
4925 \r
4926                                 if ((x + s.vp_offset_x + w) > mx)\r
4927                                         x = px ? px - w : Math.max(0, (mx - s.vp_offset_x) - w);\r
4928 \r
4929                                 if ((y + s.vp_offset_y + h) > my)\r
4930                                         y = Math.max(0, (my - s.vp_offset_y) - h);\r
4931                         }\r
4932 \r
4933                         DOM.setStyles(co, {left : x , top : y});\r
4934                         t.element.update();\r
4935 \r
4936                         t.isMenuVisible = 1;\r
4937                         t.mouseClickFunc = Event.add(co, t.fixIE ? 'mousedown' : 'click', function(e) {\r
4938                                 var m;\r
4939 \r
4940                                 e = e.target;\r
4941 \r
4942                                 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) {\r
4943                                         m = t.items[e.id];\r
4944 \r
4945                                         if (m.isDisabled())\r
4946                                                 return;\r
4947 \r
4948                                         dm = t;\r
4949 \r
4950                                         while (dm) {\r
4951                                                 if (dm.hideMenu)\r
4952                                                         dm.hideMenu();\r
4953 \r
4954                                                 dm = dm.settings.parent;\r
4955                                         }\r
4956 \r
4957                                         if (m.settings.onclick)\r
4958                                                 m.settings.onclick(e);\r
4959 \r
4960                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem\r
4961                                 }\r
4962                         });\r
4963 \r
4964                         if (t.hasMenus()) {\r
4965                                 t.mouseOverFunc = Event.add(co, 'mouseover', function(e) {\r
4966                                         var m, r, mi;\r
4967 \r
4968                                         e = e.target;\r
4969                                         if (e && (e = DOM.getParent(e, 'TR'))) {\r
4970                                                 m = t.items[e.id];\r
4971 \r
4972                                                 if (t.lastMenu)\r
4973                                                         t.lastMenu.collapse(1);\r
4974 \r
4975                                                 if (m.isDisabled())\r
4976                                                         return;\r
4977 \r
4978                                                 if (e && DOM.hasClass(e, cp + 'ItemSub')) {\r
4979                                                         //p = DOM.getPos(s.container);\r
4980                                                         r = DOM.getRect(e);\r
4981                                                         m.showMenu((r.x + r.w - ot), r.y - ot, r.x);\r
4982                                                         t.lastMenu = m;\r
4983                                                         DOM.addClass(DOM.get(m.id).firstChild, cp + 'ItemActive');\r
4984                                                 }\r
4985                                         }\r
4986                                 });\r
4987                         }\r
4988 \r
4989                         t.onShowMenu.dispatch(t);\r
4990 \r
4991                         if (s.keyboard_focus) {\r
4992                                 Event.add(co, 'keydown', t._keyHandler, t);\r
4993                                 DOM.select('a', 'menu_' + t.id)[0].focus(); // Select first link\r
4994                         }\r
4995                 },\r
4996 \r
4997                 hideMenu : function(c) {\r
4998                         var t = this, co = DOM.get('menu_' + t.id), e;\r
4999 \r
5000                         if (!t.isMenuVisible)\r
5001                                 return;\r
5002 \r
5003                         Event.remove(co, 'mouseover', t.mouseOverFunc);\r
5004                         Event.remove(co, t.fixIE ? 'mousedown' : 'click', t.mouseClickFunc);\r
5005                         Event.remove(co, 'keydown', t._keyHandler);\r
5006                         DOM.hide(co);\r
5007                         t.isMenuVisible = 0;\r
5008 \r
5009                         if (!c)\r
5010                                 t.collapse(1);\r
5011 \r
5012                         if (t.element)\r
5013                                 t.element.hide();\r
5014 \r
5015                         if (e = DOM.get(t.id))\r
5016                                 DOM.removeClass(e.firstChild, t.classPrefix + 'ItemActive');\r
5017 \r
5018                         t.onHideMenu.dispatch(t);\r
5019                 },\r
5020 \r
5021                 add : function(o) {\r
5022                         var t = this, co;\r
5023 \r
5024                         o = t.parent(o);\r
5025 \r
5026                         if (t.isRendered && (co = DOM.get('menu_' + t.id)))\r
5027                                 t._add(DOM.select('tbody', co)[0], o);\r
5028 \r
5029                         return o;\r
5030                 },\r
5031 \r
5032                 collapse : function(d) {\r
5033                         this.parent(d);\r
5034                         this.hideMenu(1);\r
5035                 },\r
5036 \r
5037                 remove : function(o) {\r
5038                         DOM.remove(o.id);\r
5039                         this.destroy();\r
5040 \r
5041                         return this.parent(o);\r
5042                 },\r
5043 \r
5044                 destroy : function() {\r
5045                         var t = this, co = DOM.get('menu_' + t.id);\r
5046 \r
5047                         Event.remove(co, 'mouseover', t.mouseOverFunc);\r
5048                         Event.remove(co, 'click', t.mouseClickFunc);\r
5049 \r
5050                         if (t.element)\r
5051                                 t.element.remove();\r
5052 \r
5053                         DOM.remove(co);\r
5054                 },\r
5055 \r
5056                 renderNode : function() {\r
5057                         var t = this, s = t.settings, n, tb, co, w;\r
5058 \r
5059                         w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:200000'});\r
5060                         co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : t.classPrefix + (s['class'] ? ' ' + s['class'] : '')});\r
5061                         t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
5062 \r
5063                         if (s.menu_line)\r
5064                                 DOM.add(co, 'span', {'class' : t.classPrefix + 'Line'});\r
5065 \r
5066 //                      n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'});\r
5067                         n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0});\r
5068                         tb = DOM.add(n, 'tbody');\r
5069 \r
5070                         each(t.items, function(o) {\r
5071                                 t._add(tb, o);\r
5072                         });\r
5073 \r
5074                         t.rendered = true;\r
5075 \r
5076                         return w;\r
5077                 },\r
5078 \r
5079                 // Internal functions\r
5080 \r
5081                 _keyHandler : function(e) {\r
5082                         // Accessibility feature\r
5083                         if (e.keyCode == 27)\r
5084                                 this.hideMenu();\r
5085                 },\r
5086 \r
5087                 _add : function(tb, o) {\r
5088                         var n, s = o.settings, a, ro, it, cp = this.classPrefix;\r
5089 \r
5090                         if (s.separator) {\r
5091                                 ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'ItemSeparator'});\r
5092                                 DOM.add(ro, 'td', {'class' : cp + 'ItemSeparator'});\r
5093 \r
5094                                 if (n = ro.previousSibling)\r
5095                                         DOM.addClass(n, 'mceLast');\r
5096 \r
5097                                 return;\r
5098                         }\r
5099 \r
5100                         n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'Item ' + cp + 'ItemEnabled'});\r
5101                         n = it = DOM.add(n, 'td');\r
5102                         n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});\r
5103 \r
5104                         DOM.addClass(it, s['class']);\r
5105 //                      n = DOM.add(n, 'span', {'class' : 'item'});\r
5106                         DOM.add(n, 'span', {'class' : 'mceIcon' + (s.icon ? ' mce_' + s.icon : '')});\r
5107                         n = DOM.add(n, s.element || 'span', {'class' : 'mceText', title : o.settings.title}, o.settings.title);\r
5108 \r
5109                         if (o.settings.style)\r
5110                                 DOM.setAttrib(n, 'style', o.settings.style);\r
5111 \r
5112                         if (tb.childNodes.length == 1)\r
5113                                 DOM.addClass(ro, 'mceFirst');\r
5114 \r
5115                         if ((n = ro.previousSibling) && DOM.hasClass(n, cp + 'ItemSeparator'))\r
5116                                 DOM.addClass(ro, 'mceFirst');\r
5117 \r
5118                         if (o.collapse)\r
5119                                 DOM.addClass(ro, cp + 'ItemSub');\r
5120 \r
5121                         if (n = ro.previousSibling)\r
5122                                 DOM.removeClass(n, 'mceLast');\r
5123 \r
5124                         DOM.addClass(ro, 'mceLast');\r
5125                 }\r
5126 \r
5127                 });\r
5128 })();\r
5129 /* file:jscripts/tiny_mce/classes/ui/Button.js */\r
5130 \r
5131 (function() {\r
5132         var DOM = tinymce.DOM;\r
5133 \r
5134         tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {\r
5135                 Button : function(id, s) {\r
5136                         this.parent(id, s);\r
5137                         this.classPrefix = 'mceButton';\r
5138                 },\r
5139 \r
5140                 renderHTML : function() {\r
5141                         var cp = this.classPrefix, s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="' + cp + ' ' + cp + 'Enabled ' + s['class'] + '" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">';\r
5142 \r
5143                         if (s.image)\r
5144                                 h += '<img class="mceIcon" src="' + s.image + '" /></a>';\r
5145                         else\r
5146                                 h += '<span class="mceIcon ' + s['class'] + '"></span></a>';\r
5147 \r
5148                         return h;\r
5149                 },\r
5150 \r
5151                 postRender : function() {\r
5152                         var t = this, s = t.settings;\r
5153 \r
5154                         tinymce.dom.Event.add(t.id, 'click', function(e) {\r
5155                                 if (!t.isDisabled())\r
5156                                         return s.onclick.call(s.scope, e);\r
5157                         });\r
5158                 }\r
5159 \r
5160                 });\r
5161 })();\r
5162 \r
5163 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */\r
5164 \r
5165 (function() {\r
5166         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
5167 \r
5168         tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {\r
5169                 ListBox : function(id, s) {\r
5170                         var t = this;\r
5171 \r
5172                         t.parent(id, s);\r
5173                         t.items = [];\r
5174                         t.onChange = new Dispatcher(t);\r
5175                         t.onPostRender = new Dispatcher(t);\r
5176                         t.onAdd = new Dispatcher(t);\r
5177                         t.onRenderMenu = new tinymce.util.Dispatcher(this);\r
5178                         t.classPrefix = 'mceListBox';\r
5179                 },\r
5180 \r
5181                 select : function(v) {\r
5182                         var t = this, e, fv;\r
5183 \r
5184                         // Do we need to do something?\r
5185                         if (v != t.selectedValue) {\r
5186                                 e = DOM.get(t.id + '_text');\r
5187                                 t.selectedValue = v;\r
5188 \r
5189                                 // Find item\r
5190                                 each(t.items, function(o) {\r
5191                                         if (o.value == v) {\r
5192                                                 DOM.setHTML(e, DOM.encode(o.title));\r
5193                                                 fv = 1;\r
5194                                                 return false;\r
5195                                         }\r
5196                                 });\r
5197 \r
5198                                 // If no item was found then present title\r
5199                                 if (!fv) {\r
5200                                         DOM.setHTML(e, DOM.encode(t.settings.title));\r
5201                                         DOM.addClass(e, 'mceTitle');\r
5202                                         e = 0;\r
5203                                         return;\r
5204                                 } else\r
5205                                         DOM.removeClass(e, 'mceTitle');\r
5206                         }\r
5207 \r
5208                         e = 0;\r
5209                 },\r
5210 \r
5211                 add : function(n, v, o) {\r
5212                         var t = this;\r
5213 \r
5214                         o = o || {};\r
5215                         o = tinymce.extend(o, {\r
5216                                 title : n,\r
5217                                 value : v\r
5218                         });\r
5219 \r
5220                         t.items.push(o);\r
5221                         t.onAdd.dispatch(t, o);\r
5222                 },\r
5223 \r
5224                 getLength : function() {\r
5225                         return this.items.length;\r
5226                 },\r
5227 \r
5228                 renderHTML : function() {\r
5229                         var h = '', t = this, s = t.settings, cp = t.classPrefix;\r
5230 \r
5231                         h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="' + cp + ' ' + cp + 'Enabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';\r
5232                         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
5233                         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
5234                         h += '</tr></tbody></table>';\r
5235 \r
5236                         return h;\r
5237                 },\r
5238 \r
5239                 showMenu : function() {\r
5240                         var t = this, p1, p2, e = DOM.get(this.id), m;\r
5241 \r
5242                         if (t.isDisabled() || t.items.length == 0)\r
5243                                 return;\r
5244 \r
5245                         if (!t.isMenuRendered) {\r
5246                                 t.renderMenu();\r
5247                                 t.isMenuRendered = true;\r
5248                         }\r
5249 \r
5250                         p1 = DOM.getPos(this.settings.menu_container);\r
5251                         p2 = DOM.getPos(e);\r
5252 \r
5253                         m = t.menu;\r
5254                         m.settings.offset_x = p2.x;\r
5255                         m.settings.offset_y = p2.y;\r
5256                         m.settings.keyboard_focus = t._focused;\r
5257 \r
5258                         // Select in menu\r
5259                         if (t.oldID)\r
5260                                 m.items[t.oldID].setSelected(0);\r
5261 \r
5262                         each(t.items, function(o) {\r
5263                                 if (o.value === t.selectedValue) {\r
5264                                         m.items[o.id].setSelected(1);\r
5265                                         t.oldID = o.id;\r
5266                                 }\r
5267                         });\r
5268 \r
5269                         m.showMenu(0, e.clientHeight);\r
5270 \r
5271                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5272                         DOM.addClass(t.id, t.classPrefix + 'Selected');\r
5273                 },\r
5274 \r
5275                 hideMenu : function(e) {\r
5276                         var t = this;\r
5277 \r
5278                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
5279                                 DOM.removeClass(t.id, t.classPrefix + 'Selected');\r
5280                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5281 \r
5282                                 if (t.menu)\r
5283                                         t.menu.hideMenu();\r
5284                         }\r
5285                 },\r
5286 \r
5287                 renderMenu : function() {\r
5288                         var t = this, m;\r
5289 \r
5290                         m = t.settings.control_manager.createDropMenu(t.id + '_menu', {\r
5291                                 menu_line : 1,\r
5292                                 'class' : t.classPrefix + 'Menu mceNoIcons',\r
5293                                 max_width : 150,\r
5294                                 max_height : 150\r
5295                         });\r
5296 \r
5297                         m.onHideMenu.add(t.hideMenu, t);\r
5298 \r
5299                         m.add({\r
5300                                 title : t.settings.title,\r
5301                                 'class' : 'mceMenuItemTitle'\r
5302                         }).setDisabled(1);\r
5303 \r
5304                         each(t.items, function(o) {\r
5305                                 o.id = DOM.uniqueId();\r
5306                                 o.onclick = function() {\r
5307                                         if (t.settings.onselect(o.value) !== false)\r
5308                                                 t.select(o.value); // Must be runned after\r
5309                                 };\r
5310 \r
5311                                 m.add(o);\r
5312                         });\r
5313 \r
5314                         t.onRenderMenu.dispatch(t, m);\r
5315                         t.menu = m;\r
5316                 },\r
5317 \r
5318                 postRender : function() {\r
5319                         var t = this, cp = t.classPrefix;\r
5320 \r
5321                         Event.add(t.id, 'click', t.showMenu, t);\r
5322                         Event.add(t.id + '_text', 'focus', function() {t._focused = 1;});\r
5323                         Event.add(t.id + '_text', 'blur', function() {t._focused = 0;});\r
5324 \r
5325                         // Old IE doesn't have hover on all elements\r
5326                         if (tinymce.isIE6 || !DOM.boxModel) {\r
5327                                 Event.add(t.id, 'mouseover', function() {\r
5328                                         if (!DOM.hasClass(t.id, cp + 'Disabled'))\r
5329                                                 DOM.addClass(t.id, cp + 'Hover');\r
5330                                 });\r
5331 \r
5332                                 Event.add(t.id, 'mouseout', function() {\r
5333                                         if (!DOM.hasClass(t.id, cp + 'Disabled'))\r
5334                                                 DOM.removeClass(t.id, cp + 'Hover');\r
5335                                 });\r
5336                         }\r
5337 \r
5338                         t.onPostRender.dispatch(t, DOM.get(t.id));\r
5339                 },\r
5340 \r
5341                 destroy : function() {\r
5342                         this.parent();\r
5343 \r
5344                         Event.clear(this.id + '_text');\r
5345                 }\r
5346 \r
5347                 });\r
5348 })();\r
5349 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */\r
5350 \r
5351 (function() {\r
5352         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
5353 \r
5354         tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {\r
5355                 NativeListBox : function(id, s) {\r
5356                         this.parent(id, s);\r
5357                         this.classPrefix = 'mceNativeListBox';\r
5358                 },\r
5359 \r
5360                 setDisabled : function(s) {\r
5361                         DOM.get(this.id).disabled = s;\r
5362                 },\r
5363 \r
5364                 isDisabled : function() {\r
5365                         return DOM.get(this.id).disabled;\r
5366                 },\r
5367 \r
5368                 select : function(v) {\r
5369                         var e = DOM.get(this.id), ol = e.options;\r
5370 \r
5371                         v = '' + (v || '');\r
5372 \r
5373                         e.selectedIndex = 0;\r
5374                         each(ol, function(o, i) {\r
5375                                 if (o.value == v) {\r
5376                                         e.selectedIndex = i;\r
5377                                         return false;\r
5378                                 }\r
5379                         });\r
5380                 },\r
5381 \r
5382                 add : function(n, v, a) {\r
5383                         var o, t = this;\r
5384 \r
5385                         a = a || {};\r
5386                         a.value = v;\r
5387 \r
5388                         if (t.isRendered())\r
5389                                 DOM.add(DOM.get(this.id), 'option', a, n);\r
5390 \r
5391                         o = {\r
5392                                 title : n,\r
5393                                 value : v,\r
5394                                 attribs : a\r
5395                         };\r
5396 \r
5397                         t.items.push(o);\r
5398                         t.onAdd.dispatch(t, o);\r
5399                 },\r
5400 \r
5401                 getLength : function() {\r
5402                         return DOM.get(this.id).options.length - 1;\r
5403                 },\r
5404 \r
5405                 renderHTML : function() {\r
5406                         var h, t = this;\r
5407 \r
5408                         h = DOM.createHTML('option', {value : ''}, '-- ' + t.settings.title + ' --');\r
5409 \r
5410                         each(t.items, function(it) {\r
5411                                 h += DOM.createHTML('option', {value : it.value}, it.title);\r
5412                         });\r
5413 \r
5414                         h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h);\r
5415 \r
5416                         return h;\r
5417                 },\r
5418 \r
5419                 postRender : function() {\r
5420                         var t = this, ch;\r
5421 \r
5422                         t.rendered = true;\r
5423 \r
5424                         function onChange(e) {\r
5425                                 var v = e.target.options[e.target.selectedIndex].value;\r
5426 \r
5427                                 t.onChange.dispatch(t, v);\r
5428 \r
5429                                 if (t.settings.onselect)\r
5430                                         t.settings.onselect(v);\r
5431                         };\r
5432 \r
5433                         Event.add(t.id, 'change', onChange);\r
5434 \r
5435                         // Accessibility keyhandler\r
5436                         Event.add(t.id, 'keydown', function(e) {\r
5437                                 var bf;\r
5438 \r
5439                                 Event.remove(t.id, 'change', ch);\r
5440 \r
5441                                 bf = Event.add(t.id, 'blur', function() {\r
5442                                         Event.add(t.id, 'change', onChange);\r
5443                                         Event.remove(t.id, 'blur', bf);\r
5444                                 });\r
5445 \r
5446                                 if (e.keyCode == 13 || e.keyCode == 32) {\r
5447                                         onChange(e);\r
5448                                         return Event.cancel(e);\r
5449                                 }\r
5450                         });\r
5451 \r
5452                         t.onPostRender.dispatch(t, DOM.get(t.id));\r
5453                 }\r
5454 \r
5455                 });\r
5456 })();\r
5457 /* file:jscripts/tiny_mce/classes/ui/MenuButton.js */\r
5458 \r
5459 (function() {\r
5460         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
5461 \r
5462         tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {\r
5463                 MenuButton : function(id, s) {\r
5464                         this.parent(id, s);\r
5465                         this.onRenderMenu = new tinymce.util.Dispatcher(this);\r
5466                         s.menu_container = s.menu_container || DOM.doc.body;\r
5467                 },\r
5468 \r
5469                 showMenu : function() {\r
5470                         var t = this, p1, p2, e = DOM.get(t.id), m;\r
5471 \r
5472                         if (t.isDisabled())\r
5473                                 return;\r
5474 \r
5475                         if (!t.isMenuRendered) {\r
5476                                 t.renderMenu();\r
5477                                 t.isMenuRendered = true;\r
5478                         }\r
5479 \r
5480                         p1 = DOM.getPos(t.settings.menu_container);\r
5481                         p2 = DOM.getPos(e);\r
5482 \r
5483                         m = t.menu;\r
5484                         m.settings.offset_x = p2.x;\r
5485                         m.settings.offset_y = p2.y;\r
5486                         m.settings.vp_offset_x = p2.x;\r
5487                         m.settings.vp_offset_y = p2.y;\r
5488                         m.settings.keyboard_focus = t._focused;\r
5489                         m.showMenu(0, e.clientHeight);\r
5490 \r
5491                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5492                         t.setState('Selected', 1);\r
5493                 },\r
5494 \r
5495                 renderMenu : function() {\r
5496                         var t = this, m;\r
5497 \r
5498                         m = t.settings.control_manager.createDropMenu(t.id + '_menu', {\r
5499                                 menu_line : 1,\r
5500                                 'class' : this.classPrefix + 'Menu',\r
5501                                 icons : t.settings.icons\r
5502                         });\r
5503 \r
5504                         m.onHideMenu.add(t.hideMenu, t);\r
5505 \r
5506                         t.onRenderMenu.dispatch(t, m);\r
5507                         t.menu = m;\r
5508                 },\r
5509 \r
5510                 hideMenu : function(e) {\r
5511                         var t = this;\r
5512 \r
5513                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
5514                                 t.setState('Selected', 0);\r
5515                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5516                                 if (t.menu)\r
5517                                         t.menu.hideMenu();\r
5518                         }\r
5519                 },\r
5520 \r
5521                 postRender : function() {\r
5522                         var t = this, s = t.settings;\r
5523 \r
5524                         Event.add(t.id, 'click', function() {\r
5525                                 if (!t.isDisabled()) {\r
5526                                         if (s.onclick)\r
5527                                                 s.onclick(t.value);\r
5528 \r
5529                                         t.showMenu();\r
5530                                 }\r
5531                         });\r
5532                 }\r
5533 \r
5534                 });\r
5535 })();\r
5536 \r
5537 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */\r
5538 \r
5539 (function() {\r
5540         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
5541 \r
5542         tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {\r
5543                 SplitButton : function(id, s) {\r
5544                         this.parent(id, s);\r
5545                         this.classPrefix = 'mceSplitButton';\r
5546                 },\r
5547 \r
5548                 renderHTML : function() {\r
5549                         var h, t = this, s = t.settings, h1;\r
5550 \r
5551                         h = '<tbody><tr>';\r
5552 \r
5553                         if (s.image)\r
5554                                 h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'mceAction ' + s['class']});\r
5555                         else\r
5556                                 h1 = DOM.createHTML('span', {'class' : 'mceAction ' + s['class']}, '');\r
5557 \r
5558                         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
5559         \r
5560                         h1 = DOM.createHTML('span', {'class' : 'mceOpen ' + s['class']});\r
5561                         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
5562 \r
5563                         h += '</tr></tbody>';\r
5564 \r
5565                         return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);\r
5566                 },\r
5567 \r
5568                 postRender : function() {\r
5569                         var t = this, s = t.settings;\r
5570 \r
5571                         if (s.onclick) {\r
5572                                 Event.add(t.id + '_action', 'click', function() {\r
5573                                         if (!t.isDisabled())\r
5574                                                 s.onclick(t.value);\r
5575                                 });\r
5576                         }\r
5577 \r
5578                         Event.add(t.id + '_open', 'click', t.showMenu, t);\r
5579                         Event.add(t.id + '_open', 'focus', function() {t._focused = 1;});\r
5580                         Event.add(t.id + '_open', 'blur', function() {t._focused = 0;});\r
5581 \r
5582                         // Old IE doesn't have hover on all elements\r
5583                         if (tinymce.isIE6 || !DOM.boxModel) {\r
5584                                 Event.add(t.id, 'mouseover', function() {\r
5585                                         if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))\r
5586                                                 DOM.addClass(t.id, 'mceSplitButtonHover');\r
5587                                 });\r
5588 \r
5589                                 Event.add(t.id, 'mouseout', function() {\r
5590                                         if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))\r
5591                                                 DOM.removeClass(t.id, 'mceSplitButtonHover');\r
5592                                 });\r
5593                         }\r
5594                 },\r
5595 \r
5596                 destroy : function() {\r
5597                         this.parent();\r
5598 \r
5599                         Event.clear(this.id + '_action');\r
5600                         Event.clear(this.id + '_open');\r
5601                 }\r
5602 \r
5603                 });\r
5604 })();\r
5605 \r
5606 /* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */\r
5607 \r
5608 (function() {\r
5609         var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;\r
5610 \r
5611         tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {\r
5612                 ColorSplitButton : function(id, s) {\r
5613                         var t = this;\r
5614 \r
5615                         t.parent(id, s);\r
5616 \r
5617                         t.settings = s = tinymce.extend({\r
5618                                 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
5619                                 grid_width : 8,\r
5620                                 default_color : '#888888'\r
5621                         }, t.settings);\r
5622 \r
5623                         t.value = s.default_color;\r
5624                 },\r
5625 \r
5626                 showMenu : function() {\r
5627                         var t = this, r, p, e, p2;\r
5628 \r
5629                         if (t.isDisabled())\r
5630                                 return;\r
5631 \r
5632                         if (!t.isMenuRendered) {\r
5633                                 t.renderMenu();\r
5634                                 t.isMenuRendered = true;\r
5635                         }\r
5636 \r
5637                         e = DOM.get(t.id);\r
5638                         DOM.show(t.id + '_menu');\r
5639                         DOM.addClass(e, 'mceSplitButtonSelected');\r
5640                         p2 = DOM.getPos(e);\r
5641                         DOM.setStyles(t.id + '_menu', {\r
5642                                 left : p2.x,\r
5643                                 top : p2.y + e.clientHeight,\r
5644                                 zIndex : 200000\r
5645                         });\r
5646                         e = 0;\r
5647 \r
5648                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);\r
5649 \r
5650                         if (t._focused) {\r
5651                                 t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {\r
5652                                         if (e.keyCode == 27)\r
5653                                                 t.hideMenu();\r
5654                                 });\r
5655 \r
5656                                 DOM.select('a', t.id + '_menu')[0].focus(); // Select first link\r
5657                         }\r
5658                 },\r
5659 \r
5660                 hideMenu : function(e) {\r
5661                         var t = this;\r
5662 \r
5663                         if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {\r
5664                                 DOM.removeClass(t.id, 'mceSplitButtonSelected');\r
5665                                 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
5666                                 Event.remove(t.id + '_menu', 'keydown', t._keyHandler);\r
5667                                 DOM.hide(t.id + '_menu');\r
5668                         }\r
5669                 },\r
5670 \r
5671                 renderMenu : function() {\r
5672                         var t = this, m, i = 0, s = t.settings, n, tb, tr, w;\r
5673 \r
5674                         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
5675                         m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});\r
5676                         DOM.add(m, 'span', {'class' : 'mceMenuLine'});\r
5677 \r
5678                         n = DOM.add(m, 'table', {'class' : 'mceColorSplitMenu'});\r
5679                         tb = DOM.add(n, 'tbody');\r
5680 \r
5681                         // Generate color grid\r
5682                         i = 0;\r
5683                         each(is(s.colors, 'array') ? s.colors : s.colors.split(','), function(c) {\r
5684                                 c = c.replace(/^#/, '');\r
5685 \r
5686                                 if (!i--) {\r
5687                                         tr = DOM.add(tb, 'tr');\r
5688                                         i = s.grid_width - 1;\r
5689                                 }\r
5690 \r
5691                                 n = DOM.add(tr, 'td');\r
5692 \r
5693                                 n = DOM.add(n, 'a', {\r
5694                                         href : 'javascript:;',\r
5695                                         style : {\r
5696                                                 backgroundColor : '#' + c\r
5697                                         },\r
5698                                         mce_color : '#' + c\r
5699                                 });\r
5700                         });\r
5701 \r
5702                         if (s.more_colors_func) {\r
5703                                 n = DOM.add(tb, 'tr');\r
5704                                 n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'mceMoreColors'});\r
5705                                 n = DOM.add(n, 'a', {id : t.id + '_more', href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);\r
5706 \r
5707                                 Event.add(n, 'click', function(e) {\r
5708                                         s.more_colors_func.call(s.more_colors_scope || this);\r
5709                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem\r
5710                                 });\r
5711                         }\r
5712 \r
5713                         DOM.addClass(m, 'mceColorSplitMenu');\r
5714 \r
5715                         Event.add(t.id + '_menu', 'click', function(e) {\r
5716                                 var c;\r
5717 \r
5718                                 e = e.target;\r
5719 \r
5720                                 if (e.nodeName == 'A' && (c = e.getAttribute('mce_color')))\r
5721                                         t.setColor(c);\r
5722                         });\r
5723 \r
5724                         return w;\r
5725                 },\r
5726 \r
5727                 setColor : function(c) {\r
5728                         var t = this;\r
5729 \r
5730                         DOM.setStyle(t.id + '_preview', 'backgroundColor', c);\r
5731 \r
5732                         t.value = c;\r
5733                         t.hideMenu();\r
5734                         t.settings.onselect(c);\r
5735                 },\r
5736 \r
5737                 postRender : function() {\r
5738                         var t = this, id = t.id;\r
5739 \r
5740                         t.parent();\r
5741                         DOM.add(id + '_action', 'div', {id : id + '_preview', 'class' : 'mceColorPreview'});\r
5742                 },\r
5743 \r
5744                 destroy : function() {\r
5745                         this.parent();\r
5746 \r
5747                         Event.clear(this.id + '_menu');\r
5748                         Event.clear(this.id + '_more');\r
5749                         DOM.remove(this.id + '_menu');\r
5750                 }\r
5751 \r
5752                 });\r
5753 })();\r
5754 \r
5755 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */\r
5756 \r
5757 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {\r
5758         renderHTML : function() {\r
5759                 var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl;\r
5760 \r
5761                 cl = t.controls;\r
5762                 for (i=0; i<cl.length; i++) {\r
5763                         // Get current control, prev control, next control and if the control is a list box or not\r
5764                         co = cl[i];\r
5765                         pr = cl[i - 1];\r
5766                         nx = cl[i + 1];\r
5767 \r
5768                         // Add toolbar start\r
5769                         if (i === 0) {\r
5770                                 c = 'mceToolbarStart';\r
5771 \r
5772                                 if (co.Button)\r
5773                                         c += ' mceToolbarStartButton';\r
5774                                 else if (co.SplitButton)\r
5775                                         c += ' mceToolbarStartSplitButton';\r
5776                                 else if (co.ListBox)\r
5777                                         c += ' mceToolbarStartListBox';\r
5778 \r
5779                                 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
5780                         }\r
5781 \r
5782                         // Add toolbar end before list box and after the previous button\r
5783                         // This is to fix the o2k7 editor skins\r
5784                         if (pr && co.ListBox) {\r
5785                                 if (pr.Button || pr.SplitButton)\r
5786                                         h += dom.createHTML('td', {'class' : 'mceToolbarEnd'}, dom.createHTML('span', null, '<!-- IE -->'));\r
5787                         }\r
5788 \r
5789                         // Render control HTML\r
5790 \r
5791                         // IE 8 quick fix, needed to propertly generate a hit area for anchors\r
5792                         if (dom.stdMode)\r
5793                                 h += '<td style="position: relative">' + co.renderHTML() + '</td>';\r
5794                         else\r
5795                                 h += '<td>' + co.renderHTML() + '</td>';\r
5796 \r
5797                         // Add toolbar start after list box and before the next button\r
5798                         // This is to fix the o2k7 editor skins\r
5799                         if (nx && co.ListBox) {\r
5800                                 if (nx.Button || nx.SplitButton)\r
5801                                         h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->'));\r
5802                         }\r
5803                 }\r
5804 \r
5805                 c = 'mceToolbarEnd';\r
5806 \r
5807                 if (co.Button)\r
5808                         c += ' mceToolbarEndButton';\r
5809                 else if (co.SplitButton)\r
5810                         c += ' mceToolbarEndSplitButton';\r
5811                 else if (co.ListBox)\r
5812                         c += ' mceToolbarEndListBox';\r
5813 \r
5814                 h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
5815 \r
5816                 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
5817         }\r
5818 \r
5819         });\r
5820 \r
5821 /* file:jscripts/tiny_mce/classes/AddOnManager.js */\r
5822 \r
5823 (function() {\r
5824         var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;\r
5825 \r
5826         tinymce.create('tinymce.AddOnManager', {\r
5827                 items : [],\r
5828                 urls : {},\r
5829                 lookup : {},\r
5830                 onAdd : new Dispatcher(this),\r
5831 \r
5832                 get : function(n) {\r
5833                         return this.lookup[n];\r
5834                 },\r
5835 \r
5836                 requireLangPack : function(n) {\r
5837                         var u, s;\r
5838 \r
5839                         if (tinymce.EditorManager.settings) {\r
5840                                 u = this.urls[n] + '/langs/' + tinymce.EditorManager.settings.language + '.js';\r
5841                                 s = tinymce.EditorManager.settings;\r
5842 \r
5843                                 if (s) {\r
5844                                         if (!tinymce.dom.Event.domLoaded && !s.strict_mode)\r
5845                                                 tinymce.ScriptLoader.load(u);\r
5846                                         else\r
5847                                                 tinymce.ScriptLoader.add(u);\r
5848                                 }\r
5849                         }\r
5850                 },\r
5851 \r
5852                 add : function(id, o) {\r
5853                         this.items.push(o);\r
5854                         this.lookup[id] = o;\r
5855                         this.onAdd.dispatch(this, id, o);\r
5856 \r
5857                         return o;\r
5858                 },\r
5859 \r
5860                 load : function(n, u, cb, s) {\r
5861                         var t = this;\r
5862 \r
5863                         if (t.urls[n])\r
5864                                 return;\r
5865 \r
5866                         if (u.indexOf('/') != 0 && u.indexOf('://') == -1)\r
5867                                 u = tinymce.baseURL + '/' +  u;\r
5868 \r
5869                         t.urls[n] = u.substring(0, u.lastIndexOf('/'));\r
5870                         tinymce.ScriptLoader.add(u, cb, s);\r
5871                 }\r
5872 \r
5873                 });\r
5874 \r
5875         // Create plugin and theme managers\r
5876         tinymce.PluginManager = new tinymce.AddOnManager();\r
5877         tinymce.ThemeManager = new tinymce.AddOnManager();\r
5878 }());\r
5879 /* file:jscripts/tiny_mce/classes/EditorManager.js */\r
5880 \r
5881 (function() {\r
5882         // Shorten names\r
5883         var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;\r
5884 \r
5885         tinymce.create('static tinymce.EditorManager', {\r
5886                 editors : {},\r
5887                 i18n : {},\r
5888                 activeEditor : null,\r
5889 \r
5890                 preInit : function() {\r
5891                         var t = this, lo = window.location;\r
5892 \r
5893                         // Setup some URLs where the editor API is located and where the document is\r
5894                         tinymce.documentBaseURL = lo.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');\r
5895                         if (!/[\/\\]$/.test(tinymce.documentBaseURL))\r
5896                                 tinymce.documentBaseURL += '/';\r
5897 \r
5898                         tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);\r
5899                         tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);\r
5900 \r
5901                         // Setup document domain\r
5902                         if (tinymce.EditorManager.baseURI.host != lo.hostname && lo.hostname)\r
5903                                 document.domain = tinymce.relaxedDomain = lo.hostname.replace(/.*\.(.+\..+)$/, '$1');\r
5904 \r
5905                         // Add before unload listener\r
5906                         // This was required since IE was leaking memory if you added and removed beforeunload listeners\r
5907                         // with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event\r
5908                         t.onBeforeUnload = new tinymce.util.Dispatcher(t);\r
5909 \r
5910                         // Must be on window or IE will leak if the editor is placed in frame or iframe\r
5911                         Event.add(window, 'beforeunload', function(e) {\r
5912                                 t.onBeforeUnload.dispatch(t, e);\r
5913                         });\r
5914                 },\r
5915 \r
5916                 init : function(s) {\r
5917                         var t = this, pl, sl = tinymce.ScriptLoader, c;\r
5918 \r
5919                         function execCallback(se, n, s) {\r
5920                                 var f = se[n];\r
5921 \r
5922                                 if (!f)\r
5923                                         return;\r
5924 \r
5925                                 if (tinymce.is(f, 'string')) {\r
5926                                         s = f.replace(/\.\w+$/, '');\r
5927                                         s = s ? tinymce.resolve(s) : 0;\r
5928                                         f = tinymce.resolve(f);\r
5929                                 }\r
5930 \r
5931                                 return f.apply(s || this, Array.prototype.slice.call(arguments, 2));\r
5932                         };\r
5933 \r
5934                         s = extend({\r
5935                                 theme : "simple",\r
5936                                 language : "en",\r
5937                                 strict_loading_mode : document.contentType == 'application/xhtml+xml'\r
5938                         }, s);\r
5939 \r
5940                         t.settings = s;\r
5941 \r
5942                         // If page not loaded and strict mode isn't enabled then load them\r
5943                         if (!Event.domLoaded && !s.strict_loading_mode) {\r
5944                                 // Load language\r
5945                                 if (s.language)\r
5946                                         sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
5947 \r
5948                                 // Load theme\r
5949                                 if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
5950                                         ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
5951 \r
5952                                 // Load plugins\r
5953                                 if (s.plugins) {\r
5954                                         pl = explode(s.plugins);\r
5955 \r
5956                                         // Load compat2x first\r
5957                                         if (tinymce.inArray(pl, 'compat2x') != -1)\r
5958                                                 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');\r
5959 \r
5960                                         // Load rest if plugins\r
5961                                         each(pl, function(v) {\r
5962                                                 if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) {\r
5963                                                         // Skip safari plugin for other browsers\r
5964                                                         if (!tinymce.isWebKit && v == 'safari')\r
5965                                                                 return;\r
5966 \r
5967                                                         PluginManager.load(v, 'plugins/' + v + '/editor_plugin' + tinymce.suffix + '.js');\r
5968                                                 }\r
5969                                         });\r
5970                                 }\r
5971 \r
5972                                 sl.loadQueue();\r
5973                         }\r
5974 \r
5975                         // Legacy call\r
5976                         Event.add(document, 'init', function() {\r
5977                                 var l, co;\r
5978 \r
5979                                 execCallback(s, 'onpageload');\r
5980 \r
5981                                 // Verify that it's a valid browser\r
5982                                 if (s.browsers) {\r
5983                                         l = false;\r
5984 \r
5985                                         each(explode(s.browsers), function(v) {\r
5986                                                 switch (v) {\r
5987                                                         case 'ie':\r
5988                                                         case 'msie':\r
5989                                                                 if (tinymce.isIE)\r
5990                                                                         l = true;\r
5991                                                                 break;\r
5992 \r
5993                                                         case 'gecko':\r
5994                                                                 if (tinymce.isGecko)\r
5995                                                                         l = true;\r
5996                                                                 break;\r
5997 \r
5998                                                         case 'safari':\r
5999                                                         case 'webkit':\r
6000                                                                 if (tinymce.isWebKit)\r
6001                                                                         l = true;\r
6002                                                                 break;\r
6003 \r
6004                                                         case 'opera':\r
6005                                                                 if (tinymce.isOpera)\r
6006                                                                         l = true;\r
6007 \r
6008                                                                 break;\r
6009                                                 }\r
6010                                         });\r
6011 \r
6012                                         // Not a valid one\r
6013                                         if (!l)\r
6014                                                 return;\r
6015                                 }\r
6016 \r
6017                                 switch (s.mode) {\r
6018                                         case "exact":\r
6019                                                 l = s.elements || '';\r
6020 \r
6021                                                 if(l.length > 0) {\r
6022                                                         each(explode(l), function(v) {\r
6023                                                                 if (DOM.get(v))\r
6024                                                                         new tinymce.Editor(v, s).render(1);\r
6025                                                                 else {\r
6026                                                                         c = 0;\r
6027 \r
6028                                                                         each(document.forms, function(f) {\r
6029                                                                                 each(f.elements, function(e) {\r
6030                                                                                         if (e.name === v) {\r
6031                                                                                                 v = 'mce_editor_' + c;\r
6032                                                                                                 DOM.setAttrib(e, 'id', v);\r
6033                                                                                                 new tinymce.Editor(v, s).render(1);\r
6034                                                                                         }\r
6035                                                                                 });\r
6036                                                                         });\r
6037                                                                 }\r
6038                                                         });\r
6039                                                 }\r
6040                                                 break;\r
6041 \r
6042                                         case "textareas":\r
6043                                         case "specific_textareas":\r
6044                                                 function hasClass(n, c) {\r
6045                                                         return new RegExp('\\b' + c + '\\b', 'g').test(n.className);\r
6046                                                 };\r
6047 \r
6048                                                 each(DOM.select('textarea'), function(v) {\r
6049                                                         if (s.editor_deselector && hasClass(v, s.editor_deselector))\r
6050                                                                 return;\r
6051 \r
6052                                                         if (!s.editor_selector || hasClass(v, s.editor_selector)) {\r
6053                                                                 v.id = v.id || v.name;\r
6054 \r
6055                                                                 // Generate unique name if missing or already exists\r
6056                                                                 if (!v.id || t.get(v.id))\r
6057                                                                         v.id = DOM.uniqueId();\r
6058 \r
6059                                                                 new tinymce.Editor(v.id, s).render(1);\r
6060                                                         }\r
6061                                                 });\r
6062                                                 break;\r
6063                                 }\r
6064 \r
6065                                 // Call onInit when all editors are initialized\r
6066                                 if (s.oninit) {\r
6067                                         l = co = 0;\r
6068 \r
6069                                         each (t.editors, function(ed) {\r
6070                                                 co++;\r
6071 \r
6072                                                 if (!ed.initialized) {\r
6073                                                         // Wait for it\r
6074                                                         ed.onInit.add(function() {\r
6075                                                                 l++;\r
6076 \r
6077                                                                 // All done\r
6078                                                                 if (l == co)\r
6079                                                                         execCallback(s, 'oninit');\r
6080                                                         });\r
6081                                                 } else\r
6082                                                         l++;\r
6083 \r
6084                                                 // All done\r
6085                                                 if (l == co)\r
6086                                                         execCallback(s, 'oninit');                                      \r
6087                                         });\r
6088                                 }\r
6089                         });\r
6090                 },\r
6091 \r
6092                 get : function(id) {\r
6093                         return this.editors[id];\r
6094                 },\r
6095 \r
6096                 getInstanceById : function(id) {\r
6097                         return this.get(id);\r
6098                 },\r
6099 \r
6100                 add : function(e) {\r
6101                         this.editors[e.id] = e;\r
6102                         this._setActive(e);\r
6103 \r
6104                         return e;\r
6105                 },\r
6106 \r
6107                 remove : function(e) {\r
6108                         var t = this;\r
6109 \r
6110                         // Not in the collection\r
6111                         if (!t.editors[e.id])\r
6112                                 return null;\r
6113 \r
6114                         delete t.editors[e.id];\r
6115 \r
6116                         // Select another editor since the active one was removed\r
6117                         if (t.activeEditor == e) {\r
6118                                 each(t.editors, function(e) {\r
6119                                         t._setActive(e);\r
6120                                         return false; // Break\r
6121                                 });\r
6122                         }\r
6123 \r
6124                         e.destroy();\r
6125 \r
6126                         return e;\r
6127                 },\r
6128 \r
6129                 execCommand : function(c, u, v) {\r
6130                         var t = this, ed = t.get(v), w;\r
6131 \r
6132                         // Manager commands\r
6133                         switch (c) {\r
6134                                 case "mceFocus":\r
6135                                         ed.focus();\r
6136                                         return true;\r
6137 \r
6138                                 case "mceAddEditor":\r
6139                                 case "mceAddControl":\r
6140                                         new tinymce.Editor(v, t.settings).render();\r
6141                                         return true;\r
6142 \r
6143                                 case "mceAddFrameControl":\r
6144                                         w = v.window;\r
6145 \r
6146                                         // Add tinyMCE global instance and tinymce namespace to specified window\r
6147                                         w.tinyMCE = tinyMCE;\r
6148                                         w.tinymce = tinymce;\r
6149 \r
6150                                         tinymce.DOM.doc = w.document;\r
6151                                         tinymce.DOM.win = w;\r
6152 \r
6153                                         ed = new tinymce.Editor(v.element_id, v);\r
6154                                         ed.render();\r
6155 \r
6156                                         // Fix IE memory leaks\r
6157                                         if (tinymce.isIE) {\r
6158                                                 function clr() {\r
6159                                                         ed.destroy();\r
6160                                                         w.detachEvent('onunload', clr);\r
6161                                                         w = w.tinyMCE = w.tinymce = null; // IE leak\r
6162                                                 };\r
6163 \r
6164                                                 w.attachEvent('onunload', clr);\r
6165                                         }\r
6166 \r
6167                                         v.page_window = null;\r
6168 \r
6169                                         return true;\r
6170 \r
6171                                 case "mceRemoveEditor":\r
6172                                 case "mceRemoveControl":\r
6173                                         ed.remove();\r
6174                                         return true;\r
6175 \r
6176                                 case 'mceToggleEditor':\r
6177                                         if (!ed) {\r
6178                                                 t.execCommand('mceAddControl', 0, v);\r
6179                                                 return true;\r
6180                                         }\r
6181 \r
6182                                         if (ed.isHidden())\r
6183                                                 ed.show();\r
6184                                         else\r
6185                                                 ed.hide();\r
6186 \r
6187                                         return true;\r
6188                         }\r
6189 \r
6190                         // Run command on active editor\r
6191                         if (t.activeEditor)\r
6192                                 return t.activeEditor.execCommand(c, u, v);\r
6193 \r
6194                         return false;\r
6195                 },\r
6196 \r
6197                 execInstanceCommand : function(id, c, u, v) {\r
6198                         var ed = this.get(id);\r
6199 \r
6200                         if (ed)\r
6201                                 return ed.execCommand(c, u, v);\r
6202 \r
6203                         return false;\r
6204                 },\r
6205 \r
6206                 triggerSave : function() {\r
6207                         each(this.editors, function(e) {\r
6208                                 e.save();\r
6209                         });\r
6210                 },\r
6211 \r
6212                 addI18n : function(p, o) {\r
6213                         var lo, i18n = this.i18n;\r
6214 \r
6215                         if (!tinymce.is(p, 'string')) {\r
6216                                 each(p, function(o, lc) {\r
6217                                         each(o, function(o, g) {\r
6218                                                 each(o, function(o, k) {\r
6219                                                         if (g === 'common')\r
6220                                                                 i18n[lc + '.' + k] = o;\r
6221                                                         else\r
6222                                                                 i18n[lc + '.' + g + '.' + k] = o;\r
6223                                                 });\r
6224                                         });\r
6225                                 });\r
6226                         } else {\r
6227                                 each(o, function(o, k) {\r
6228                                         i18n[p + '.' + k] = o;\r
6229                                 });\r
6230                         }\r
6231                 },\r
6232 \r
6233                 // Private methods\r
6234 \r
6235                 _setActive : function(e) {\r
6236                         this.selectedInstance = this.activeEditor = e;\r
6237                 }\r
6238 \r
6239                 });\r
6240 \r
6241         tinymce.EditorManager.preInit();\r
6242 })();\r
6243 \r
6244 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call\r
6245 var tinyMCE = window.tinyMCE = tinymce.EditorManager;\r
6246 \r
6247 /* file:jscripts/tiny_mce/classes/Editor.js */\r
6248 \r
6249 (function() {\r
6250         var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;\r
6251         var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;\r
6252         var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;\r
6253         var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;\r
6254 \r
6255         tinymce.create('tinymce.Editor', {\r
6256                 Editor : function(id, s) {\r
6257                         var t = this;\r
6258 \r
6259                         t.id = t.editorId = id;\r
6260                         t.execCommands = {};\r
6261                         t.queryStateCommands = {};\r
6262                         t.queryValueCommands = {};\r
6263                         t.plugins = {};\r
6264 \r
6265                         // Add events to the editor\r
6266                         each([\r
6267                                 'onPreInit',\r
6268                                 'onBeforeRenderUI',\r
6269                                 'onPostRender',\r
6270                                 'onInit',\r
6271                                 'onRemove',\r
6272                                 'onActivate',\r
6273                                 'onDeactivate',\r
6274                                 'onClick',\r
6275                                 'onEvent',\r
6276                                 'onMouseUp',\r
6277                                 'onMouseDown',\r
6278                                 'onDblClick',\r
6279                                 'onKeyDown',\r
6280                                 'onKeyUp',\r
6281                                 'onKeyPress',\r
6282                                 'onContextMenu',\r
6283                                 'onSubmit',\r
6284                                 'onReset',\r
6285                                 'onPaste',\r
6286                                 'onPreProcess',\r
6287                                 'onPostProcess',\r
6288                                 'onBeforeSetContent',\r
6289                                 'onBeforeGetContent',\r
6290                                 'onSetContent',\r
6291                                 'onGetContent',\r
6292                                 'onLoadContent',\r
6293                                 'onSaveContent',\r
6294                                 'onNodeChange',\r
6295                                 'onChange',\r
6296                                 'onBeforeExecCommand',\r
6297                                 'onExecCommand',\r
6298                                 'onUndo',\r
6299                                 'onRedo',\r
6300                                 'onVisualAid',\r
6301                                 'onSetProgressState'\r
6302                         ], function(e) {\r
6303                                 t[e] = new Dispatcher(t);\r
6304                         });\r
6305 \r
6306                         // Default editor config\r
6307                         t.settings = s = extend({\r
6308                                 id : id,\r
6309                                 language : 'en',\r
6310                                 docs_language : 'en',\r
6311                                 theme : 'simple',\r
6312                                 skin : 'default',\r
6313                                 delta_width : 0,\r
6314                                 delta_height : 0,\r
6315                                 popup_css : '',\r
6316                                 plugins : '',\r
6317                                 document_base_url : tinymce.documentBaseURL,\r
6318                                 add_form_submit_trigger : 1,\r
6319                                 submit_patch : 1,\r
6320                                 add_unload_trigger : 1,\r
6321                                 convert_urls : 1,\r
6322                                 relative_urls : 1,\r
6323                                 remove_script_host : 1,\r
6324                                 table_inline_editing : 0,\r
6325                                 object_resizing : 1,\r
6326                                 cleanup : 1,\r
6327                                 accessibility_focus : 1,\r
6328                                 custom_shortcuts : 1,\r
6329                                 custom_undo_redo_keyboard_shortcuts : 1,\r
6330                                 custom_undo_redo_restore_selection : 1,\r
6331                                 custom_undo_redo : 1,\r
6332                                 doctype : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',\r
6333                                 visual_table_class : 'mceItemTable',\r
6334                                 visual : 1,\r
6335                                 inline_styles : true,\r
6336                                 convert_fonts_to_spans : true,\r
6337                                 font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',\r
6338                                 apply_source_formatting : 1,\r
6339                                 directionality : 'ltr',\r
6340                                 forced_root_block : 'p',\r
6341                                 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,-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|_value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',\r
6342                                 hidden_input : 1,\r
6343                                 padd_empty_editor : 1,\r
6344                                 render_ui : 1,\r
6345                                 init_theme : 1,\r
6346                                 force_p_newlines : 1,\r
6347                                 indentation : '30px'\r
6348                         }, s);\r
6349 \r
6350                         // Setup URIs\r
6351                         t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {\r
6352                                 base_uri : tinyMCE.baseURI\r
6353                         });\r
6354                         t.baseURI = EditorManager.baseURI;\r
6355 \r
6356                         // Call setup\r
6357                         t.execCallback('setup', t);\r
6358                 },\r
6359 \r
6360                 render : function(nst) {\r
6361                         var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;\r
6362 \r
6363                         // Page is not loaded yet, wait for it\r
6364                         if (!Event.domLoaded) {\r
6365                                 Event.add(document, 'init', function() {\r
6366                                         t.render();\r
6367                                 });\r
6368                                 return;\r
6369                         }\r
6370 \r
6371                         // Force strict loading mode if render us called by user and not internally\r
6372                         if (!nst) {\r
6373                                 s.strict_loading_mode = 1;\r
6374                                 tinyMCE.settings = s;\r
6375                         }\r
6376 \r
6377                         // Element not found, then skip initialization\r
6378                         if (!t.getElement())\r
6379                                 return;\r
6380 \r
6381                         if (s.strict_loading_mode) {\r
6382                                 sl.settings.strict_mode = s.strict_loading_mode;\r
6383                                 tinymce.DOM.settings.strict = 1;\r
6384                         }\r
6385 \r
6386                         // Add hidden input for non input elements inside form elements\r
6387                         if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))\r
6388                                 DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);\r
6389 \r
6390                         t.windowManager = new tinymce.WindowManager(t);\r
6391 \r
6392                         if (s.encoding == 'xml') {\r
6393                                 t.onGetContent.add(function(ed, o) {\r
6394                                         if (o.get)\r
6395                                                 o.content = DOM.encode(o.content);\r
6396                                 });\r
6397                         }\r
6398 \r
6399                         if (s.add_form_submit_trigger) {\r
6400                                 t.onSubmit.addToTop(function() {\r
6401                                         if (t.initialized) {\r
6402                                                 t.save();\r
6403                                                 t.isNotDirty = 1;\r
6404                                         }\r
6405                                 });\r
6406                         }\r
6407 \r
6408                         if (s.add_unload_trigger) {\r
6409                                 t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {\r
6410                                         if (t.initialized && !t.destroyed)\r
6411                                                 t.save({format : 'raw', no_events : true});\r
6412                                 });\r
6413                         }\r
6414 \r
6415                         tinymce.addUnload(t.destroy, t);\r
6416 \r
6417                         if (s.submit_patch) {\r
6418                                 t.onBeforeRenderUI.add(function() {\r
6419                                         var n = t.getElement().form;\r
6420 \r
6421                                         if (!n)\r
6422                                                 return;\r
6423 \r
6424                                         // Already patched\r
6425                                         if (n._mceOldSubmit)\r
6426                                                 return;\r
6427 \r
6428                                         // Check page uses id="submit" or name="submit" for it's submit button\r
6429                                         if (!n.submit.nodeType && !n.submit.length) {\r
6430                                                 t.formElement = n;\r
6431                                                 n._mceOldSubmit = n.submit;\r
6432                                                 n.submit = function() {\r
6433                                                         // Save all instances\r
6434                                                         EditorManager.triggerSave();\r
6435                                                         t.isNotDirty = 1;\r
6436 \r
6437                                                         return this._mceOldSubmit(this);\r
6438                                                 };\r
6439                                         }\r
6440 \r
6441                                         n = null;\r
6442                                 });\r
6443                         }\r
6444 \r
6445                         // Load scripts\r
6446                         function loadScripts() {\r
6447                                 if (s.language)\r
6448                                         sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
6449 \r
6450                                 if (s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
6451                                         ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
6452 \r
6453                                 each(explode(s.plugins), function(p) {\r
6454                                         if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) {\r
6455                                                 // Skip safari plugin for other browsers\r
6456                                                 if (!isWebKit && p == 'safari')\r
6457                                                         return;\r
6458 \r
6459                                                 PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js');\r
6460                                         }\r
6461                                 });\r
6462 \r
6463                                 // Init when que is loaded\r
6464                                 sl.loadQueue(function() {\r
6465                                         if (s.ask) {\r
6466                                                 function ask() {\r
6467                                                         t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {\r
6468                                                                 if (s)\r
6469                                                                         t.init();\r
6470                                                                 else\r
6471                                                                         Event.remove(t.id, 'focus', ask);\r
6472                                                         });\r
6473                                                 };\r
6474 \r
6475                                                 Event.add(t.id, 'focus', ask);\r
6476                                                 return;\r
6477                                         }\r
6478 \r
6479                                         if (!t.removed)\r
6480                                                 t.init();\r
6481                                 });\r
6482                         };\r
6483 \r
6484                         // Load compat2x first\r
6485                         if (s.plugins.indexOf('compat2x') != -1) {\r
6486                                 PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');\r
6487                                 sl.loadQueue(loadScripts);\r
6488                         } else\r
6489                                 loadScripts();\r
6490                 },\r
6491 \r
6492                 init : function() {\r
6493                         var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;\r
6494 \r
6495                         EditorManager.add(t);\r
6496 \r
6497                         // Create theme\r
6498                         s.theme = s.theme.replace(/-/, '');\r
6499                         o = ThemeManager.get(s.theme);\r
6500                         t.theme = new o();\r
6501 \r
6502                         if (t.theme.init && s.init_theme)\r
6503                                 t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));\r
6504 \r
6505                         // Create all plugins\r
6506                         each(explode(s.plugins.replace(/\-/g, '')), function(p) {\r
6507                                 var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;\r
6508 \r
6509                                 if (c) {\r
6510                                         po = new c(t, u);\r
6511 \r
6512                                         t.plugins[p] = po;\r
6513 \r
6514                                         if (po.init)\r
6515                                                 po.init(t, u);\r
6516                                 }\r
6517                         });\r
6518 \r
6519                         // Setup popup CSS path(s)\r
6520                         if (s.popup_css)\r
6521                                 s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);\r
6522                         else\r
6523                                 s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");\r
6524 \r
6525                         if (s.popup_css_add)\r
6526                                 s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);\r
6527 \r
6528                         // Setup control factory\r
6529                         t.controlManager = new tinymce.ControlManager(t);\r
6530                         t.undoManager = new tinymce.UndoManager(t);\r
6531 \r
6532                         // Pass through\r
6533                         t.undoManager.onAdd.add(function(um, l) {\r
6534                                 return t.onChange.dispatch(t, l, um);\r
6535                         });\r
6536 \r
6537                         t.undoManager.onUndo.add(function(um, l) {\r
6538                                 return t.onUndo.dispatch(t, l, um);\r
6539                         });\r
6540 \r
6541                         t.undoManager.onRedo.add(function(um, l) {\r
6542                                 return t.onRedo.dispatch(t, l, um);\r
6543                         });\r
6544 \r
6545                         if (s.custom_undo_redo) {\r
6546                                 t.onExecCommand.add(function(ed, cmd, ui, val, a) {\r
6547                                         if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))\r
6548                                                 t.undoManager.add();\r
6549                                 });\r
6550                         }\r
6551 \r
6552                         t.onExecCommand.add(function(ed, c) {\r
6553                                 // Don't refresh the select lists until caret move\r
6554                                 if (!/^(FontName|FontSize)$/.test(c))\r
6555                                         t.nodeChanged();\r
6556                         });\r
6557 \r
6558                         // Remove ghost selections on images and tables in Gecko\r
6559                         if (isGecko) {\r
6560                                 function repaint(a, o) {\r
6561                                         if (!o || !o.initial)\r
6562                                                 t.execCommand('mceRepaint');\r
6563                                 };\r
6564 \r
6565                                 t.onUndo.add(repaint);\r
6566                                 t.onRedo.add(repaint);\r
6567                                 t.onSetContent.add(repaint);\r
6568                         }\r
6569 \r
6570                         // Enables users to override the control factory\r
6571                         t.onBeforeRenderUI.dispatch(t, t.controlManager);\r
6572 \r
6573                         // Measure box\r
6574                         if (s.render_ui) {\r
6575                                 w = s.width || e.style.width || e.clientWidth;\r
6576                                 h = s.height || e.style.height || e.clientHeight;\r
6577                                 t.orgDisplay = e.style.display;\r
6578                                 re = /^[0-9\.]+(|px)$/i;\r
6579 \r
6580                                 if (re.test('' + w))\r
6581                                         w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);\r
6582 \r
6583                                 if (re.test('' + h))\r
6584                                         h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);\r
6585 \r
6586                                 // Render UI\r
6587                                 o = t.theme.renderUI({\r
6588                                         targetNode : e,\r
6589                                         width : w,\r
6590                                         height : h,\r
6591                                         deltaWidth : s.delta_width,\r
6592                                         deltaHeight : s.delta_height\r
6593                                 });\r
6594 \r
6595                                 t.editorContainer = o.editorContainer;\r
6596                         }\r
6597 \r
6598                         \r
6599                         // Resize editor\r
6600                         DOM.setStyles(o.sizeContainer || o.editorContainer, {\r
6601                                 width : w,\r
6602                                 height : h\r
6603                         });\r
6604 \r
6605                         h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');\r
6606                         if (h < 100)\r
6607                                 h = 100;\r
6608 \r
6609                         t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '"></base>';\r
6610                         t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';\r
6611 \r
6612                         if (tinymce.relaxedDomain)\r
6613                                 t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';\r
6614 \r
6615                         bi = s.body_id || 'tinymce';\r
6616                         if (bi.indexOf('=') != -1) {\r
6617                                 bi = t.getParam('body_id', '', 'hash');\r
6618                                 bi = bi[t.id] || bi;\r
6619                         }\r
6620 \r
6621                         bc = s.body_class || '';\r
6622                         if (bc.indexOf('=') != -1) {\r
6623                                 bc = t.getParam('body_class', '', 'hash');\r
6624                                 bc = bc[t.id] || '';\r
6625                         }\r
6626 \r
6627                         t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';\r
6628 \r
6629                         // Domain relaxing enabled, then set document domain\r
6630                         if (tinymce.relaxedDomain) {\r
6631                                 // We need to write the contents here in IE since multiple writes messes up refresh button and back button\r
6632                                 if (isIE)\r
6633                                         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
6634                                 else if (tinymce.isOpera)\r
6635                                         u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';                                  \r
6636                         }\r
6637 \r
6638                         // Create iframe\r
6639                         n = DOM.add(o.iframeContainer, 'iframe', {\r
6640                                 id : t.id + "_ifr",\r
6641                                 src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7\r
6642                                 frameBorder : '0',\r
6643                                 style : {\r
6644                                         width : '100%',\r
6645                                         height : h\r
6646                                 }\r
6647                         });\r
6648 \r
6649                         t.contentAreaContainer = o.iframeContainer;\r
6650                         DOM.get(o.editorContainer).style.display = t.orgDisplay;\r
6651                         DOM.get(t.id).style.display = 'none';\r
6652 \r
6653                         // Safari 2.x requires us to wait for the load event and load a real HTML doc\r
6654                         if (tinymce.isOldWebKit) {\r
6655                                 Event.add(n, 'load', t.setupIframe, t);\r
6656                                 n.src = tinymce.baseURL + '/plugins/safari/blank.htm';\r
6657                         } else {\r
6658                                 if (!isIE || !tinymce.relaxedDomain)\r
6659                                         t.setupIframe();\r
6660 \r
6661                                 e = n = o = null; // Cleanup\r
6662                         }\r
6663                 },\r
6664 \r
6665                 setupIframe : function() {\r
6666                         var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;\r
6667 \r
6668                         // Setup iframe body\r
6669                         if (!isIE || !tinymce.relaxedDomain) {\r
6670                                 d.open();\r
6671                                 d.write(t.iframeHTML);\r
6672                                 d.close();\r
6673                         }\r
6674 \r
6675                         // Design mode needs to be added here Ctrl+A will fail otherwise\r
6676                         if (!isIE) {\r
6677                                 try {\r
6678                                         d.designMode = 'On';\r
6679                                 } catch (ex) {\r
6680                                         // Will fail on Gecko if the editor is placed in an hidden container element\r
6681                                         // The design mode will be set ones the editor is focused\r
6682                                 }\r
6683                         }\r
6684 \r
6685                         // IE needs to use contentEditable or it will display non secure items for HTTPS\r
6686                         if (isIE) {\r
6687                                 // It will not steal focus if we hide it while setting contentEditable\r
6688                                 b = t.getBody();\r
6689                                 DOM.hide(b);\r
6690                                 b.contentEditable = true;\r
6691                                 DOM.show(b);\r
6692                         }\r
6693 \r
6694                         // Setup objects\r
6695                         t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {\r
6696                                 keep_values : true,\r
6697                                 url_converter : t.convertURL,\r
6698                                 url_converter_scope : t,\r
6699                                 hex_colors : s.force_hex_style_colors,\r
6700                                 class_filter : s.class_filter,\r
6701                                 update_styles : 1,\r
6702                                 fix_ie_paragraphs : 1\r
6703                         });\r
6704 \r
6705                         t.serializer = new tinymce.dom.Serializer({\r
6706                                 entity_encoding : s.entity_encoding,\r
6707                                 entities : s.entities,\r
6708                                 valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,\r
6709                                 extended_valid_elements : s.extended_valid_elements,\r
6710                                 valid_child_elements : s.valid_child_elements,\r
6711                                 invalid_elements : s.invalid_elements,\r
6712                                 fix_table_elements : s.fix_table_elements,\r
6713                                 fix_list_elements : s.fix_list_elements,\r
6714                                 fix_content_duplication : s.fix_content_duplication,\r
6715                                 convert_fonts_to_spans : s.convert_fonts_to_spans,\r
6716                                 font_size_classes  : s.font_size_classes,\r
6717                                 font_size_style_values : s.font_size_style_values,\r
6718                                 apply_source_formatting : s.apply_source_formatting,\r
6719                                 remove_linebreaks : s.remove_linebreaks,\r
6720                                 dom : t.dom\r
6721                         });\r
6722 \r
6723                         t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);\r
6724                         t.forceBlocks = new tinymce.ForceBlocks(t, {\r
6725                                 forced_root_block : s.forced_root_block\r
6726                         });\r
6727                         t.editorCommands = new tinymce.EditorCommands(t);\r
6728 \r
6729                         // Pass through\r
6730                         t.serializer.onPreProcess.add(function(se, o) {\r
6731                                 return t.onPreProcess.dispatch(t, o, se);\r
6732                         });\r
6733 \r
6734                         t.serializer.onPostProcess.add(function(se, o) {\r
6735                                 return t.onPostProcess.dispatch(t, o, se);\r
6736                         });\r
6737 \r
6738                         t.onPreInit.dispatch(t);\r
6739 \r
6740                         if (!s.gecko_spellcheck)\r
6741                                 t.getBody().spellcheck = 0;\r
6742 \r
6743                         t._addEvents();\r
6744 \r
6745                         t.controlManager.onPostRender.dispatch(t, t.controlManager);\r
6746                         t.onPostRender.dispatch(t);\r
6747 \r
6748                         if (s.directionality)\r
6749                                 t.getBody().dir = s.directionality;\r
6750 \r
6751                         if (s.nowrap)\r
6752                                 t.getBody().style.whiteSpace = "nowrap";\r
6753 \r
6754                         if (s.auto_resize)\r
6755                                 t.onNodeChange.add(t.resizeToContent, t);\r
6756 \r
6757                         if (s.custom_elements) {\r
6758                                 function handleCustom(ed, o) {\r
6759                                         each(explode(s.custom_elements), function(v) {\r
6760                                                 var n;\r
6761 \r
6762                                                 if (v.indexOf('~') === 0) {\r
6763                                                         v = v.substring(1);\r
6764                                                         n = 'span';\r
6765                                                 } else\r
6766                                                         n = 'div';\r
6767 \r
6768                                                 o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' mce_name="$1"$2>');\r
6769                                                 o.content = o.content.replace(new RegExp('</(' + v + ')>', 'g'), '</' + n + '>');\r
6770                                         });\r
6771                                 };\r
6772 \r
6773                                 t.onBeforeSetContent.add(handleCustom);\r
6774                                 t.onPostProcess.add(function(ed, o) {\r
6775                                         if (o.set)\r
6776                                                 handleCustom(ed, o)\r
6777                                 });\r
6778                         }\r
6779 \r
6780                         if (s.handle_node_change_callback) {\r
6781                                 t.onNodeChange.add(function(ed, cm, n) {\r
6782                                         t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());\r
6783                                 });\r
6784                         }\r
6785 \r
6786                         if (s.save_callback) {\r
6787                                 t.onSaveContent.add(function(ed, o) {\r
6788                                         var h = t.execCallback('save_callback', t.id, o.content, t.getBody());\r
6789 \r
6790                                         if (h)\r
6791                                                 o.content = h;\r
6792                                 });\r
6793                         }\r
6794 \r
6795                         if (s.onchange_callback) {\r
6796                                 t.onChange.add(function(ed, l) {\r
6797                                         t.execCallback('onchange_callback', t, l);\r
6798                                 });\r
6799                         }\r
6800 \r
6801                         if (s.convert_newlines_to_brs) {\r
6802                                 t.onBeforeSetContent.add(function(ed, o) {\r
6803                                         if (o.initial)\r
6804                                                 o.content = o.content.replace(/\r?\n/g, '<br />');\r
6805                                 });\r
6806                         }\r
6807 \r
6808                         if (s.fix_nesting && isIE) {\r
6809                                 t.onBeforeSetContent.add(function(ed, o) {\r
6810                                         o.content = t._fixNesting(o.content);\r
6811                                 });\r
6812                         }\r
6813 \r
6814                         if (s.preformatted) {\r
6815                                 t.onPostProcess.add(function(ed, o) {\r
6816                                         o.content = o.content.replace(/^\s*<pre.*?>/, '');\r
6817                                         o.content = o.content.replace(/<\/pre>\s*$/, '');\r
6818 \r
6819                                         if (o.set)\r
6820                                                 o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';\r
6821                                 });\r
6822                         }\r
6823 \r
6824                         if (s.verify_css_classes) {\r
6825                                 t.serializer.attribValueFilter = function(n, v) {\r
6826                                         var s, cl;\r
6827 \r
6828                                         if (n == 'class') {\r
6829                                                 // Build regexp for classes\r
6830                                                 if (!t.classesRE) {\r
6831                                                         cl = t.dom.getClasses();\r
6832 \r
6833                                                         if (cl.length > 0) {\r
6834                                                                 s = '';\r
6835 \r
6836                                                                 each (cl, function(o) {\r
6837                                                                         s += (s ? '|' : '') + o['class'];\r
6838                                                                 });\r
6839 \r
6840                                                                 t.classesRE = new RegExp('(' + s + ')', 'gi');\r
6841                                                         }\r
6842                                                 }\r
6843 \r
6844                                                 return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';\r
6845                                         }\r
6846 \r
6847                                         return v;\r
6848                                 };\r
6849                         }\r
6850 \r
6851                         if (s.convert_fonts_to_spans)\r
6852                                 t._convertFonts();\r
6853 \r
6854                         if (s.inline_styles)\r
6855                                 t._convertInlineElements();\r
6856 \r
6857                         if (s.cleanup_callback) {\r
6858                                 t.onBeforeSetContent.add(function(ed, o) {\r
6859                                         o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);\r
6860                                 });\r
6861 \r
6862                                 t.onPreProcess.add(function(ed, o) {\r
6863                                         if (o.set)\r
6864                                                 t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);\r
6865 \r
6866                                         if (o.get)\r
6867                                                 t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);\r
6868                                 });\r
6869 \r
6870                                 t.onPostProcess.add(function(ed, o) {\r
6871                                         if (o.set)\r
6872                                                 o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);\r
6873 \r
6874                                         if (o.get)                                              \r
6875                                                 o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);\r
6876                                 });\r
6877                         }\r
6878 \r
6879                         if (s.save_callback) {\r
6880                                 t.onGetContent.add(function(ed, o) {\r
6881                                         if (o.save)\r
6882                                                 o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());\r
6883                                 });\r
6884                         }\r
6885 \r
6886                         if (s.handle_event_callback) {\r
6887                                 t.onEvent.add(function(ed, e, o) {\r
6888                                         if (t.execCallback('handle_event_callback', e, ed, o) === false)\r
6889                                                 Event.cancel(e);\r
6890                                 });\r
6891                         }\r
6892 \r
6893                         t.onSetContent.add(function() {\r
6894                                 // Safari needs some time, it will crash the browser when a link is created otherwise\r
6895                                 // I think this crash issue is resolved in the latest 3.0.4\r
6896                                 //window.setTimeout(function() {\r
6897                                         t.addVisual(t.getBody());\r
6898                                 //}, 1);\r
6899                         });\r
6900 \r
6901                         // Remove empty contents\r
6902                         if (s.padd_empty_editor) {\r
6903                                 t.onPostProcess.add(function(ed, o) {\r
6904                                         o.content = o.content.replace(/^<p>(&nbsp;|#160;|\s|\u00a0)<\/p>$/, '');\r
6905                                 });\r
6906                         }\r
6907 \r
6908                         if (isGecko) {\r
6909                                 try {\r
6910                                         // Design mode must be set here once again to fix a bug where\r
6911                                         // Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again\r
6912                                         d.designMode = 'Off';\r
6913                                         d.designMode = 'On';\r
6914                                 } catch (ex) {\r
6915                                         // Will fail on Gecko if the editor is placed in an hidden container element\r
6916                                         // The design mode will be set ones the editor is focused\r
6917                                 }\r
6918                         }\r
6919 \r
6920                         // A small timeout was needed since firefox will remove. Bug: #1838304\r
6921                         setTimeout(function () {\r
6922                                 if (t.removed)\r
6923                                         return;\r
6924 \r
6925                                 t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});\r
6926                                 t.startContent = t.getContent({format : 'raw'});\r
6927                                 t.undoManager.add({initial : true});\r
6928                                 t.initialized = true;\r
6929 \r
6930                                 t.onInit.dispatch(t);\r
6931                                 t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());\r
6932                                 t.execCallback('init_instance_callback', t);\r
6933                                 t.focus(true);\r
6934                                 t.nodeChanged({initial : 1});\r
6935 \r
6936                                 // Load specified content CSS last\r
6937                                 if (s.content_css) {\r
6938                                         tinymce.each(explode(s.content_css), function(u) {\r
6939                                                 t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));\r
6940                                         });\r
6941                                 }\r
6942 \r
6943                                 // Handle auto focus\r
6944                                 if (s.auto_focus) {\r
6945                                         setTimeout(function () {\r
6946                                                 var ed = EditorManager.get(s.auto_focus);\r
6947 \r
6948                                                 ed.selection.select(ed.getBody(), 1);\r
6949                                                 ed.selection.collapse(1);\r
6950                                                 ed.getWin().focus();\r
6951                                         }, 100);\r
6952                                 }\r
6953                         }, 1);\r
6954         \r
6955                         e = null;\r
6956                 },\r
6957 \r
6958                 \r
6959                 focus : function(sf) {\r
6960                         var oed, t = this;\r
6961 \r
6962                         if (!sf) {\r
6963                                 t.getWin().focus();\r
6964 \r
6965                                                         }\r
6966 \r
6967                         if (EditorManager.activeEditor != t) {\r
6968                                 if ((oed = EditorManager.activeEditor) != null)\r
6969                                         oed.onDeactivate.dispatch(oed, t);\r
6970 \r
6971                                 t.onActivate.dispatch(t, oed);\r
6972                         }\r
6973 \r
6974                         EditorManager._setActive(t);\r
6975                 },\r
6976 \r
6977                 execCallback : function(n) {\r
6978                         var t = this, f = t.settings[n], s;\r
6979 \r
6980                         if (!f)\r
6981                                 return;\r
6982 \r
6983                         // Look through lookup\r
6984                         if (t.callbackLookup && (s = t.callbackLookup[n])) {\r
6985                                 f = s.func;\r
6986                                 s = s.scope;\r
6987                         }\r
6988 \r
6989                         if (is(f, 'string')) {\r
6990                                 s = f.replace(/\.\w+$/, '');\r
6991                                 s = s ? tinymce.resolve(s) : 0;\r
6992                                 f = tinymce.resolve(f);\r
6993                                 t.callbackLookup = t.callbackLookup || {};\r
6994                                 t.callbackLookup[n] = {func : f, scope : s};\r
6995                         }\r
6996 \r
6997                         return f.apply(s || t, Array.prototype.slice.call(arguments, 1));\r
6998                 },\r
6999 \r
7000                 translate : function(s) {\r
7001                         var c = this.settings.language, i18n = EditorManager.i18n;\r
7002 \r
7003                         if (!s)\r
7004                                 return '';\r
7005 \r
7006                         return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {\r
7007                                 return i18n[c + '.' + b] || '{#' + b + '}';\r
7008                         });\r
7009                 },\r
7010 \r
7011                 getLang : function(n, dv) {\r
7012                         return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');\r
7013                 },\r
7014 \r
7015                 getParam : function(n, dv, ty) {\r
7016                         var tr = tinymce.trim, v = is(this.settings[n]) ? this.settings[n] : dv, o;\r
7017 \r
7018                         if (ty === 'hash') {\r
7019                                 o = {};\r
7020 \r
7021                                 if (is(v, 'string')) {\r
7022                                         each(v.indexOf('=') > 0 ? v.split(/[;,](?![^=;,]*(?:[;,]|$))/) : v.split(','), function(v) {\r
7023                                                 v = v.split('=');\r
7024 \r
7025                                                 if (v.length > 1)\r
7026                                                         o[tr(v[0])] = tr(v[1]);\r
7027                                                 else\r
7028                                                         o[tr(v[0])] = tr(v);\r
7029                                         });\r
7030                                 } else\r
7031                                         o = v;\r
7032 \r
7033                                 return o;\r
7034                         }\r
7035 \r
7036                         return v;\r
7037                 },\r
7038 \r
7039                 nodeChanged : function(o) {\r
7040                         var t = this, s = t.selection, n = s.getNode() || t.getBody();\r
7041 \r
7042                         // Fix for bug #1896577 it seems that this can not be fired while the editor is loading\r
7043                         if (t.initialized) {\r
7044                                 t.onNodeChange.dispatch(\r
7045                                         t,\r
7046                                         o ? o.controlManager || t.controlManager : t.controlManager,\r
7047                                         isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n, // Fix for IE initial state\r
7048                                         s.isCollapsed(),\r
7049                                         o\r
7050                                 );\r
7051                         }\r
7052                 },\r
7053 \r
7054                 addButton : function(n, s) {\r
7055                         var t = this;\r
7056 \r
7057                         t.buttons = t.buttons || {};\r
7058                         t.buttons[n] = s;\r
7059                 },\r
7060 \r
7061                 addCommand : function(n, f, s) {\r
7062                         this.execCommands[n] = {func : f, scope : s || this};\r
7063                 },\r
7064 \r
7065                 addQueryStateHandler : function(n, f, s) {\r
7066                         this.queryStateCommands[n] = {func : f, scope : s || this};\r
7067                 },\r
7068 \r
7069                 addQueryValueHandler : function(n, f, s) {\r
7070                         this.queryValueCommands[n] = {func : f, scope : s || this};\r
7071                 },\r
7072 \r
7073                 addShortcut : function(pa, desc, cmd_func, sc) {\r
7074                         var t = this, c;\r
7075 \r
7076                         if (!t.settings.custom_shortcuts)\r
7077                                 return false;\r
7078 \r
7079                         t.shortcuts = t.shortcuts || {};\r
7080 \r
7081                         if (is(cmd_func, 'string')) {\r
7082                                 c = cmd_func;\r
7083 \r
7084                                 cmd_func = function() {\r
7085                                         t.execCommand(c, false, null);\r
7086                                 };\r
7087                         }\r
7088 \r
7089                         if (is(cmd_func, 'object')) {\r
7090                                 c = cmd_func;\r
7091 \r
7092                                 cmd_func = function() {\r
7093                                         t.execCommand(c[0], c[1], c[2]);\r
7094                                 };\r
7095                         }\r
7096 \r
7097                         each(explode(pa), function(pa) {\r
7098                                 var o = {\r
7099                                         func : cmd_func,\r
7100                                         scope : sc || this,\r
7101                                         desc : desc,\r
7102                                         alt : false,\r
7103                                         ctrl : false,\r
7104                                         shift : false\r
7105                                 };\r
7106 \r
7107                                 each(explode(pa, '+'), function(v) {\r
7108                                         switch (v) {\r
7109                                                 case 'alt':\r
7110                                                 case 'ctrl':\r
7111                                                 case 'shift':\r
7112                                                         o[v] = true;\r
7113                                                         break;\r
7114 \r
7115                                                 default:\r
7116                                                         o.charCode = v.charCodeAt(0);\r
7117                                                         o.keyCode = v.toUpperCase().charCodeAt(0);\r
7118                                         }\r
7119                                 });\r
7120 \r
7121                                 t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o;\r
7122                         });\r
7123 \r
7124                         return true;\r
7125                 },\r
7126 \r
7127                 execCommand : function(cmd, ui, val, a) {\r
7128                         var t = this, s = 0, o;\r
7129 \r
7130                         if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus))\r
7131                                 t.focus();\r
7132 \r
7133                         o = {};\r
7134                         t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o);\r
7135                         if (o.terminate)\r
7136                                 return false;\r
7137 \r
7138                         // Comamnd callback\r
7139                         if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) {\r
7140                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7141                                 return true;\r
7142                         }\r
7143 \r
7144                         // Registred commands\r
7145                         if (o = t.execCommands[cmd]) {\r
7146                                 s = o.func.call(o.scope, ui, val);\r
7147                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7148                                 return s;\r
7149                         }\r
7150 \r
7151                         // Plugin commands\r
7152                         each(t.plugins, function(p) {\r
7153                                 if (p.execCommand && p.execCommand(cmd, ui, val)) {\r
7154                                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7155                                         s = 1;\r
7156                                         return false;\r
7157                                 }\r
7158                         });\r
7159 \r
7160                         if (s)\r
7161                                 return true;\r
7162 \r
7163                         // Theme commands\r
7164                         if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {\r
7165                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7166                                 return true;\r
7167                         }\r
7168 \r
7169                         // Editor commands\r
7170                         if (t.editorCommands.execCommand(cmd, ui, val)) {\r
7171                                 t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7172                                 return true;\r
7173                         }\r
7174 \r
7175                         // Browser commands\r
7176                         t.getDoc().execCommand(cmd, ui, val);\r
7177                         t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
7178                 },\r
7179 \r
7180                 queryCommandState : function(c) {\r
7181                         var t = this, o;\r
7182 \r
7183                         // Is hidden then return undefined\r
7184                         if (t._isHidden())\r
7185                                 return;\r
7186 \r
7187                         // Registred commands\r
7188                         if (o = t.queryStateCommands[c])\r
7189                                 return o.func.call(o.scope);\r
7190 \r
7191                         // Registred commands\r
7192                         o = t.editorCommands.queryCommandState(c);\r
7193                         if (o !== -1)\r
7194                                 return o;\r
7195 \r
7196                         // Browser commands\r
7197                         try {\r
7198                                 return this.getDoc().queryCommandState(c);\r
7199                         } catch (ex) {\r
7200                                 // Fails sometimes see bug: 1896577\r
7201                         }\r
7202                 },\r
7203 \r
7204                 queryCommandValue : function(c) {\r
7205                         var t = this, o;\r
7206 \r
7207                         // Is hidden then return undefined\r
7208                         if (t._isHidden())\r
7209                                 return;\r
7210 \r
7211                         // Registred commands\r
7212                         if (o = t.queryValueCommands[c])\r
7213                                 return o.func.call(o.scope);\r
7214 \r
7215                         // Registred commands\r
7216                         o = t.editorCommands.queryCommandValue(c);\r
7217                         if (is(o))\r
7218                                 return o;\r
7219 \r
7220                         // Browser commands\r
7221                         try {\r
7222                                 return this.getDoc().queryCommandValue(c);\r
7223                         } catch (ex) {\r
7224                                 // Fails sometimes see bug: 1896577\r
7225                         }\r
7226                 },\r
7227 \r
7228                 show : function() {\r
7229                         var t = this;\r
7230 \r
7231                         DOM.show(t.getContainer());\r
7232                         DOM.hide(t.id);\r
7233                         t.load();\r
7234                 },\r
7235 \r
7236                 hide : function() {\r
7237                         var t = this, d = t.getDoc();\r
7238 \r
7239                         // Fixed bug where IE has a blinking cursor left from the editor\r
7240                         if (isIE && d)\r
7241                                 d.execCommand('SelectAll');\r
7242 \r
7243                         // We must save before we hide so Safari doesn't crash\r
7244                         t.save();\r
7245                         DOM.hide(t.getContainer());\r
7246                         DOM.setStyle(t.id, 'display', t.orgDisplay);\r
7247                 },\r
7248 \r
7249                 isHidden : function() {\r
7250                         return !DOM.isHidden(this.id);\r
7251                 },\r
7252 \r
7253                 setProgressState : function(b, ti, o) {\r
7254                         this.onSetProgressState.dispatch(this, b, ti, o);\r
7255 \r
7256                         return b;\r
7257                 },\r
7258 \r
7259                 resizeToContent : function() {\r
7260                         var t = this;\r
7261 \r
7262                         DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight);\r
7263                 },\r
7264 \r
7265                 load : function(o) {\r
7266                         var t = this, e = t.getElement(), h;\r
7267 \r
7268                         o = o || {};\r
7269                         o.load = true;\r
7270 \r
7271                         h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);\r
7272                         o.element = e;\r
7273 \r
7274                         if (!o.no_events)\r
7275                                 t.onLoadContent.dispatch(t, o);\r
7276 \r
7277                         o.element = e = null;\r
7278 \r
7279                         return h;\r
7280                 },\r
7281 \r
7282                 save : function(o) {\r
7283                         var t = this, e = t.getElement(), h, f;\r
7284 \r
7285                         if (!t.initialized)\r
7286                                 return;\r
7287 \r
7288                         o = o || {};\r
7289                         o.save = true;\r
7290 \r
7291                         o.element = e;\r
7292                         h = o.content = t.getContent(o);\r
7293 \r
7294                         if (!o.no_events)\r
7295                                 t.onSaveContent.dispatch(t, o);\r
7296 \r
7297                         h = o.content;\r
7298 \r
7299                         if (!/TEXTAREA|INPUT/i.test(e.nodeName)) {\r
7300                                 e.innerHTML = h;\r
7301 \r
7302                                 // Update hidden form element\r
7303                                 if (f = DOM.getParent(t.id, 'form')) {\r
7304                                         each(f.elements, function(e) {\r
7305                                                 if (e.name == t.id) {\r
7306                                                         e.value = h;\r
7307                                                         return false;\r
7308                                                 }\r
7309                                         });\r
7310                                 }\r
7311                         } else\r
7312                                 e.value = h;\r
7313 \r
7314                         o.element = e = null;\r
7315 \r
7316                         return h;\r
7317                 },\r
7318 \r
7319                 setContent : function(h, o) {\r
7320                         var t = this;\r
7321 \r
7322                         o = o || {};\r
7323                         o.format = o.format || 'html';\r
7324                         o.set = true;\r
7325                         o.content = h;\r
7326 \r
7327                         if (!o.no_events)\r
7328                                 t.onBeforeSetContent.dispatch(t, o);\r
7329 \r
7330                         // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content\r
7331                         // It will also be impossible to place the caret in the editor unless there is a BR element present\r
7332                         if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {\r
7333                                 o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />', 1);\r
7334                                 o.format = 'raw';\r
7335                         }\r
7336 \r
7337                         o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content));\r
7338 \r
7339                         if (o.format != 'raw' && t.settings.cleanup) {\r
7340                                 o.getInner = true;\r
7341                                 o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));\r
7342                         }\r
7343 \r
7344                         if (!o.no_events)\r
7345                                 t.onSetContent.dispatch(t, o);\r
7346 \r
7347                         return o.content;\r
7348                 },\r
7349 \r
7350                 getContent : function(o) {\r
7351                         var t = this, h;\r
7352 \r
7353                         o = o || {};\r
7354                         o.format = o.format || 'html';\r
7355                         o.get = true;\r
7356 \r
7357                         if (!o.no_events)\r
7358                                 t.onBeforeGetContent.dispatch(t, o);\r
7359 \r
7360                         if (o.format != 'raw' && t.settings.cleanup) {\r
7361                                 o.getInner = true;\r
7362                                 h = t.serializer.serialize(t.getBody(), o);\r
7363                         } else\r
7364                                 h = t.getBody().innerHTML;\r
7365 \r
7366                         h = h.replace(/^\s*|\s*$/g, '');\r
7367                         o = {content : h};\r
7368                         t.onGetContent.dispatch(t, o);\r
7369 \r
7370                         return o.content;\r
7371                 },\r
7372 \r
7373                 isDirty : function() {\r
7374                         var t = this;\r
7375 \r
7376                         return tinymce.trim(t.startContent) != tinymce.trim(t.getContent({format : 'raw', no_events : 1})) && !t.isNotDirty;\r
7377                 },\r
7378 \r
7379                 getContainer : function() {\r
7380                         var t = this;\r
7381 \r
7382                         if (!t.container)\r
7383                                 t.container = DOM.get(t.editorContainer || t.id + '_parent');\r
7384 \r
7385                         return t.container;\r
7386                 },\r
7387 \r
7388                 getContentAreaContainer : function() {\r
7389                         return this.contentAreaContainer;\r
7390                 },\r
7391 \r
7392                 getElement : function() {\r
7393                         return DOM.get(this.settings.content_element || this.id);\r
7394                 },\r
7395 \r
7396                 getWin : function() {\r
7397                         var t = this, e;\r
7398 \r
7399                         if (!t.contentWindow) {\r
7400                                 e = DOM.get(t.id + "_ifr");\r
7401 \r
7402                                 if (e)\r
7403                                         t.contentWindow = e.contentWindow;\r
7404                         }\r
7405 \r
7406                         return t.contentWindow;\r
7407                 },\r
7408 \r
7409                 getDoc : function() {\r
7410                         var t = this, w;\r
7411 \r
7412                         if (!t.contentDocument) {\r
7413                                 w = t.getWin();\r
7414 \r
7415                                 if (w)\r
7416                                         t.contentDocument = w.document;\r
7417                         }\r
7418 \r
7419                         return t.contentDocument;\r
7420                 },\r
7421 \r
7422                 getBody : function() {\r
7423                         return this.bodyElement || this.getDoc().body;\r
7424                 },\r
7425 \r
7426                 convertURL : function(u, n, e) {\r
7427                         var t = this, s = t.settings;\r
7428 \r
7429                         // Use callback instead\r
7430                         if (s.urlconverter_callback)\r
7431                                 return t.execCallback('urlconverter_callback', u, e, true, n);\r
7432 \r
7433                         // Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs\r
7434                         if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0)\r
7435                                 return u;\r
7436 \r
7437                         // Convert to relative\r
7438                         if (s.relative_urls)\r
7439                                 return t.documentBaseURI.toRelative(u);\r
7440 \r
7441                         // Convert to absolute\r
7442                         u = t.documentBaseURI.toAbsolute(u, s.remove_script_host);\r
7443 \r
7444                         return u;\r
7445                 },\r
7446 \r
7447                 addVisual : function(e) {\r
7448                         var t = this, s = t.settings;\r
7449 \r
7450                         e = e || t.getBody();\r
7451 \r
7452                         if (!is(t.hasVisual))\r
7453                                 t.hasVisual = s.visual;\r
7454 \r
7455                         each(t.dom.select('table,a', e), function(e) {\r
7456                                 var v;\r
7457 \r
7458                                 switch (e.nodeName) {\r
7459                                         case 'TABLE':\r
7460                                                 v = t.dom.getAttrib(e, 'border');\r
7461 \r
7462                                                 if (!v || v == '0') {\r
7463                                                         if (t.hasVisual)\r
7464                                                                 t.dom.addClass(e, s.visual_table_class);\r
7465                                                         else\r
7466                                                                 t.dom.removeClass(e, s.visual_table_class);\r
7467                                                 }\r
7468 \r
7469                                                 return;\r
7470 \r
7471                                         case 'A':\r
7472                                                 v = t.dom.getAttrib(e, 'name');\r
7473 \r
7474                                                 if (v) {\r
7475                                                         if (t.hasVisual)\r
7476                                                                 t.dom.addClass(e, 'mceItemAnchor');\r
7477                                                         else\r
7478                                                                 t.dom.removeClass(e, 'mceItemAnchor');\r
7479                                                 }\r
7480 \r
7481                                                 return;\r
7482                                 }\r
7483                         });\r
7484 \r
7485                         t.onVisualAid.dispatch(t, e, t.hasVisual);\r
7486                 },\r
7487 \r
7488                 remove : function() {\r
7489                         var t = this, e = t.getContainer();\r
7490 \r
7491                         t.removed = 1; // Cancels post remove event execution\r
7492                         t.hide();\r
7493 \r
7494                         t.execCallback('remove_instance_callback', t);\r
7495                         t.onRemove.dispatch(t);\r
7496 \r
7497                         // Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command\r
7498                         t.onExecCommand.listeners = [];\r
7499 \r
7500                         EditorManager.remove(t);\r
7501                         DOM.remove(e);\r
7502                 },\r
7503 \r
7504                 destroy : function(s) {\r
7505                         var t = this;\r
7506 \r
7507                         // One time is enough\r
7508                         if (t.destroyed)\r
7509                                 return;\r
7510 \r
7511                         if (!s) {\r
7512                                 tinymce.removeUnload(t.destroy);\r
7513                                 tinyMCE.onBeforeUnload.remove(t._beforeUnload);\r
7514 \r
7515                                 // Manual destroy\r
7516                                 if (t.theme.destroy)\r
7517                                         t.theme.destroy();\r
7518 \r
7519                                 // Destroy controls, selection and dom\r
7520                                 t.controlManager.destroy();\r
7521                                 t.selection.destroy();\r
7522                                 t.dom.destroy();\r
7523 \r
7524                                 // Remove all events\r
7525                                 Event.clear(t.getWin());\r
7526                                 Event.clear(t.getDoc());\r
7527                                 Event.clear(t.getBody());\r
7528                                 Event.clear(t.formElement);\r
7529                         }\r
7530 \r
7531                         if (t.formElement) {\r
7532                                 t.formElement.submit = t.formElement._mceOldSubmit;\r
7533                                 t.formElement._mceOldSubmit = null;\r
7534                         }\r
7535 \r
7536                         t.contentAreaContainer = t.formElement = t.container = t.settings.content_element = t.bodyElement = t.contentDocument = t.contentWindow = null;\r
7537 \r
7538                         if (t.selection)\r
7539                                 t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null;\r
7540 \r
7541                         t.destroyed = 1;\r
7542                 },\r
7543 \r
7544                 // Internal functions\r
7545 \r
7546                 _addEvents : function() {\r
7547                         // 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset\r
7548                         var t = this, i, s = t.settings, lo = {\r
7549                                 mouseup : 'onMouseUp',\r
7550                                 mousedown : 'onMouseDown',\r
7551                                 click : 'onClick',\r
7552                                 keyup : 'onKeyUp',\r
7553                                 keydown : 'onKeyDown',\r
7554                                 keypress : 'onKeyPress',\r
7555                                 submit : 'onSubmit',\r
7556                                 reset : 'onReset',\r
7557                                 contextmenu : 'onContextMenu',\r
7558                                 dblclick : 'onDblClick',\r
7559                                 paste : 'onPaste' // Doesn't work in all browsers yet\r
7560                         };\r
7561 \r
7562                         function eventHandler(e, o) {\r
7563                                 var ty = e.type;\r
7564 \r
7565                                 // Don't fire events when it's removed\r
7566                                 if (t.removed)\r
7567                                         return;\r
7568 \r
7569                                 // Generic event handler\r
7570                                 if (t.onEvent.dispatch(t, e, o) !== false) {\r
7571                                         // Specific event handler\r
7572                                         t[lo[e.fakeType || e.type]].dispatch(t, e, o);\r
7573                                 }\r
7574                         };\r
7575 \r
7576                         // Add DOM events\r
7577                         each(lo, function(v, k) {\r
7578                                 switch (k) {\r
7579                                         case 'contextmenu':\r
7580                                                 if (tinymce.isOpera) {\r
7581                                                         // Fake contextmenu on Opera\r
7582                                                         Event.add(t.getDoc(), 'mousedown', function(e) {\r
7583                                                                 if (e.ctrlKey) {\r
7584                                                                         e.fakeType = 'contextmenu';\r
7585                                                                         eventHandler(e);\r
7586                                                                 }\r
7587                                                         });\r
7588                                                 } else\r
7589                                                         Event.add(t.getDoc(), k, eventHandler);\r
7590                                                 break;\r
7591 \r
7592                                         case 'paste':\r
7593                                                 Event.add(t.getBody(), k, function(e) {\r
7594                                                         var tx, h, el, r;\r
7595 \r
7596                                                         // Get plain text data\r
7597                                                         if (e.clipboardData)\r
7598                                                                 tx = e.clipboardData.getData('text/plain');\r
7599                                                         else if (tinymce.isIE)\r
7600                                                                 tx = t.getWin().clipboardData.getData('Text');\r
7601 \r
7602                                                         // Get HTML data\r
7603                                                         /*if (tinymce.isIE) {\r
7604                                                                 el = DOM.add(DOM.doc.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'});\r
7605                                                                 r = DOM.doc.body.createTextRange();\r
7606                                                                 r.moveToElementText(el);\r
7607                                                                 r.execCommand('Paste');\r
7608                                                                 h = el.innerHTML;\r
7609                                                                 DOM.remove(el);\r
7610                                                         }*/\r
7611 \r
7612                                                         eventHandler(e, {text : tx, html : h});\r
7613                                                 });\r
7614                                                 break;\r
7615 \r
7616                                         case 'submit':\r
7617                                         case 'reset':\r
7618                                                 Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);\r
7619                                                 break;\r
7620 \r
7621                                         default:\r
7622                                                 Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);\r
7623                                 }\r
7624                         });\r
7625 \r
7626                         Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {\r
7627                                 t.focus(true);\r
7628                         });\r
7629 \r
7630                         \r
7631                         // Fixes bug where a specified document_base_uri could result in broken images\r
7632                         // This will also fix drag drop of images in Gecko\r
7633                         if (tinymce.isGecko) {\r
7634                                 // Convert all images to absolute URLs\r
7635 /*                              t.onSetContent.add(function(ed, o) {\r
7636                                         each(ed.dom.select('img'), function(e) {\r
7637                                                 var v;\r
7638 \r
7639                                                 if (v = e.getAttribute('mce_src'))\r
7640                                                         e.src = t.documentBaseURI.toAbsolute(v);\r
7641                                         })\r
7642                                 });*/\r
7643 \r
7644                                 Event.add(t.getDoc(), 'DOMNodeInserted', function(e) {\r
7645                                         var v;\r
7646 \r
7647                                         e = e.target;\r
7648 \r
7649                                         if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src')))\r
7650                                                 e.src = t.documentBaseURI.toAbsolute(v);\r
7651                                 });\r
7652                         }\r
7653 \r
7654                         // Set various midas options in Gecko\r
7655                         if (isGecko) {\r
7656                                 function setOpts() {\r
7657                                         var t = this, d = t.getDoc(), s = t.settings;\r
7658 \r
7659                                         if (isGecko) {\r
7660                                                 if (t._isHidden()) {\r
7661                                                         try {\r
7662                                                                 if (!s.content_editable)\r
7663                                                                         d.designMode = 'On';\r
7664                                                         } catch (ex) {\r
7665                                                                 // Fails if it's hidden\r
7666                                                         }\r
7667                                                 }\r
7668 \r
7669                                                 try {\r
7670                                                         // Try new Gecko method\r
7671                                                         d.execCommand("styleWithCSS", 0, false);\r
7672                                                 } catch (ex) {\r
7673                                                         // Use old method\r
7674                                                         if (!t._isHidden())\r
7675                                                                 d.execCommand("useCSS", 0, true);\r
7676                                                 }\r
7677 \r
7678                                                 if (!s.table_inline_editing)\r
7679                                                         try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}\r
7680 \r
7681                                                 if (!s.object_resizing)\r
7682                                                         try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}\r
7683                                         }\r
7684                                 };\r
7685 \r
7686                                 t.onBeforeExecCommand.add(setOpts);\r
7687                                 t.onMouseDown.add(setOpts);\r
7688                         }\r
7689 \r
7690                         // Add node change handlers\r
7691                         t.onMouseUp.add(t.nodeChanged);\r
7692                         t.onClick.add(t.nodeChanged);\r
7693                         t.onKeyUp.add(function(ed, e) {\r
7694                                 if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.keyCode == 46 || e.keyCode == 8 || e.ctrlKey)\r
7695                                         t.nodeChanged();\r
7696                         });\r
7697 \r
7698                         // Add reset handler\r
7699                         t.onReset.add(function() {\r
7700                                 t.setContent(t.startContent, {format : 'raw'});\r
7701                         });\r
7702 \r
7703                         if (t.getParam('tab_focus')) {\r
7704                                 function tabCancel(ed, e) {\r
7705                                         if (e.keyCode === 9)\r
7706                                                 return Event.cancel(e);\r
7707                                 };\r
7708 \r
7709                                 function tabHandler(ed, e) {\r
7710                                         var x, i, f, el, v;\r
7711 \r
7712                                         function find(d) {\r
7713                                                 f = DOM.getParent(ed.id, 'form');\r
7714                                                 el = f.elements;\r
7715 \r
7716                                                 if (f) {\r
7717                                                         each(el, function(e, i) {\r
7718                                                                 if (e.id == ed.id) {\r
7719                                                                         x = i;\r
7720                                                                         return false;\r
7721                                                                 }\r
7722                                                         });\r
7723 \r
7724                                                         if (d > 0) {\r
7725                                                                 for (i = x + 1; i < el.length; i++) {\r
7726                                                                         if (el[i].type != 'hidden')\r
7727                                                                                 return el[i];\r
7728                                                                 }\r
7729                                                         } else {\r
7730                                                                 for (i = x - 1; i >= 0; i--) {\r
7731                                                                         if (el[i].type != 'hidden')\r
7732                                                                                 return el[i];\r
7733                                                                 }\r
7734                                                         }\r
7735                                                 }\r
7736 \r
7737                                                 return null;\r
7738                                         };\r
7739 \r
7740                                         if (e.keyCode === 9) {\r
7741                                                 v = explode(ed.getParam('tab_focus'));\r
7742 \r
7743                                                 if (v.length == 1) {\r
7744                                                         v[1] = v[0];\r
7745                                                         v[0] = ':prev';\r
7746                                                 }\r
7747 \r
7748                                                 // Find element to focus\r
7749                                                 if (e.shiftKey) {\r
7750                                                         if (v[0] == ':prev')\r
7751                                                                 el = find(-1);\r
7752                                                         else\r
7753                                                                 el = DOM.get(v[0]);\r
7754                                                 } else {\r
7755                                                         if (v[1] == ':next')\r
7756                                                                 el = find(1);\r
7757                                                         else\r
7758                                                                 el = DOM.get(v[1]);\r
7759                                                 }\r
7760 \r
7761                                                 if (el) {\r
7762                                                         if (ed = EditorManager.get(el.id || el.name))\r
7763                                                                 ed.focus();\r
7764                                                         else\r
7765                                                                 window.setTimeout(function() {window.focus();el.focus();}, 10);\r
7766 \r
7767                                                         return Event.cancel(e);\r
7768                                                 }\r
7769                                         }\r
7770                                 };\r
7771 \r
7772                                 t.onKeyUp.add(tabCancel);\r
7773 \r
7774                                 if (isGecko) {\r
7775                                         t.onKeyPress.add(tabHandler);\r
7776                                         t.onKeyDown.add(tabCancel);\r
7777                                 } else\r
7778                                         t.onKeyDown.add(tabHandler);\r
7779                         }\r
7780 \r
7781                         // Add shortcuts\r
7782                         if (s.custom_shortcuts) {\r
7783                                 if (s.custom_undo_redo_keyboard_shortcuts) {\r
7784                                         t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');\r
7785                                         t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');\r
7786                                 }\r
7787 \r
7788                                 // Add default shortcuts for gecko\r
7789                                 if (isGecko) {\r
7790                                         t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold');\r
7791                                         t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic');\r
7792                                         t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline');\r
7793                                 }\r
7794 \r
7795                                 // BlockFormat shortcuts keys\r
7796                                 for (i=1; i<=6; i++)\r
7797                                         t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, '<h' + i + '>']);\r
7798 \r
7799                                 t.addShortcut('ctrl+7', '', ['FormatBlock', false, '<p>']);\r
7800                                 t.addShortcut('ctrl+8', '', ['FormatBlock', false, '<div>']);\r
7801                                 t.addShortcut('ctrl+9', '', ['FormatBlock', false, '<address>']);\r
7802 \r
7803                                 function find(e) {\r
7804                                         var v = null;\r
7805 \r
7806                                         if (!e.altKey && !e.ctrlKey && !e.metaKey)\r
7807                                                 return v;\r
7808 \r
7809                                         each(t.shortcuts, function(o) {\r
7810                                                 if (o.ctrl != e.ctrlKey && (!tinymce.isMac || o.ctrl == e.metaKey))\r
7811                                                         return;\r
7812 \r
7813                                                 if (o.alt != e.altKey)\r
7814                                                         return;\r
7815 \r
7816                                                 if (o.shift != e.shiftKey)\r
7817                                                         return;\r
7818 \r
7819                                                 if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {\r
7820                                                         v = o;\r
7821                                                         return false;\r
7822                                                 }\r
7823                                         });\r
7824 \r
7825                                         return v;\r
7826                                 };\r
7827 \r
7828                                 t.onKeyUp.add(function(ed, e) {\r
7829                                         var o = find(e);\r
7830 \r
7831                                         if (o)\r
7832                                                 return Event.cancel(e);\r
7833                                 });\r
7834 \r
7835                                 t.onKeyPress.add(function(ed, e) {\r
7836                                         var o = find(e);\r
7837 \r
7838                                         if (o)\r
7839                                                 return Event.cancel(e);\r
7840                                 });\r
7841 \r
7842                                 t.onKeyDown.add(function(ed, e) {\r
7843                                         var o = find(e);\r
7844 \r
7845                                         if (o) {\r
7846                                                 o.func.call(o.scope);\r
7847                                                 return Event.cancel(e);\r
7848                                         }\r
7849                                 });\r
7850                         }\r
7851 \r
7852                         if (tinymce.isIE) {\r
7853                                 // Fix so resize will only update the width and height attributes not the styles of an image\r
7854                                 // It will also block mceItemNoResize items\r
7855                                 Event.add(t.getDoc(), 'controlselect', function(e) {\r
7856                                         var re = t.resizeInfo, cb;\r
7857 \r
7858                                         e = e.target;\r
7859                                         e.removeAttribute('mce_style'); // Remove this one since it might change\r
7860 \r
7861                                         // Don't do this action for non image elements\r
7862                                         if (e.nodeName !== 'IMG')\r
7863                                                 return;\r
7864 \r
7865                                         if (re)\r
7866                                                 Event.remove(re.node, re.ev, re.cb);\r
7867 \r
7868                                         if (!t.dom.hasClass(e, 'mceItemNoResize')) {\r
7869                                                 ev = 'resizeend';\r
7870                                                 cb = Event.add(e, ev, function(e) {\r
7871                                                         var v;\r
7872 \r
7873                                                         e = e.target;\r
7874 \r
7875                                                         if (v = t.dom.getStyle(e, 'width')) {\r
7876                                                                 t.dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));\r
7877                                                                 t.dom.setStyle(e, 'width', '');\r
7878                                                         }\r
7879 \r
7880                                                         if (v = t.dom.getStyle(e, 'height')) {\r
7881                                                                 t.dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));\r
7882                                                                 t.dom.setStyle(e, 'height', '');\r
7883                                                         }\r
7884                                                 });\r
7885                                         } else {\r
7886                                                 ev = 'resizestart';\r
7887                                                 cb = Event.add(e, 'resizestart', Event.cancel, Event);\r
7888                                         }\r
7889 \r
7890                                         re = t.resizeInfo = {\r
7891                                                 node : e,\r
7892                                                 ev : ev,\r
7893                                                 cb : cb\r
7894                                         };\r
7895                                 });\r
7896 \r
7897                                 t.onKeyDown.add(function(ed, e) {\r
7898                                         switch (e.keyCode) {\r
7899                                                 case 8:\r
7900                                                         // Fix IE control + backspace browser bug\r
7901                                                         if (t.selection.getRng().item) {\r
7902                                                                 t.selection.getRng().item(0).removeNode();\r
7903                                                                 return Event.cancel(e);\r
7904                                                         }\r
7905                                         }\r
7906                                 });\r
7907                         }\r
7908 \r
7909                         if (tinymce.isOpera) {\r
7910                                 t.onClick.add(function(ed, e) {\r
7911                                         Event.prevent(e);\r
7912                                 });\r
7913                         }\r
7914 \r
7915                         // Add custom undo/redo handlers\r
7916                         if (s.custom_undo_redo) {\r
7917                                 function addUndo() {\r
7918                                         t.undoManager.typing = 0;\r
7919                                         t.undoManager.add();\r
7920                                 };\r
7921 \r
7922                                 // Add undo level on editor blur\r
7923                                 if (tinymce.isIE) {\r
7924                                         Event.add(t.getWin(), 'blur', function(e) {\r
7925                                                 var n;\r
7926 \r
7927                                                 // Check added for fullscreen bug\r
7928                                                 if (t.selection) {\r
7929                                                         n = t.selection.getNode();\r
7930 \r
7931                                                         // Add undo level is selection was lost to another document\r
7932                                                         if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc())\r
7933                                                                 addUndo();\r
7934                                                 }\r
7935                                         });\r
7936                                 } else {\r
7937                                         Event.add(t.getDoc(), 'blur', function() {\r
7938                                                 if (t.selection && !t.removed)\r
7939                                                         addUndo();\r
7940                                         });\r
7941                                 }\r
7942 \r
7943                                 t.onMouseDown.add(addUndo);\r
7944 \r
7945                                 t.onKeyUp.add(function(ed, e) {\r
7946                                         if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) {\r
7947                                                 t.undoManager.typing = 0;\r
7948                                                 t.undoManager.add();\r
7949                                         }\r
7950                                 });\r
7951 \r
7952                                 t.onKeyDown.add(function(ed, e) {\r
7953                                         // Is caracter positon keys\r
7954                                         if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) {\r
7955                                                 if (t.undoManager.typing) {\r
7956                                                         t.undoManager.add();\r
7957                                                         t.undoManager.typing = 0;\r
7958                                                 }\r
7959 \r
7960                                                 return;\r
7961                                         }\r
7962 \r
7963                                         if (!t.undoManager.typing) {\r
7964                                                 t.undoManager.add();\r
7965                                                 t.undoManager.typing = 1;\r
7966                                         }\r
7967                                 });\r
7968                         }\r
7969                 },\r
7970 \r
7971                 _convertInlineElements : function() {\r
7972                         var t = this, s = t.settings, dom = t.dom, v, e, na, st, sp;\r
7973 \r
7974                         function convert(ed, o) {\r
7975                                 if (!s.inline_styles)\r
7976                                         return;\r
7977 \r
7978                                 if (o.get) {\r
7979                                         each(t.dom.select('table,u,strike', o.node), function(n) {\r
7980                                                 switch (n.nodeName) {\r
7981                                                         case 'TABLE':\r
7982                                                                 if (v = dom.getAttrib(n, 'height')) {\r
7983                                                                         dom.setStyle(n, 'height', v);\r
7984                                                                         dom.setAttrib(n, 'height', '');\r
7985                                                                 }\r
7986                                                                 break;\r
7987 \r
7988                                                         case 'U':\r
7989                                                         case 'STRIKE':\r
7990                                                                 sp = dom.create('span', {style : dom.getAttrib(n, 'style')});\r
7991                                                                 sp.style.textDecoration = n.nodeName == 'U' ? 'underline' : 'line-through';\r
7992                                                                 dom.setAttrib(sp, 'mce_style', '');\r
7993                                                                 dom.replace(sp, n, 1);\r
7994                                                                 break;\r
7995                                                 }\r
7996                                         });\r
7997                                 } else if (o.set) {\r
7998                                         each(t.dom.select('table,span', o.node), function(n) {\r
7999                                                 if (n.nodeName == 'TABLE') {\r
8000                                                         if (v = dom.getStyle(n, 'height'))\r
8001                                                                 dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));\r
8002                                                 } else {\r
8003                                                         // Convert spans to elements\r
8004                                                         if (n.style.textDecoration == 'underline')\r
8005                                                                 na = 'u';\r
8006                                                         else if (n.style.textDecoration == 'line-through')\r
8007                                                                 na = 'strike';\r
8008                                                         else\r
8009                                                                 na = '';\r
8010 \r
8011                                                         if (na) {\r
8012                                                                 n.style.textDecoration = '';\r
8013                                                                 dom.setAttrib(n, 'mce_style', '');\r
8014 \r
8015                                                                 e = dom.create(na, {\r
8016                                                                         style : dom.getAttrib(n, 'style')\r
8017                                                                 });\r
8018 \r
8019                                                                 dom.replace(e, n, 1);\r
8020                                                         }\r
8021                                                 }\r
8022                                         });\r
8023                                 }\r
8024                         };\r
8025 \r
8026                         t.onPreProcess.add(convert);\r
8027 \r
8028                         if (!s.cleanup_on_startup) {\r
8029                                 t.onInit.add(function() {\r
8030                                         convert(t, {node : t.getBody(), set : 1});\r
8031                                 });\r
8032                         }\r
8033                 },\r
8034 \r
8035                 _convertFonts : function() {\r
8036                         var t = this, s = t.settings, dom = t.dom, fz, fzn, sl, cl;\r
8037 \r
8038                         // No need\r
8039                         if (!s.inline_styles)\r
8040                                 return;\r
8041 \r
8042                         // Font pt values and font size names\r
8043                         fz = [8, 10, 12, 14, 18, 24, 36];\r
8044                         fzn = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large'];\r
8045 \r
8046                         if (sl = s.font_size_style_values)\r
8047                                 sl = explode(sl);\r
8048 \r
8049                         if (cl = s.font_size_classes)\r
8050                                 cl = explode(cl);\r
8051 \r
8052                         function convertToFonts(no) {\r
8053                                 var n, f, nl, x, i, v, st;\r
8054 \r
8055                                 // Convert spans to fonts on non WebKit browsers\r
8056                                 if (tinymce.isWebKit || !s.inline_styles)\r
8057                                         return;\r
8058 \r
8059                                 nl = t.dom.select('span', no);\r
8060                                 for (x = nl.length - 1; x >= 0; x--) {\r
8061                                         n = nl[x];\r
8062 \r
8063                                         f = dom.create('font', {\r
8064                                                 color : dom.toHex(dom.getStyle(n, 'color')),\r
8065                                                 face : dom.getStyle(n, 'fontFamily'),\r
8066                                                 style : dom.getAttrib(n, 'style'),\r
8067                                                 'class' : dom.getAttrib(n, 'class')\r
8068                                         });\r
8069 \r
8070                                         // Clear color and font family\r
8071                                         st = f.style;\r
8072                                         if (st.color || st.fontFamily) {\r
8073                                                 st.color = st.fontFamily = '';\r
8074                                                 dom.setAttrib(f, 'mce_style', ''); // Remove cached style data\r
8075                                         }\r
8076 \r
8077                                         if (sl) {\r
8078                                                 i = inArray(sl, dom.getStyle(n, 'fontSize'));\r
8079 \r
8080                                                 if (i != -1) {\r
8081                                                         dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
8082                                                         f.style.fontSize = '';\r
8083                                                 }\r
8084                                         } else if (cl) {\r
8085                                                 i = inArray(cl, dom.getAttrib(n, 'class'));\r
8086                                                 v = dom.getStyle(n, 'fontSize');\r
8087 \r
8088                                                 if (i == -1 && v.indexOf('pt') > 0)\r
8089                                                         i = inArray(fz, parseInt(v));\r
8090 \r
8091                                                 if (i == -1)\r
8092                                                         i = inArray(fzn, v);\r
8093 \r
8094                                                 if (i != -1) {\r
8095                                                         dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
8096                                                         f.style.fontSize = '';\r
8097                                                 }\r
8098                                         }\r
8099 \r
8100                                         if (f.color || f.face || f.size) {\r
8101                                                 f.style.fontFamily = '';\r
8102                                                 dom.setAttrib(f, 'mce_style', '');\r
8103                                                 dom.replace(f, n, 1);\r
8104                                         }\r
8105 \r
8106                                         f = n = null;\r
8107                                 }\r
8108                         };\r
8109 \r
8110                         // Run on setup\r
8111                         t.onSetContent.add(function(ed, o) {\r
8112                                 convertToFonts(ed.getBody());\r
8113                         });\r
8114 \r
8115                         // Run on cleanup\r
8116                         t.onPreProcess.add(function(ed, o) {\r
8117                                 var n, sp, nl, x;\r
8118 \r
8119                                 // Keep unit tests happy\r
8120                                 if (!s.inline_styles)\r
8121                                         return;\r
8122 \r
8123                                 if (o.get) {\r
8124                                         nl = t.dom.select('font', o.node);\r
8125                                         for (x = nl.length - 1; x >= 0; x--) {\r
8126                                                 n = nl[x];\r
8127 \r
8128                                                 sp = dom.create('span', {\r
8129                                                         style : dom.getAttrib(n, 'style'),\r
8130                                                         'class' : dom.getAttrib(n, 'class')\r
8131                                                 });\r
8132 \r
8133                                                 dom.setStyles(sp, {\r
8134                                                         fontFamily : dom.getAttrib(n, 'face'),\r
8135                                                         color : dom.getAttrib(n, 'color'),\r
8136                                                         backgroundColor : n.style.backgroundColor\r
8137                                                 });\r
8138 \r
8139                                                 if (n.size) {\r
8140                                                         if (sl)\r
8141                                                                 dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]);\r
8142                                                         else\r
8143                                                                 dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);\r
8144                                                 }\r
8145 \r
8146                                                 dom.setAttrib(sp, 'mce_style', '');\r
8147                                                 dom.replace(sp, n, 1);\r
8148                                         }\r
8149                                 }\r
8150                         });\r
8151                 },\r
8152 \r
8153                 _isHidden : function() {\r
8154                         var s;\r
8155 \r
8156                         if (!isGecko)\r
8157                                 return 0;\r
8158 \r
8159                         // Weird, wheres that cursor selection?\r
8160                         s = this.selection.getSel();\r
8161                         return (!s || !s.rangeCount || s.rangeCount == 0);\r
8162                 },\r
8163 \r
8164                 // Fix for bug #1867292\r
8165                 _fixNesting : function(s) {\r
8166                         var d = [], i;\r
8167 \r
8168                         s = s.replace(/<(\/)?([^\s>]+)[^>]*?>/g, function(a, b, c) {\r
8169                                 var e;\r
8170 \r
8171                                 // Handle end element\r
8172                                 if (b === '/') {\r
8173                                         if (!d.length)\r
8174                                                 return '';\r
8175 \r
8176                                         if (c !== d[d.length - 1].tag) {\r
8177                                                 for (i=d.length - 1; i>=0; i--) {\r
8178                                                         if (d[i].tag === c) {\r
8179                                                                 d[i].close = 1;\r
8180                                                                 break;\r
8181                                                         }\r
8182                                                 }\r
8183 \r
8184                                                 return '';\r
8185                                         } else {\r
8186                                                 d.pop();\r
8187 \r
8188                                                 if (d.length && d[d.length - 1].close) {\r
8189                                                         a = a + '</' + d[d.length - 1].tag + '>';\r
8190                                                         d.pop();\r
8191                                                 }\r
8192                                         }\r
8193                                 } else {\r
8194                                         // Ignore these\r
8195                                         if (/^(br|hr|input|meta|img|link|param)$/i.test(c))\r
8196                                                 return a;\r
8197 \r
8198                                         // Ignore closed ones\r
8199                                         if (/\/>$/.test(a))\r
8200                                                 return a;\r
8201 \r
8202                                         d.push({tag : c}); // Push start element\r
8203                                 }\r
8204 \r
8205                                 return a;\r
8206                         });\r
8207 \r
8208                         // End all open tags\r
8209                         for (i=d.length - 1; i>=0; i--)\r
8210                                 s += '</' + d[i].tag + '>';\r
8211 \r
8212                         return s;\r
8213                 }\r
8214 \r
8215                 });\r
8216 })();\r
8217 \r
8218 /* file:jscripts/tiny_mce/classes/EditorCommands.js */\r
8219 \r
8220 (function() {\r
8221         var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;\r
8222 \r
8223         tinymce.create('tinymce.EditorCommands', {\r
8224                 EditorCommands : function(ed) {\r
8225                         this.editor = ed;\r
8226                 },\r
8227 \r
8228                 execCommand : function(cmd, ui, val) {\r
8229                         var t = this, ed = t.editor, f;\r
8230 \r
8231                         switch (cmd) {\r
8232                                 case 'Cut':\r
8233                                 case 'Copy':\r
8234                                 case 'Paste':\r
8235                                         try {\r
8236                                                 ed.getDoc().execCommand(cmd, ui, val);\r
8237                                         } catch (ex) {\r
8238                                                 if (isGecko) {\r
8239                                                         ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {\r
8240                                                                 if (s)\r
8241                                                                         window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');\r
8242                                                         });\r
8243                                                 } else\r
8244                                                         ed.windowManager.alert(ed.getLang('clipboard_no_support'));\r
8245                                         }\r
8246 \r
8247                                         return true;\r
8248 \r
8249                                 // Ignore these\r
8250                                 case 'mceResetDesignMode':\r
8251                                 case 'mceBeginUndoLevel':\r
8252                                         return true;\r
8253 \r
8254                                 // Ignore these\r
8255                                 case 'unlink':\r
8256                                         t.UnLink();\r
8257                                         return true;\r
8258 \r
8259                                 // Bundle these together\r
8260                                 case 'JustifyLeft':\r
8261                                 case 'JustifyCenter':\r
8262                                 case 'JustifyRight':\r
8263                                 case 'JustifyFull':\r
8264                                         t.mceJustify(cmd, cmd.substring(7).toLowerCase());\r
8265                                         return true;\r
8266 \r
8267                                 case 'mceEndUndoLevel':\r
8268                                 case 'mceAddUndoLevel':\r
8269                                         ed.undoManager.add();\r
8270                                         return true;\r
8271 \r
8272                                 default:\r
8273                                         f = this[cmd];\r
8274 \r
8275                                         if (f) {\r
8276                                                 f.call(this, ui, val);\r
8277                                                 return true;\r
8278                                         }\r
8279                         }\r
8280 \r
8281                         return false;\r
8282                 },\r
8283 \r
8284                 Indent : function() {\r
8285                         var ed = this.editor, d = ed.dom, s = ed.selection, e, iv, iu;\r
8286 \r
8287                         // Setup indent level\r
8288                         iv = ed.settings.indentation;\r
8289                         iu = /[a-z%]+$/i.exec(iv);\r
8290                         iv = parseInt(iv);\r
8291 \r
8292                         if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
8293                                 each(this._getSelectedBlocks(), function(e) {\r
8294                                         d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);\r
8295                                 });\r
8296 \r
8297                                 return;\r
8298                         }\r
8299 \r
8300                         ed.getDoc().execCommand('Indent', false, null);\r
8301 \r
8302                         if (isIE) {\r
8303                                 d.getParent(s.getNode(), function(n) {\r
8304                                         if (n.nodeName == 'BLOCKQUOTE') {\r
8305                                                 n.dir = n.style.cssText = '';\r
8306                                         }\r
8307                                 });\r
8308                         }\r
8309                 },\r
8310 \r
8311                 Outdent : function() {\r
8312                         var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu;\r
8313 \r
8314                         // Setup indent level\r
8315                         iv = ed.settings.indentation;\r
8316                         iu = /[a-z%]+$/i.exec(iv);\r
8317                         iv = parseInt(iv);\r
8318 \r
8319                         if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
8320                                 each(this._getSelectedBlocks(), function(e) {\r
8321                                         v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);\r
8322                                         d.setStyle(e, 'paddingLeft', v ? v + iu : '');\r
8323                                 });\r
8324 \r
8325                                 return;\r
8326                         }\r
8327 \r
8328                         ed.getDoc().execCommand('Outdent', false, null);\r
8329                 },\r
8330 \r
8331                 mceSetAttribute : function(u, v) {\r
8332                         var ed = this.editor, d = ed.dom, e;\r
8333 \r
8334                         if (e = d.getParent(ed.selection.getNode(), d.isBlock))\r
8335                                 d.setAttrib(e, v.name, v.value);\r
8336                 },\r
8337 \r
8338                 mceSetContent : function(u, v) {\r
8339                         this.editor.setContent(v);\r
8340                 },\r
8341 \r
8342                 mceToggleVisualAid : function() {\r
8343                         var ed = this.editor;\r
8344 \r
8345                         ed.hasVisual = !ed.hasVisual;\r
8346                         ed.addVisual();\r
8347                 },\r
8348 \r
8349                 mceReplaceContent : function(u, v) {\r
8350                         var s = this.editor.selection;\r
8351 \r
8352                         s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'})));\r
8353                 },\r
8354 \r
8355                 mceInsertLink : function(u, v) {\r
8356                         var ed = this.editor, e = ed.dom.getParent(ed.selection.getNode(), 'A');\r
8357 \r
8358                         if (tinymce.is(v, 'string'))\r
8359                                 v = {href : v};\r
8360 \r
8361                         function set(e) {\r
8362                                 each(v, function(v, k) {\r
8363                                         ed.dom.setAttrib(e, k, v);\r
8364                                 });\r
8365                         };\r
8366 \r
8367                         if (!e) {\r
8368                                 ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');\r
8369                                 each(ed.dom.select('a'), function(e) {\r
8370                                         if (e.href == 'javascript:mctmp(0);')\r
8371                                                 set(e);\r
8372                                 });\r
8373                         } else {\r
8374                                 if (v.href)\r
8375                                         set(e);\r
8376                                 else\r
8377                                         ed.dom.remove(e, 1);\r
8378                         }\r
8379                 },\r
8380 \r
8381                 UnLink : function() {\r
8382                         var ed = this.editor, s = ed.selection;\r
8383 \r
8384                         if (s.isCollapsed())\r
8385                                 s.select(s.getNode());\r
8386 \r
8387                         ed.getDoc().execCommand('unlink', false, null);\r
8388                         s.collapse(0);\r
8389                 },\r
8390 \r
8391                 FontName : function(u, v) {\r
8392                         var t = this, ed = t.editor, s = ed.selection, e;\r
8393 \r
8394                         if (!v) {\r
8395                                 if (s.isCollapsed())\r
8396                                         s.select(s.getNode());\r
8397 \r
8398                                 t.RemoveFormat();\r
8399                         } else\r
8400                                 ed.getDoc().execCommand('FontName', false, v);\r
8401                 },\r
8402 \r
8403                 queryCommandValue : function(c) {\r
8404                         var f = this['queryValue' + c];\r
8405 \r
8406                         if (f)\r
8407                                 return f.call(this, c);\r
8408 \r
8409                         return false;\r
8410                 },\r
8411 \r
8412                 queryCommandState : function(cmd) {\r
8413                         var f;\r
8414 \r
8415                         switch (cmd) {\r
8416                                 // Bundle these together\r
8417                                 case 'JustifyLeft':\r
8418                                 case 'JustifyCenter':\r
8419                                 case 'JustifyRight':\r
8420                                 case 'JustifyFull':\r
8421                                         return this.queryStateJustify(cmd, cmd.substring(7).toLowerCase());\r
8422 \r
8423                                 default:\r
8424                                         if (f = this['queryState' + cmd])\r
8425                                                 return f.call(this, cmd);\r
8426                         }\r
8427 \r
8428                         return -1;\r
8429                 },\r
8430 \r
8431                 _queryState : function(c) {\r
8432                         try {\r
8433                                 return this.editor.getDoc().queryCommandState(c);\r
8434                         } catch (ex) {\r
8435                                 // Ignore exception\r
8436                         }\r
8437                 },\r
8438 \r
8439                 _queryVal : function(c) {\r
8440                         try {\r
8441                                 return this.editor.getDoc().queryCommandValue(c);\r
8442                         } catch (ex) {\r
8443                                 // Ignore exception\r
8444                         }\r
8445                 },\r
8446 \r
8447                 queryValueFontSize : function() {\r
8448                         var ed = this.editor, v = 0, p;\r
8449 \r
8450                         if (isOpera || isWebKit) {\r
8451                                 if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
8452                                         v = p.size;\r
8453 \r
8454                                 return v;\r
8455                         }\r
8456 \r
8457                         return this._queryVal('FontSize');\r
8458                 },\r
8459 \r
8460                 queryValueFontName : function() {\r
8461                         var ed = this.editor, v = 0, p;\r
8462 \r
8463                         if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
8464                                 v = p.face;\r
8465 \r
8466                         if (!v)\r
8467                                 v = this._queryVal('FontName');\r
8468 \r
8469                         return v;\r
8470                 },\r
8471 \r
8472                 mceJustify : function(c, v) {\r
8473                         var ed = this.editor, se = ed.selection, n = se.getNode(), nn = n.nodeName, bl, nb, dom = ed.dom, rm;\r
8474 \r
8475                         if (ed.settings.inline_styles && this.queryStateJustify(c, v))\r
8476                                 rm = 1;\r
8477 \r
8478                         bl = dom.getParent(n, ed.dom.isBlock);\r
8479 \r
8480                         if (nn == 'IMG') {\r
8481                                 if (v == 'full')\r
8482                                         return;\r
8483 \r
8484                                 if (rm) {\r
8485                                         if (v == 'center')\r
8486                                                 dom.setStyle(n.parentNode, 'textAlign', '');\r
8487 \r
8488                                         dom.setStyle(n, 'float', '');\r
8489                                         this.mceRepaint();\r
8490                                         return;\r
8491                                 }\r
8492 \r
8493                                 if (v == 'center') {\r
8494                                         // Do not change table elements\r
8495                                         if (/^(TD|TH)$/.test(bl.nodeName))\r
8496                                                 bl = 0;\r
8497 \r
8498                                         if (!bl || bl.childNodes.length > 1) {\r
8499                                                 nb = dom.create('p');\r
8500                                                 nb.appendChild(n.cloneNode(false));\r
8501 \r
8502                                                 if (bl)\r
8503                                                         dom.insertAfter(nb, bl);\r
8504                                                 else\r
8505                                                         dom.insertAfter(nb, n);\r
8506 \r
8507                                                 dom.remove(n);\r
8508                                                 n = nb.firstChild;\r
8509                                                 bl = nb;\r
8510                                         }\r
8511 \r
8512                                         dom.setStyle(bl, 'textAlign', v);\r
8513                                         dom.setStyle(n, 'float', '');\r
8514                                 } else {\r
8515                                         dom.setStyle(n, 'float', v);\r
8516                                         dom.setStyle(n.parentNode, 'textAlign', '');\r
8517                                 }\r
8518 \r
8519                                 this.mceRepaint();\r
8520                                 return;\r
8521                         }\r
8522 \r
8523                         // Handle the alignment outselfs, less quirks in all browsers\r
8524                         if (ed.settings.inline_styles && ed.settings.forced_root_block) {\r
8525                                 if (rm)\r
8526                                         v = '';\r
8527 \r
8528                                 each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {\r
8529                                         dom.setAttrib(e, 'align', '');\r
8530                                         dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);\r
8531                                 });\r
8532 \r
8533                                 return;\r
8534                         } else if (!rm)\r
8535                                 ed.getDoc().execCommand(c, false, null);\r
8536 \r
8537                         if (ed.settings.inline_styles) {\r
8538                                 if (rm) {\r
8539                                         dom.getParent(ed.selection.getNode(), function(n) {\r
8540                                                 if (n.style && n.style.textAlign)\r
8541                                                         dom.setStyle(n, 'textAlign', '');\r
8542                                         });\r
8543 \r
8544                                         return;\r
8545                                 }\r
8546 \r
8547                                 each(dom.select('*'), function(n) {\r
8548                                         var v = n.align;\r
8549 \r
8550                                         if (v) {\r
8551                                                 if (v == 'full')\r
8552                                                         v = 'justify';\r
8553 \r
8554                                                 dom.setStyle(n, 'textAlign', v);\r
8555                                                 dom.setAttrib(n, 'align', '');\r
8556                                         }\r
8557                                 });\r
8558                         }\r
8559                 },\r
8560 \r
8561                 mceSetCSSClass : function(u, v) {\r
8562                         this.mceSetStyleInfo(0, {command : 'setattrib', name : 'class', value : v});\r
8563                 },\r
8564 \r
8565                 getSelectedElement : function() {\r
8566                         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
8567 \r
8568                         if (se.isCollapsed() || r.item)\r
8569                                 return se.getNode();\r
8570 \r
8571                         // Setup regexp\r
8572                         re = ed.settings.merge_styles_invalid_parents;\r
8573                         if (tinymce.is(re, 'string'))\r
8574                                 re = new RegExp(re, 'i');\r
8575 \r
8576                         if (isIE) {\r
8577                                 r1 = r.duplicate();\r
8578                                 r1.collapse(true);\r
8579                                 sc = r1.parentElement();\r
8580 \r
8581                                 r2 = r.duplicate();\r
8582                                 r2.collapse(false);\r
8583                                 ec = r2.parentElement();\r
8584 \r
8585                                 if (sc != ec) {\r
8586                                         r1.move('character', 1);\r
8587                                         sc = r1.parentElement();\r
8588                                 }\r
8589 \r
8590                                 if (sc == ec) {\r
8591                                         r1 = r.duplicate();\r
8592                                         r1.moveToElementText(sc);\r
8593 \r
8594                                         if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0)\r
8595                                                 return re && re.test(sc.nodeName) ? null : sc;\r
8596                                 }\r
8597                         } else {\r
8598                                 function getParent(n) {\r
8599                                         return dom.getParent(n, function(n) {return n.nodeType == 1;});\r
8600                                 };\r
8601 \r
8602                                 sc = r.startContainer;\r
8603                                 ec = r.endContainer;\r
8604                                 so = r.startOffset;\r
8605                                 eo = r.endOffset;\r
8606 \r
8607                                 if (!r.collapsed) {\r
8608                                         if (sc == ec) {\r
8609                                                 if (so - eo < 2) {\r
8610                                                         if (sc.hasChildNodes()) {\r
8611                                                                 sp = sc.childNodes[so];\r
8612                                                                 return re && re.test(sp.nodeName) ? null : sp;\r
8613                                                         }\r
8614                                                 }\r
8615                                         }\r
8616                                 }\r
8617 \r
8618                                 if (sc.nodeType != 3 || ec.nodeType != 3)\r
8619                                         return null;\r
8620 \r
8621                                 if (so == 0) {\r
8622                                         sp = getParent(sc);\r
8623 \r
8624                                         if (sp && sp.firstChild != sc)\r
8625                                                 sp = null;\r
8626                                 }\r
8627 \r
8628                                 if (so == sc.nodeValue.length) {\r
8629                                         e = sc.nextSibling;\r
8630 \r
8631                                         if (e && e.nodeType == 1)\r
8632                                                 sp = sc.nextSibling;\r
8633                                 }\r
8634 \r
8635                                 if (eo == 0) {\r
8636                                         e = ec.previousSibling;\r
8637 \r
8638                                         if (e && e.nodeType == 1)\r
8639                                                 ep = e;\r
8640                                 }\r
8641 \r
8642                                 if (eo == ec.nodeValue.length) {\r
8643                                         ep = getParent(ec);\r
8644 \r
8645                                         if (ep && ep.lastChild != ec)\r
8646                                                 ep = null;\r
8647                                 }\r
8648 \r
8649                                 // Same element\r
8650                                 if (sp == ep)\r
8651                                         return re && sp && re.test(sp.nodeName) ? null : sp;\r
8652                         }\r
8653 \r
8654                         return null;\r
8655                 },\r
8656 \r
8657                 InsertHorizontalRule : function() {\r
8658                         // Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");\r
8659                         if (isGecko || isIE)\r
8660                                 this.editor.selection.setContent('<hr />');\r
8661                         else\r
8662                                 this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');\r
8663                 },\r
8664 \r
8665                 RemoveFormat : function() {\r
8666                         var t = this, ed = t.editor, s = ed.selection, b;\r
8667 \r
8668                         // Safari breaks tables\r
8669                         if (isWebKit)\r
8670                                 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
8671                         else\r
8672                                 ed.getDoc().execCommand('RemoveFormat', false, null);\r
8673 \r
8674                         t.mceSetStyleInfo(0, {command : 'removeformat'});\r
8675                         ed.addVisual();\r
8676                 },\r
8677 \r
8678                 mceSetStyleInfo : function(u, v) {\r
8679                         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
8680 \r
8681                         function set(n, e) {\r
8682                                 if (n.nodeType == 1) {\r
8683                                         switch (v.command) {\r
8684                                                 case 'setattrib':\r
8685                                                         return dom.setAttrib(n, v.name, v.value);\r
8686 \r
8687                                                 case 'setstyle':\r
8688                                                         return dom.setStyle(n, v.name, v.value);\r
8689 \r
8690                                                 case 'removeformat':\r
8691                                                         return dom.setAttrib(n, 'class', '');\r
8692                                         }\r
8693                                 }\r
8694                         };\r
8695 \r
8696                         // Setup regexp\r
8697                         re = ed.settings.merge_styles_invalid_parents;\r
8698                         if (tinymce.is(re, 'string'))\r
8699                                 re = new RegExp(re, 'i');\r
8700 \r
8701                         // Set style info on selected element\r
8702                         if (e = t.getSelectedElement())\r
8703                                 set(e, 1);\r
8704                         else {\r
8705                                 // Generate wrappers and set styles on them\r
8706                                 d.execCommand('FontName', false, '__');\r
8707                                 each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {\r
8708                                         var sp, e;\r
8709 \r
8710                                         if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {\r
8711                                                 sp = dom.create(nn, {mce_new : '1'});\r
8712 \r
8713                                                 set(sp);\r
8714 \r
8715                                                 each (n.childNodes, function(n) {\r
8716                                                         sp.appendChild(n.cloneNode(true));\r
8717                                                 });\r
8718 \r
8719                                                 dom.replace(sp, n);\r
8720                                         }\r
8721                                 });\r
8722                         }\r
8723 \r
8724                         // Remove wrappers inside new ones\r
8725                         each(dom.select(nn).reverse(), function(n) {\r
8726                                 var p = n.parentNode;\r
8727 \r
8728                                 // Check if it's an old span in a new wrapper\r
8729                                 if (!dom.getAttrib(n, 'mce_new')) {\r
8730                                         // Find new wrapper\r
8731                                         p = dom.getParent(n, function(n) {\r
8732                                                 return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');\r
8733                                         });\r
8734 \r
8735                                         if (p)\r
8736                                                 dom.remove(n, 1);\r
8737                                 }\r
8738                         });\r
8739 \r
8740                         // Merge wrappers with parent wrappers\r
8741                         each(dom.select(nn).reverse(), function(n) {\r
8742                                 var p = n.parentNode;\r
8743 \r
8744                                 if (!p || !dom.getAttrib(n, 'mce_new'))\r
8745                                         return;\r
8746 \r
8747                                 // Has parent of the same type and only child\r
8748                                 if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1)\r
8749                                         return dom.remove(p, 1);\r
8750 \r
8751                                 // Has parent that is more suitable to have the class and only child\r
8752                                 if (n.nodeType == 1 && (!re || !re.test(p.nodeName)) && p.childNodes.length == 1) {\r
8753                                         set(p); // Set style info on parent instead\r
8754                                         dom.setAttrib(n, 'class', '');\r
8755                                 }\r
8756                         });\r
8757 \r
8758                         // Remove empty wrappers\r
8759                         each(dom.select(nn).reverse(), function(n) {\r
8760                                 if (dom.getAttrib(n, 'mce_new') || (dom.getAttribs(n).length <= 1 && n.className === '')) {\r
8761                                         if (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style'))\r
8762                                                 return dom.remove(n, 1);\r
8763 \r
8764                                         dom.setAttrib(n, 'mce_new', ''); // Remove mce_new marker\r
8765                                 }\r
8766                         });\r
8767 \r
8768                         s.moveToBookmark(b);\r
8769                 },\r
8770 \r
8771                 queryStateJustify : function(c, v) {\r
8772                         var ed = this.editor, n = ed.selection.getNode(), dom = ed.dom;\r
8773 \r
8774                         if (n && n.nodeName == 'IMG') {\r
8775                                 if (dom.getStyle(n, 'float') == v)\r
8776                                         return 1;\r
8777 \r
8778                                 return n.parentNode.style.textAlign == v;\r
8779                         }\r
8780 \r
8781                         n = dom.getParent(ed.selection.getStart(), function(n) {\r
8782                                 return n.nodeType == 1 && n.style.textAlign;\r
8783                         });\r
8784 \r
8785                         if (v == 'full')\r
8786                                 v = 'justify';\r
8787 \r
8788                         if (ed.settings.inline_styles)\r
8789                                 return (n && n.style.textAlign == v);\r
8790 \r
8791                         return this._queryState(c);\r
8792                 },\r
8793 \r
8794                 HiliteColor : function(ui, val) {\r
8795                         var t = this, ed = t.editor, d = ed.getDoc();\r
8796 \r
8797                         function set(s) {\r
8798                                 if (!isGecko)\r
8799                                         return;\r
8800 \r
8801                                 try {\r
8802                                         // Try new Gecko method\r
8803                                         d.execCommand("styleWithCSS", 0, s);\r
8804                                 } catch (ex) {\r
8805                                         // Use old\r
8806                                         d.execCommand("useCSS", 0, !s);\r
8807                                 }\r
8808                         };\r
8809 \r
8810                         if (isGecko || isOpera) {\r
8811                                 set(true);\r
8812                                 d.execCommand('hilitecolor', false, val);\r
8813                                 set(false);\r
8814                         } else\r
8815                                 d.execCommand('BackColor', false, val);\r
8816                 },\r
8817 \r
8818                 Undo : function() {\r
8819                         var ed = this.editor;\r
8820 \r
8821                         if (ed.settings.custom_undo_redo) {\r
8822                                 ed.undoManager.undo();\r
8823                                 ed.nodeChanged();\r
8824                         } else\r
8825                                 ed.getDoc().execCommand('Undo', false, null);\r
8826                 },\r
8827 \r
8828                 Redo : function() {\r
8829                         var ed = this.editor;\r
8830 \r
8831                         if (ed.settings.custom_undo_redo) {\r
8832                                 ed.undoManager.redo();\r
8833                                 ed.nodeChanged();\r
8834                         } else\r
8835                                 ed.getDoc().execCommand('Redo', false, null);\r
8836                 },\r
8837 \r
8838                 FormatBlock : function(ui, val) {\r
8839                         var t = this, ed = t.editor;\r
8840 \r
8841                         val = ed.settings.forced_root_block ? (val || '<p>') : val;\r
8842 \r
8843                         if (/^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(ed.selection.getNode().nodeName))\r
8844                                 t.mceRemoveNode();\r
8845 \r
8846                         if (val.indexOf('<') == -1)\r
8847                                 val = '<' + val + '>';\r
8848 \r
8849                         if (tinymce.isGecko)\r
8850                                 val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1');\r
8851 \r
8852                         ed.getDoc().execCommand('FormatBlock', false, val);\r
8853                 },\r
8854 \r
8855                 mceCleanup : function() {\r
8856                         var ed = this.editor, s = ed.selection, b = s.getBookmark();\r
8857                         ed.setContent(ed.getContent());\r
8858                         s.moveToBookmark(b);\r
8859                 },\r
8860 \r
8861                 mceRemoveNode : function(ui, val) {\r
8862                         var ed = this.editor, s = ed.selection, b, n = val || s.getNode();\r
8863 \r
8864                         // Make sure that the body node isn't removed\r
8865                         if (n == ed.getBody())\r
8866                                 return;\r
8867 \r
8868                         b = s.getBookmark();\r
8869                         ed.dom.remove(n, 1);\r
8870                         s.moveToBookmark(b);\r
8871                         ed.nodeChanged();\r
8872                 },\r
8873 \r
8874                 mceSelectNodeDepth : function(ui, val) {\r
8875                         var ed = this.editor, s = ed.selection, c = 0;\r
8876 \r
8877                         ed.dom.getParent(s.getNode(), function(n) {\r
8878                                 if (n.nodeType == 1 && c++ == val) {\r
8879                                         s.select(n);\r
8880                                         ed.nodeChanged();\r
8881                                         return false;\r
8882                                 }\r
8883                         }, ed.getBody());\r
8884                 },\r
8885 \r
8886                 mceSelectNode : function(u, v) {\r
8887                         this.editor.selection.select(v);\r
8888                 },\r
8889 \r
8890                 mceInsertContent : function(ui, val) {\r
8891                         this.editor.selection.setContent(val);\r
8892                 },\r
8893 \r
8894                 mceInsertRawHTML : function(ui, val) {\r
8895                         var ed = this.editor;\r
8896 \r
8897                         ed.selection.setContent('tiny_mce_marker');\r
8898                         ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val));\r
8899                 },\r
8900 \r
8901                 mceRepaint : function() {\r
8902                         var s, b, e = this.editor;\r
8903 \r
8904                         if (tinymce.isGecko) {\r
8905                                 try {\r
8906                                         s = e.selection;\r
8907                                         b = s.getBookmark(true);\r
8908 \r
8909                                         if (s.getSel())\r
8910                                                 s.getSel().selectAllChildren(e.getBody());\r
8911 \r
8912                                         s.collapse(true);\r
8913                                         s.moveToBookmark(b);\r
8914                                 } catch (ex) {\r
8915                                         // Ignore\r
8916                                 }\r
8917                         }\r
8918                 },\r
8919 \r
8920                 queryStateUnderline : function() {\r
8921                         var ed = this.editor, n;\r
8922 \r
8923                         if (n && n.nodeName == 'A')\r
8924                                 return false;\r
8925 \r
8926                         return this._queryState('Underline');\r
8927                 },\r
8928 \r
8929                 queryStateOutdent : function() {\r
8930                         var ed = this.editor, n;\r
8931 \r
8932                         if (ed.settings.inline_styles) {\r
8933                                 if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
8934                                         return true;\r
8935 \r
8936                                 if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
8937                                         return true;\r
8938                         } else\r
8939                                 return !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE');\r
8940 \r
8941                         return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList();\r
8942                 },\r
8943 \r
8944                 queryStateInsertUnorderedList : function() {\r
8945                         return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL');\r
8946                 },\r
8947 \r
8948                 queryStateInsertOrderedList : function() {\r
8949                         return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL');\r
8950                 },\r
8951 \r
8952                 queryStatemceBlockQuote : function() {\r
8953                         return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
8954                 },\r
8955 \r
8956                 mceBlockQuote : function() {\r
8957                         var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;\r
8958 \r
8959                         function getBQ(e) {\r
8960                                 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
8961                         };\r
8962 \r
8963                         // Get start/end block\r
8964                         sb = dom.getParent(s.getStart(), dom.isBlock);\r
8965                         eb = dom.getParent(s.getEnd(), dom.isBlock);\r
8966 \r
8967                         // Remove blockquote(s)\r
8968                         if (bq = getBQ(sb)) {\r
8969                                 if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
8970                                         bm = s.getBookmark();\r
8971 \r
8972                                 // Move all elements after the end block into new bq\r
8973                                 if (getBQ(eb)) {\r
8974                                         bq2 = bq.cloneNode(false);\r
8975 \r
8976                                         while (n = eb.nextSibling)\r
8977                                                 bq2.appendChild(n.parentNode.removeChild(n));\r
8978                                 }\r
8979 \r
8980                                 // Add new bq after\r
8981                                 if (bq2)\r
8982                                         dom.insertAfter(bq2, bq);\r
8983 \r
8984                                 // Move all selected blocks after the current bq\r
8985                                 nl = t._getSelectedBlocks(sb, eb);\r
8986                                 for (i = nl.length - 1; i >= 0; i--) {\r
8987                                         dom.insertAfter(nl[i], bq);\r
8988                                 }\r
8989 \r
8990                                 // Empty bq, then remove it\r
8991                                 if (/^\s*$/.test(bq.innerHTML))\r
8992                                         dom.remove(bq, 1); // Keep children so boomark restoration works correctly\r
8993 \r
8994                                 // Empty bq, then remote it\r
8995                                 if (bq2 && /^\s*$/.test(bq2.innerHTML))\r
8996                                         dom.remove(bq2, 1); // Keep children so boomark restoration works correctly\r
8997 \r
8998                                 if (!bm) {\r
8999                                         // Move caret inside empty block element\r
9000                                         if (!isIE) {\r
9001                                                 r = ed.getDoc().createRange();\r
9002                                                 r.setStart(sb, 0);\r
9003                                                 r.setEnd(sb, 0);\r
9004                                                 s.setRng(r);\r
9005                                         } else {\r
9006                                                 s.select(sb);\r
9007                                                 s.collapse(0);\r
9008 \r
9009                                                 // IE misses the empty block some times element so we must move back the caret\r
9010                                                 if (dom.getParent(s.getStart(), dom.isBlock) != sb) {\r
9011                                                         r = s.getRng();\r
9012                                                         r.move('character', -1);\r
9013                                                         r.select();\r
9014                                                 }\r
9015                                         }\r
9016                                 } else\r
9017                                         t.editor.selection.moveToBookmark(bm);\r
9018 \r
9019                                 return;\r
9020                         }\r
9021 \r
9022                         // Since IE can start with a totally empty document we need to add the first bq and paragraph\r
9023                         if (isIE && !sb && !eb) {\r
9024                                 t.editor.getDoc().execCommand('Indent');\r
9025                                 n = getBQ(s.getNode());\r
9026                                 n.style.margin = n.dir = ''; // IE adds margin and dir to bq\r
9027                                 return;\r
9028                         }\r
9029 \r
9030                         if (!sb || !eb)\r
9031                                 return;\r
9032 \r
9033                         // If empty paragraph node then do not use bookmark\r
9034                         if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
9035                                 bm = s.getBookmark();\r
9036 \r
9037                         // Move selected block elements into a bq\r
9038                         each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {\r
9039                                 // Found existing BQ add to this one\r
9040                                 if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
9041                                         bq = e;\r
9042                                         return;\r
9043                                 }\r
9044 \r
9045                                 // No BQ found, create one\r
9046                                 if (!bq) {\r
9047                                         bq = dom.create('blockquote');\r
9048                                         e.parentNode.insertBefore(bq, e);\r
9049                                 }\r
9050 \r
9051                                 // Add children from existing BQ\r
9052                                 if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
9053                                         n = e.firstChild;\r
9054 \r
9055                                         while (n) {\r
9056                                                 bq.appendChild(n.cloneNode(true));\r
9057                                                 n = n.nextSibling;\r
9058                                         }\r
9059 \r
9060                                         dom.remove(e);\r
9061                                         return;\r
9062                                 }\r
9063 \r
9064                                 // Add non BQ element to BQ\r
9065                                 bq.appendChild(dom.remove(e));\r
9066                         });\r
9067 \r
9068                         if (!bm) {\r
9069                                 // Move caret inside empty block element\r
9070                                 if (!isIE) {\r
9071                                         r = ed.getDoc().createRange();\r
9072                                         r.setStart(sb, 0);\r
9073                                         r.setEnd(sb, 0);\r
9074                                         s.setRng(r);\r
9075                                 } else {\r
9076                                         s.select(sb);\r
9077                                         s.collapse(1);\r
9078                                 }\r
9079                         } else\r
9080                                 s.moveToBookmark(bm);\r
9081                 },\r
9082 /*\r
9083                 _mceBlockQuote : function() {\r
9084                         var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;\r
9085 \r
9086                         function findBQ(e) {\r
9087                                 return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
9088                         };\r
9089 \r
9090                         // Remove blockquote(s)\r
9091                         if (findBQ(s.getStart())) {\r
9092                                 each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
9093                                         // Found BQ lets remove it\r
9094                                         if (e.nodeName == 'BLOCKQUOTE')\r
9095                                                 dom.remove(e, 1);\r
9096                                 });\r
9097 \r
9098                                 t.editor.selection.moveToBookmark(b);\r
9099                                 return;\r
9100                         }\r
9101 \r
9102                         each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
9103                                 var n;\r
9104 \r
9105                                 // Found existing BQ add to this one\r
9106                                 if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
9107                                         bq = e;\r
9108                                         return;\r
9109                                 }\r
9110 \r
9111                                 // No BQ found, create one\r
9112                                 if (!bq) {\r
9113                                         bq = dom.create('blockquote');\r
9114                                         e.parentNode.insertBefore(bq, e);\r
9115                                 }\r
9116 \r
9117                                 // Add children from existing BQ\r
9118                                 if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
9119                                         n = e.firstChild;\r
9120 \r
9121                                         while (n) {\r
9122                                                 bq.appendChild(n.cloneNode(true));\r
9123                                                 n = n.nextSibling;\r
9124                                         }\r
9125 \r
9126                                         dom.remove(e);\r
9127 \r
9128                                         return;\r
9129                                 }\r
9130 \r
9131                                 // Add non BQ element to BQ\r
9132                                 bq.appendChild(dom.remove(e));\r
9133                         });\r
9134 \r
9135                         t.editor.selection.moveToBookmark(b);\r
9136                 },\r
9137 */\r
9138                 _getSelectedBlocks : function(st, en) {\r
9139                         var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];\r
9140 \r
9141                         sb = dom.getParent(st || s.getStart(), dom.isBlock);\r
9142                         eb = dom.getParent(en || s.getEnd(), dom.isBlock);\r
9143 \r
9144                         if (sb)\r
9145                                 bl.push(sb);\r
9146 \r
9147                         if (sb && eb && sb != eb) {\r
9148                                 n = sb;\r
9149 \r
9150                                 while ((n = n.nextSibling) && n != eb) {\r
9151                                         if (dom.isBlock(n))\r
9152                                                 bl.push(n);\r
9153                                 }\r
9154                         }\r
9155 \r
9156                         if (eb && sb != eb)\r
9157                                 bl.push(eb);\r
9158 \r
9159                         return bl;\r
9160                 }\r
9161         });\r
9162 })();\r
9163 \r
9164 \r
9165 /* file:jscripts/tiny_mce/classes/UndoManager.js */\r
9166 \r
9167 tinymce.create('tinymce.UndoManager', {\r
9168         index : 0,\r
9169         data : null,\r
9170         typing : 0,\r
9171 \r
9172         UndoManager : function(ed) {\r
9173                 var t = this, Dispatcher = tinymce.util.Dispatcher;\r
9174 \r
9175                 t.editor = ed;\r
9176                 t.data = [];\r
9177                 t.onAdd = new Dispatcher(this);\r
9178                 t.onUndo = new Dispatcher(this);\r
9179                 t.onRedo = new Dispatcher(this);\r
9180         },\r
9181 \r
9182         add : function(l) {\r
9183                 var t = this, i, ed = t.editor, b, s = ed.settings, la;\r
9184 \r
9185                 l = l || {};\r
9186                 l.content = l.content || ed.getContent({format : 'raw', no_events : 1});\r
9187 \r
9188                 // Add undo level if needed\r
9189                 l.content = l.content.replace(/^\s*|\s*$/g, '');\r
9190                 la = t.data[t.index > 0 ? t.index - 1 : 0];\r
9191                 if (!l.initial && la && l.content == la.content)\r
9192                         return null;\r
9193 \r
9194                 // Time to compress\r
9195                 if (s.custom_undo_redo_levels) {\r
9196                         if (t.data.length > s.custom_undo_redo_levels) {\r
9197                                 for (i = 0; i < t.data.length - 1; i++)\r
9198                                         t.data[i] = t.data[i + 1];\r
9199 \r
9200                                 t.data.length--;\r
9201                                 t.index = t.data.length;\r
9202                         }\r
9203                 }\r
9204 \r
9205                 if (s.custom_undo_redo_restore_selection && !l.initial)\r
9206                         l.bookmark = b = l.bookmark || ed.selection.getBookmark();\r
9207 \r
9208                 if (t.index < t.data.length && t.data[t.index].initial)\r
9209                         t.index++;\r
9210 \r
9211                 // Add level\r
9212                 t.data.length = t.index + 1;\r
9213                 t.data[t.index++] = l;\r
9214 \r
9215                 if (l.initial)\r
9216                         t.index = 0;\r
9217 \r
9218                 // Set initial bookmark use first real undo level\r
9219                 if (t.data.length == 2 && t.data[0].initial)\r
9220                         t.data[0].bookmark = b;\r
9221 \r
9222                 t.onAdd.dispatch(t, l);\r
9223                 ed.isNotDirty = 0;\r
9224 \r
9225                 //console.dir(t.data);\r
9226 \r
9227                 return l;\r
9228         },\r
9229 \r
9230         undo : function() {\r
9231                 var t = this, ed = t.editor, l = l, i;\r
9232 \r
9233                 if (t.typing) {\r
9234                         t.add();\r
9235                         t.typing = 0;\r
9236                 }\r
9237 \r
9238                 if (t.index > 0) {\r
9239                         // If undo on last index then take snapshot\r
9240                         if (t.index == t.data.length && t.index > 1) {\r
9241                                 i = t.index;\r
9242                                 t.typing = 0;\r
9243 \r
9244                                 if (!t.add())\r
9245                                         t.index = i;\r
9246 \r
9247                                 --t.index;\r
9248                         }\r
9249 \r
9250                         l = t.data[--t.index];\r
9251                         ed.setContent(l.content, {format : 'raw'});\r
9252                         ed.selection.moveToBookmark(l.bookmark);\r
9253 \r
9254                         t.onUndo.dispatch(t, l);\r
9255                 }\r
9256 \r
9257                 return l;\r
9258         },\r
9259 \r
9260         redo : function() {\r
9261                 var t = this, ed = t.editor, l = null;\r
9262 \r
9263                 if (t.index < t.data.length - 1) {\r
9264                         l = t.data[++t.index];\r
9265                         ed.setContent(l.content, {format : 'raw'});\r
9266                         ed.selection.moveToBookmark(l.bookmark);\r
9267 \r
9268                         t.onRedo.dispatch(t, l);\r
9269                 }\r
9270 \r
9271                 return l;\r
9272         },\r
9273 \r
9274         clear : function() {\r
9275                 var t = this;\r
9276 \r
9277                 t.data = [];\r
9278                 t.index = 0;\r
9279                 t.typing = 0;\r
9280                 t.add({initial : true});\r
9281         },\r
9282 \r
9283         hasUndo : function() {\r
9284                 return this.index != 0 || this.typing;\r
9285         },\r
9286 \r
9287         hasRedo : function() {\r
9288                 return this.index < this.data.length - 1;\r
9289         }\r
9290 \r
9291         });\r
9292 /* file:jscripts/tiny_mce/classes/ForceBlocks.js */\r
9293 \r
9294 (function() {\r
9295         // Shorten names\r
9296         var Event, isIE, isGecko, isOpera, each, extend;\r
9297 \r
9298         Event = tinymce.dom.Event;\r
9299         isIE = tinymce.isIE;\r
9300         isGecko = tinymce.isGecko;\r
9301         isOpera = tinymce.isOpera;\r
9302         each = tinymce.each;\r
9303         extend = tinymce.extend;\r
9304 \r
9305         tinymce.create('tinymce.ForceBlocks', {\r
9306                 ForceBlocks : function(ed) {\r
9307                         var t = this, s = ed.settings, elm;\r
9308 \r
9309                         t.editor = ed;\r
9310                         t.dom = ed.dom;\r
9311                         elm = (s.forced_root_block || 'p').toLowerCase();\r
9312                         s.element = elm.toUpperCase();\r
9313 \r
9314                         ed.onPreInit.add(t.setup, t);\r
9315 \r
9316                         t.reOpera = new RegExp('(\\u00a0|&#160;|&nbsp;)<\/' + elm + '>', 'gi');\r
9317                         t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');\r
9318                         t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');\r
9319                         t.reNbsp2BR2 = new RegExp('<p( )([^>]+)>(&nbsp;|&#160;)<\\\/p>|<p>(&nbsp;|&#160;)<\\\/p>'.replace(/p/g, elm), 'gi');\r
9320                         t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
9321                         t.reTrailBr = new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
9322 \r
9323                         function padd(ed, o) {\r
9324                                 if (isOpera)\r
9325                                         o.content = o.content.replace(t.reOpera, '</' + elm + '>');\r
9326 \r
9327                                 o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0</' + elm + '>');\r
9328 \r
9329                                 if (!isIE && !isOpera && o.set) {\r
9330                                         // Use &nbsp; instead of BR in padded paragraphs\r
9331                                         o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');\r
9332                                         o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');\r
9333                                 } else {\r
9334                                         o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');\r
9335                                         o.content = o.content.replace(t.reTrailBr, '</' + elm + '>');\r
9336                                 }\r
9337                         };\r
9338 \r
9339                         ed.onBeforeSetContent.add(padd);\r
9340                         ed.onPostProcess.add(padd);\r
9341 \r
9342                         if (s.forced_root_block) {\r
9343                                 ed.onInit.add(t.forceRoots, t);\r
9344                                 ed.onSetContent.add(t.forceRoots, t);\r
9345                                 ed.onBeforeGetContent.add(t.forceRoots, t);\r
9346                         }\r
9347                 },\r
9348 \r
9349                 setup : function() {\r
9350                         var t = this, ed = t.editor, s = ed.settings;\r
9351 \r
9352                         // Force root blocks when typing and when getting output\r
9353                         if (s.forced_root_block) {\r
9354                                 ed.onKeyUp.add(t.forceRoots, t);\r
9355                                 ed.onPreProcess.add(t.forceRoots, t);\r
9356                         }\r
9357 \r
9358                         if (s.force_br_newlines) {\r
9359                                 // Force IE to produce BRs on enter\r
9360                                 if (isIE) {\r
9361                                         ed.onKeyPress.add(function(ed, e) {\r
9362                                                 var n, s = ed.selection;\r
9363 \r
9364                                                 if (e.keyCode == 13 && s.getNode().nodeName != 'LI') {\r
9365                                                         s.setContent('<br id="__" /> ', {format : 'raw'});\r
9366                                                         n = ed.dom.get('__');\r
9367                                                         n.removeAttribute('id');\r
9368                                                         s.select(n);\r
9369                                                         s.collapse();\r
9370                                                         return Event.cancel(e);\r
9371                                                 }\r
9372                                         });\r
9373                                 }\r
9374 \r
9375                                 return;\r
9376                         }\r
9377 \r
9378                         if (!isIE && s.force_p_newlines) {\r
9379 /*                              ed.onPreProcess.add(function(ed, o) {\r
9380                                         each(ed.dom.select('br', o.node), function(n) {\r
9381                                                 var p = n.parentNode;\r
9382 \r
9383                                                 // Replace <p><br /></p> with <p>&nbsp;</p>\r
9384                                                 if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n)) {\r
9385                                                         p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n);\r
9386                                                 }\r
9387                                         });\r
9388                                 });*/\r
9389 \r
9390                                 ed.onKeyPress.add(function(ed, e) {\r
9391                                         if (e.keyCode == 13 && !e.shiftKey) {\r
9392                                                 if (!t.insertPara(e))\r
9393                                                         Event.cancel(e);\r
9394                                         }\r
9395                                 });\r
9396 \r
9397                                 if (isGecko) {\r
9398                                         ed.onKeyDown.add(function(ed, e) {\r
9399                                                 if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey)\r
9400                                                         t.backspaceDelete(e, e.keyCode == 8);\r
9401                                         });\r
9402                                 }\r
9403                         }\r
9404 \r
9405                         function ren(rn, na) {\r
9406                                 var ne = ed.dom.create(na);\r
9407 \r
9408                                 each(rn.attributes, function(a) {\r
9409                                         if (a.specified && a.nodeValue)\r
9410                                                 ne.setAttribute(a.nodeName.toLowerCase(), a.nodeValue);\r
9411                                 });\r
9412 \r
9413                                 each(rn.childNodes, function(n) {\r
9414                                         ne.appendChild(n.cloneNode(true));\r
9415                                 });\r
9416 \r
9417                                 rn.parentNode.replaceChild(ne, rn);\r
9418 \r
9419                                 return ne;\r
9420                         };\r
9421 \r
9422                         // Replaces IE:s auto generated paragraphs with the specified element name\r
9423                         if (isIE && s.element != 'P') {\r
9424                                 ed.onKeyPress.add(function(ed, e) {\r
9425                                         t.lastElm = ed.selection.getNode().nodeName;\r
9426                                 });\r
9427 \r
9428                                 ed.onKeyUp.add(function(ed, e) {\r
9429                                         var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();\r
9430 \r
9431                                         if (b.childNodes.length === 1 && n.nodeName == 'P') {\r
9432                                                 n = ren(n, s.element);\r
9433                                                 sel.select(n);\r
9434                                                 sel.collapse();\r
9435                                                 ed.nodeChanged();\r
9436                                         } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {\r
9437                                                 bl = ed.dom.getParent(n, 'P');\r
9438 \r
9439                                                 if (bl) {\r
9440                                                         ren(bl, s.element);\r
9441                                                         ed.nodeChanged();\r
9442                                                 }\r
9443                                         }\r
9444                                 });\r
9445                         }\r
9446                 },\r
9447 \r
9448                 find : function(n, t, s) {\r
9449                         var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1;\r
9450 \r
9451                         while (n = w.nextNode()) {\r
9452                                 c++;\r
9453 \r
9454                                 // Index by node\r
9455                                 if (t == 0 && n == s)\r
9456                                         return c;\r
9457 \r
9458                                 // Node by index\r
9459                                 if (t == 1 && c == s)\r
9460                                         return n;\r
9461                         }\r
9462 \r
9463                         return -1;\r
9464                 },\r
9465 \r
9466                 forceRoots : function(ed, e) {\r
9467                         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
9468                         var nx, bl, bp, sp, le, nl = b.childNodes, i;\r
9469 \r
9470                         // Fix for bug #1863847\r
9471                         if (e && e.keyCode == 13)\r
9472                                 return true;\r
9473 \r
9474                         // Wrap non blocks into blocks\r
9475                         for (i = nl.length - 1; i >= 0; i--) {\r
9476                                 nx = nl[i];\r
9477 \r
9478                                 // Is text or non block element\r
9479                                 if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) {\r
9480                                         if (!bl) {\r
9481                                                 // Create new block but ignore whitespace\r
9482                                                 if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {\r
9483                                                         // Store selection\r
9484                                                         if (si == -2 && r) {\r
9485                                                                 if (!isIE) {\r
9486                                                                         so = r.startOffset;\r
9487                                                                         eo = r.endOffset;\r
9488                                                                         si = t.find(b, 0, r.startContainer);\r
9489                                                                         ei = t.find(b, 0, r.endContainer);\r
9490                                                                 } else {\r
9491                                                                         tr = d.body.createTextRange();\r
9492                                                                         tr.moveToElementText(b);\r
9493                                                                         tr.collapse(1);\r
9494                                                                         bp = tr.move('character', c) * -1;\r
9495 \r
9496                                                                         tr = r.duplicate();\r
9497                                                                         tr.collapse(1);\r
9498                                                                         sp = tr.move('character', c) * -1;\r
9499 \r
9500                                                                         tr = r.duplicate();\r
9501                                                                         tr.collapse(0);\r
9502                                                                         le = (tr.move('character', c) * -1) - sp;\r
9503 \r
9504                                                                         si = sp - bp;\r
9505                                                                         ei = le;\r
9506                                                                 }\r
9507                                                         }\r
9508 \r
9509                                                         bl = ed.dom.create(ed.settings.forced_root_block);\r
9510                                                         bl.appendChild(nx.cloneNode(1));\r
9511                                                         nx.parentNode.replaceChild(bl, nx);\r
9512                                                 }\r
9513                                         } else {\r
9514                                                 if (bl.hasChildNodes())\r
9515                                                         bl.insertBefore(nx, bl.firstChild);\r
9516                                                 else\r
9517                                                         bl.appendChild(nx);\r
9518                                         }\r
9519                                 } else\r
9520                                         bl = null; // Time to create new block\r
9521                         }\r
9522 \r
9523                         // Restore selection\r
9524                         if (si != -2) {\r
9525                                 if (!isIE) {\r
9526                                         bl = d.getElementsByTagName(ed.settings.element)[0];\r
9527                                         r = d.createRange();\r
9528 \r
9529                                         // Select last location or generated block\r
9530                                         if (si != -1)\r
9531                                                 r.setStart(t.find(b, 1, si), so);\r
9532                                         else\r
9533                                                 r.setStart(bl, 0);\r
9534 \r
9535                                         // Select last location or generated block\r
9536                                         if (ei != -1)\r
9537                                                 r.setEnd(t.find(b, 1, ei), eo);\r
9538                                         else\r
9539                                                 r.setEnd(bl, 0);\r
9540 \r
9541                                         if (s) {\r
9542                                                 s.removeAllRanges();\r
9543                                                 s.addRange(r);\r
9544                                         }\r
9545                                 } else {\r
9546                                         try {\r
9547                                                 r = s.createRange();\r
9548                                                 r.moveToElementText(b);\r
9549                                                 r.collapse(1);\r
9550                                                 r.moveStart('character', si);\r
9551                                                 r.moveEnd('character', ei);\r
9552                                                 r.select();\r
9553                                         } catch (ex) {\r
9554                                                 // Ignore\r
9555                                         }\r
9556                                 }\r
9557                         }\r
9558                 },\r
9559 \r
9560                 getParentBlock : function(n) {\r
9561                         var d = this.dom;\r
9562 \r
9563                         return d.getParent(n, d.isBlock);\r
9564                 },\r
9565 \r
9566                 insertPara : function(e) {\r
9567                         var t = this, ed = t.editor, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;\r
9568                         var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = ed.dom.getViewPort(ed.getWin()), y, ch;\r
9569 \r
9570                         function isEmpty(n) {\r
9571                                 n = n.innerHTML;\r
9572                                 n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars\r
9573                                 n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
9574 \r
9575                                 return n.replace(/[ \t\r\n]+/g, '') == '';\r
9576                         };\r
9577 \r
9578                         // If root blocks are forced then use Operas default behavior since it's really good\r
9579 // Removed due to bug: #1853816\r
9580 //                      if (se.forced_root_block && isOpera)\r
9581 //                              return true;\r
9582 \r
9583                         // Setup before range\r
9584                         rb = d.createRange();\r
9585 \r
9586                         // If is before the first block element and in body, then move it into first block element\r
9587                         rb.setStart(s.anchorNode, s.anchorOffset);\r
9588                         rb.collapse(true);\r
9589 \r
9590                         // Setup after range\r
9591                         ra = d.createRange();\r
9592 \r
9593                         // If is before the first block element and in body, then move it into first block element\r
9594                         ra.setStart(s.focusNode, s.focusOffset);\r
9595                         ra.collapse(true);\r
9596 \r
9597                         // Setup start/end points\r
9598                         dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0;\r
9599                         sn = dir ? s.anchorNode : s.focusNode;\r
9600                         so = dir ? s.anchorOffset : s.focusOffset;\r
9601                         en = dir ? s.focusNode : s.anchorNode;\r
9602                         eo = dir ? s.focusOffset : s.anchorOffset;\r
9603 \r
9604                         // If the caret is in an invalid location in FF we need to move it into the first block\r
9605                         if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) {\r
9606                                 sn = en = sn.firstChild;\r
9607                                 so = eo = 0;\r
9608                                 rb = d.createRange();\r
9609                                 rb.setStart(sn, 0);\r
9610                                 ra = d.createRange();\r
9611                                 ra.setStart(en, 0);\r
9612                         }\r
9613 \r
9614                         // Never use body as start or end node\r
9615                         sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes\r
9616                         sn = sn.nodeName == "BODY" ? sn.firstChild : sn;\r
9617                         en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes\r
9618                         en = en.nodeName == "BODY" ? en.firstChild : en;\r
9619 \r
9620                         // Get start and end blocks\r
9621                         sb = t.getParentBlock(sn);\r
9622                         eb = t.getParentBlock(en);\r
9623                         bn = sb ? sb.nodeName : se.element; // Get block name to create\r
9624 \r
9625                         // Return inside list use default browser behavior\r
9626                         if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))\r
9627                                 return true;\r
9628 \r
9629                         // If caption or absolute layers then always generate new blocks within\r
9630                         if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {\r
9631                                 bn = se.element;\r
9632                                 sb = null;\r
9633                         }\r
9634 \r
9635                         // If caption or absolute layers then always generate new blocks within\r
9636                         if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {\r
9637                                 bn = se.element;\r
9638                                 eb = null;\r
9639                         }\r
9640 \r
9641                         // Use P instead\r
9642                         if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {\r
9643                                 bn = se.element;\r
9644                                 sb = eb = null;\r
9645                         }\r
9646 \r
9647                         // Setup new before and after blocks\r
9648                         bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn);\r
9649                         aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn);\r
9650 \r
9651                         // Remove id from after clone\r
9652                         aft.removeAttribute('id');\r
9653 \r
9654                         // Is header and cursor is at the end, then force paragraph under\r
9655                         if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)\r
9656                                 aft = ed.dom.create(se.element);\r
9657 \r
9658                         // Find start chop node\r
9659                         n = sc = sn;\r
9660                         do {\r
9661                                 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))\r
9662                                         break;\r
9663 \r
9664                                 sc = n;\r
9665                         } while ((n = n.previousSibling ? n.previousSibling : n.parentNode));\r
9666 \r
9667                         // Find end chop node\r
9668                         n = ec = en;\r
9669                         do {\r
9670                                 if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))\r
9671                                         break;\r
9672 \r
9673                                 ec = n;\r
9674                         } while ((n = n.nextSibling ? n.nextSibling : n.parentNode));\r
9675 \r
9676                         // Place first chop part into before block element\r
9677                         if (sc.nodeName == bn)\r
9678                                 rb.setStart(sc, 0);\r
9679                         else\r
9680                                 rb.setStartBefore(sc);\r
9681 \r
9682                         rb.setEnd(sn, so);\r
9683                         bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari\r
9684 \r
9685                         // Place secnd chop part within new block element\r
9686                         try {\r
9687                                 ra.setEndAfter(ec);\r
9688                         } catch(ex) {\r
9689                                 //console.debug(s.focusNode, s.focusOffset);\r
9690                         }\r
9691 \r
9692                         ra.setStart(en, eo);\r
9693                         aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari\r
9694 \r
9695                         // Create range around everything\r
9696                         r = d.createRange();\r
9697                         if (!sc.previousSibling && sc.parentNode.nodeName == bn) {\r
9698                                 r.setStartBefore(sc.parentNode);\r
9699                         } else {\r
9700                                 if (rb.startContainer.nodeName == bn && rb.startOffset == 0)\r
9701                                         r.setStartBefore(rb.startContainer);\r
9702                                 else\r
9703                                         r.setStart(rb.startContainer, rb.startOffset);\r
9704                         }\r
9705 \r
9706                         if (!ec.nextSibling && ec.parentNode.nodeName == bn)\r
9707                                 r.setEndAfter(ec.parentNode);\r
9708                         else\r
9709                                 r.setEnd(ra.endContainer, ra.endOffset);\r
9710 \r
9711                         // Delete and replace it with new block elements\r
9712                         r.deleteContents();\r
9713 \r
9714                         if (isOpera)\r
9715                                 ed.getWin().scrollTo(0, vp.y);\r
9716 \r
9717                         // Never wrap blocks in blocks\r
9718                         if (bef.firstChild && bef.firstChild.nodeName == bn)\r
9719                                 bef.innerHTML = bef.firstChild.innerHTML;\r
9720 \r
9721                         if (aft.firstChild && aft.firstChild.nodeName == bn)\r
9722                                 aft.innerHTML = aft.firstChild.innerHTML;\r
9723 \r
9724                         // Padd empty blocks\r
9725                         if (isEmpty(bef))\r
9726                                 bef.innerHTML = '<br />';\r
9727 \r
9728                         if (isEmpty(aft))\r
9729                                 aft.innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there\r
9730 \r
9731                         // Opera needs this one backwards\r
9732                         if (isOpera) {\r
9733                                 r.insertNode(bef);\r
9734                                 r.insertNode(aft);\r
9735                         } else {\r
9736                                 r.insertNode(aft);\r
9737                                 r.insertNode(bef);\r
9738                         }\r
9739 \r
9740                         // Normalize\r
9741                         aft.normalize();\r
9742                         bef.normalize();\r
9743 \r
9744                         // Move cursor and scroll into view\r
9745                         r = d.createRange();\r
9746                         r.selectNodeContents(aft);\r
9747                         r.collapse(1);\r
9748                         s.removeAllRanges();\r
9749                         s.addRange(r);\r
9750 \r
9751                         // 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
9752                         y = ed.dom.getPos(aft).y;\r
9753                         ch = aft.clientHeight;\r
9754 \r
9755                         // Is element within viewport\r
9756                         if (y < vp.y || y + ch > vp.y + vp.h) {\r
9757                                 ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + ch);\r
9758                                 //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
9759                         }\r
9760 \r
9761                         return false;\r
9762                 },\r
9763 \r
9764                 backspaceDelete : function(e, bs) {\r
9765                         var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;\r
9766 \r
9767                         // The caret sometimes gets stuck in Gecko if you delete empty paragraphs\r
9768                         // This workaround removes the element by hand and moves the caret to the previous element\r
9769                         if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) {\r
9770                                 if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) {\r
9771                                         // Find previous block element\r
9772                                         n = sc;\r
9773                                         while ((n = n.previousSibling) && !ed.dom.isBlock(n)) ;\r
9774 \r
9775                                         if (n) {\r
9776                                                 if (sc != b.firstChild) {\r
9777                                                         // Find last text node\r
9778                                                         w = ed.dom.doc.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
9779                                                         while (tn = w.nextNode())\r
9780                                                                 n = tn;\r
9781 \r
9782                                                         // Place caret at the end of last text node\r
9783                                                         r = ed.getDoc().createRange();\r
9784                                                         r.setStart(n, n.nodeValue ? n.nodeValue.length : 0);\r
9785                                                         r.setEnd(n, n.nodeValue ? n.nodeValue.length : 0);\r
9786                                                         se.setRng(r);\r
9787 \r
9788                                                         // Remove the target container\r
9789                                                         ed.dom.remove(sc);\r
9790                                                 }\r
9791 \r
9792                                                 return Event.cancel(e);\r
9793                                         }\r
9794                                 }\r
9795                         }\r
9796 \r
9797                         // Gecko generates BR elements here and there, we don't like those so lets remove them\r
9798                         function handler(e) {\r
9799                                 e = e.target;\r
9800 \r
9801                                 // A new BR was created in a block element, remove it\r
9802                                 if (e && e.parentNode && e.nodeName == 'BR' && (n = t.getParentBlock(e))) {\r
9803                                         Event.remove(b, 'DOMNodeInserted', handler);\r
9804 \r
9805                                         // Only remove BR elements that got inserted in the middle of the text\r
9806                                         if (e.previousSibling || e.nextSibling)\r
9807                                                 ed.dom.remove(e);\r
9808                                 }\r
9809                         };\r
9810 \r
9811                         // Listen for new nodes\r
9812                         Event._add(b, 'DOMNodeInserted', handler);\r
9813 \r
9814                         // Remove listener\r
9815                         window.setTimeout(function() {\r
9816                                 Event._remove(b, 'DOMNodeInserted', handler);\r
9817                         }, 1);\r
9818                 }\r
9819         });\r
9820 })();\r
9821 \r
9822 /* file:jscripts/tiny_mce/classes/ControlManager.js */\r
9823 \r
9824 (function() {\r
9825         // Shorten names\r
9826         var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;\r
9827 \r
9828         tinymce.create('tinymce.ControlManager', {\r
9829                 ControlManager : function(ed, s) {\r
9830                         var t = this, i;\r
9831 \r
9832                         s = s || {};\r
9833                         t.editor = ed;\r
9834                         t.controls = {};\r
9835                         t.onAdd = new tinymce.util.Dispatcher(t);\r
9836                         t.onPostRender = new tinymce.util.Dispatcher(t);\r
9837                         t.prefix = s.prefix || ed.id + '_';\r
9838                         t._cls = {};\r
9839 \r
9840                         t.onPostRender.add(function() {\r
9841                                 each(t.controls, function(c) {\r
9842                                         c.postRender();\r
9843                                 });\r
9844                         });\r
9845                 },\r
9846 \r
9847                 get : function(id) {\r
9848                         return this.controls[this.prefix + id] || this.controls[id];\r
9849                 },\r
9850 \r
9851                 setActive : function(id, s) {\r
9852                         var c = null;\r
9853 \r
9854                         if (c = this.get(id))\r
9855                                 c.setActive(s);\r
9856 \r
9857                         return c;\r
9858                 },\r
9859 \r
9860                 setDisabled : function(id, s) {\r
9861                         var c = null;\r
9862 \r
9863                         if (c = this.get(id))\r
9864                                 c.setDisabled(s);\r
9865 \r
9866                         return c;\r
9867                 },\r
9868 \r
9869                 add : function(c) {\r
9870                         var t = this;\r
9871 \r
9872                         if (c) {\r
9873                                 t.controls[c.id] = c;\r
9874                                 t.onAdd.dispatch(c, t);\r
9875                         }\r
9876 \r
9877                         return c;\r
9878                 },\r
9879 \r
9880                 createControl : function(n) {\r
9881                         var c, t = this, ed = t.editor;\r
9882 \r
9883                         each(ed.plugins, function(p) {\r
9884                                 if (p.createControl) {\r
9885                                         c = p.createControl(n, t);\r
9886 \r
9887                                         if (c)\r
9888                                                 return false;\r
9889                                 }\r
9890                         });\r
9891 \r
9892                         switch (n) {\r
9893                                 case "|":\r
9894                                 case "separator":\r
9895                                         return t.createSeparator();\r
9896                         }\r
9897 \r
9898                         if (!c && ed.buttons && (c = ed.buttons[n]))\r
9899                                 return t.createButton(n, c);\r
9900 \r
9901                         return t.add(c);\r
9902                 },\r
9903 \r
9904                 createDropMenu : function(id, s, cc) {\r
9905                         var t = this, ed = t.editor, c, bm, v, cls;\r
9906 \r
9907                         s = extend({\r
9908                                 'class' : 'mceDropDown',\r
9909                                 constrain : ed.settings.constrain_menus\r
9910                         }, s);\r
9911 \r
9912                         s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';\r
9913                         if (v = ed.getParam('skin_variant'))\r
9914                                 s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);\r
9915 \r
9916                         id = t.prefix + id;\r
9917                         cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;\r
9918                         c = t.controls[id] = new cls(id, s);\r
9919                         c.onAddItem.add(function(c, o) {\r
9920                                 var s = o.settings;\r
9921 \r
9922                                 s.title = ed.getLang(s.title, s.title);\r
9923 \r
9924                                 if (!s.onclick) {\r
9925                                         s.onclick = function(v) {\r
9926                                                 ed.execCommand(s.cmd, s.ui || false, s.value);\r
9927                                         };\r
9928                                 }\r
9929                         });\r
9930 \r
9931                         ed.onRemove.add(function() {\r
9932                                 c.destroy();\r
9933                         });\r
9934 \r
9935                         // Fix for bug #1897785, #1898007\r
9936                         if (tinymce.isIE) {\r
9937                                 c.onShowMenu.add(function() {\r
9938                                         var s = ed.selection, n = s.getNode();\r
9939 \r
9940                                         if (n.nodeName == 'IMG')\r
9941                                                 bm = s.getBookmark();\r
9942                                         else\r
9943                                                 bm = 0;\r
9944                                 });\r
9945 \r
9946                                 c.onHideMenu.add(function() {\r
9947                                         if (bm)\r
9948                                                 ed.selection.moveToBookmark(bm);\r
9949                                 });\r
9950                         }\r
9951 \r
9952                         return t.add(c);\r
9953                 },\r
9954 \r
9955                 createListBox : function(id, s, cc) {\r
9956                         var t = this, ed = t.editor, cmd, c, cls;\r
9957 \r
9958                         if (t.get(id))\r
9959                                 return null;\r
9960 \r
9961                         s.title = ed.translate(s.title);\r
9962                         s.scope = s.scope || ed;\r
9963 \r
9964                         if (!s.onselect) {\r
9965                                 s.onselect = function(v) {\r
9966                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
9967                                 };\r
9968                         }\r
9969 \r
9970                         s = extend({\r
9971                                 title : s.title,\r
9972                                 'class' : 'mce_' + id,\r
9973                                 scope : s.scope,\r
9974                                 control_manager : t\r
9975                         }, s);\r
9976 \r
9977                         id = t.prefix + id;\r
9978 \r
9979                         if (ed.settings.use_native_selects)\r
9980                                 c = new tinymce.ui.NativeListBox(id, s);\r
9981                         else {\r
9982                                 cls = cc || t._cls.listbox || tinymce.ui.ListBox;\r
9983                                 c = new cls(id, s);\r
9984                         }\r
9985 \r
9986                         t.controls[id] = c;\r
9987 \r
9988                         // Fix focus problem in Safari\r
9989                         if (tinymce.isWebKit) {\r
9990                                 c.onPostRender.add(function(c, n) {\r
9991                                         // Store bookmark on mousedown\r
9992                                         Event.add(n, 'mousedown', function() {\r
9993                                                 ed.bookmark = ed.selection.getBookmark('simple');\r
9994                                         });\r
9995 \r
9996                                         // Restore on focus, since it might be lost\r
9997                                         Event.add(n, 'focus', function() {\r
9998                                                 ed.selection.moveToBookmark(ed.bookmark);\r
9999                                                 ed.bookmark = null;\r
10000                                         });\r
10001                                 });\r
10002                         }\r
10003 \r
10004                         if (c.hideMenu)\r
10005                                 ed.onMouseDown.add(c.hideMenu, c);\r
10006 \r
10007                         return t.add(c);\r
10008                 },\r
10009 \r
10010                 createButton : function(id, s, cc) {\r
10011                         var t = this, ed = t.editor, o, c, cls;\r
10012 \r
10013                         if (t.get(id))\r
10014                                 return null;\r
10015 \r
10016                         s.title = ed.translate(s.title);\r
10017                         s.scope = s.scope || ed;\r
10018 \r
10019                         if (!s.onclick && !s.menu_button) {\r
10020                                 s.onclick = function() {\r
10021                                         ed.execCommand(s.cmd, s.ui || false, s.value);\r
10022                                 };\r
10023                         }\r
10024 \r
10025                         s = extend({\r
10026                                 title : s.title,\r
10027                                 'class' : 'mce_' + id,\r
10028                                 unavailable_prefix : ed.getLang('unavailable', ''),\r
10029                                 scope : s.scope,\r
10030                                 control_manager : t\r
10031                         }, s);\r
10032 \r
10033                         id = t.prefix + id;\r
10034 \r
10035                         if (s.menu_button) {\r
10036                                 cls = cc || t._cls.menubutton || tinymce.ui.MenuButton;\r
10037                                 c = new cls(id, s);\r
10038                                 ed.onMouseDown.add(c.hideMenu, c);\r
10039                         } else {\r
10040                                 cls = t._cls.button || tinymce.ui.Button;\r
10041                                 c = new cls(id, s);\r
10042                         }\r
10043 \r
10044                         return t.add(c);\r
10045                 },\r
10046 \r
10047                 createMenuButton : function(id, s) {\r
10048                         s = s || {};\r
10049                         s.menu_button = 1;\r
10050 \r
10051                         return this.createButton(id, s);\r
10052                 },\r
10053 \r
10054                 createSplitButton : function(id, s, cc) {\r
10055                         var t = this, ed = t.editor, cmd, c, cls;\r
10056 \r
10057                         if (t.get(id))\r
10058                                 return null;\r
10059 \r
10060                         s.title = ed.translate(s.title);\r
10061                         s.scope = s.scope || ed;\r
10062 \r
10063                         if (!s.onclick) {\r
10064                                 s.onclick = function(v) {\r
10065                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10066                                 };\r
10067                         }\r
10068 \r
10069                         if (!s.onselect) {\r
10070                                 s.onselect = function(v) {\r
10071                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10072                                 };\r
10073                         }\r
10074 \r
10075                         s = extend({\r
10076                                 title : s.title,\r
10077                                 'class' : 'mce_' + id,\r
10078                                 scope : s.scope,\r
10079                                 control_manager : t\r
10080                         }, s);\r
10081 \r
10082                         id = t.prefix + id;\r
10083                         cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton;\r
10084                         c = t.add(new cls(id, s));\r
10085                         ed.onMouseDown.add(c.hideMenu, c);\r
10086 \r
10087                         return c;\r
10088                 },\r
10089 \r
10090                 createColorSplitButton : function(id, s, cc) {\r
10091                         var t = this, ed = t.editor, cmd, c, cls;\r
10092 \r
10093                         if (t.get(id))\r
10094                                 return null;\r
10095 \r
10096                         s.title = ed.translate(s.title);\r
10097                         s.scope = s.scope || ed;\r
10098 \r
10099                         if (!s.onclick) {\r
10100                                 s.onclick = function(v) {\r
10101                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10102                                 };\r
10103                         }\r
10104 \r
10105                         if (!s.onselect) {\r
10106                                 s.onselect = function(v) {\r
10107                                         ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
10108                                 };\r
10109                         }\r
10110 \r
10111                         s = extend({\r
10112                                 title : s.title,\r
10113                                 'class' : 'mce_' + id,\r
10114                                 'menu_class' : ed.getParam('skin') + 'Skin',\r
10115                                 scope : s.scope,\r
10116                                 more_colors_title : ed.getLang('more_colors')\r
10117                         }, s);\r
10118 \r
10119                         id = t.prefix + id;\r
10120                         cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton;\r
10121                         c = new cls(id, s);\r
10122                         ed.onMouseDown.add(c.hideMenu, c);\r
10123 \r
10124                         // Remove the menu element when the editor is removed\r
10125                         ed.onRemove.add(function() {\r
10126                                 c.destroy();\r
10127                         });\r
10128 \r
10129                         return t.add(c);\r
10130                 },\r
10131 \r
10132                 createToolbar : function(id, s, cc) {\r
10133                         var c, t = this, cls;\r
10134 \r
10135                         id = t.prefix + id;\r
10136                         cls = cc || t._cls.toolbar || tinymce.ui.Toolbar;\r
10137                         c = new cls(id, s);\r
10138 \r
10139                         if (t.get(id))\r
10140                                 return null;\r
10141 \r
10142                         return t.add(c);\r
10143                 },\r
10144 \r
10145                 createSeparator : function(cc) {\r
10146                         var cls = cc || this._cls.separator || tinymce.ui.Separator;\r
10147 \r
10148                         return new cls();\r
10149                 },\r
10150 \r
10151                 setControlType : function(n, c) {\r
10152                         return this._cls[n.toLowerCase()] = c;\r
10153                 },\r
10154 \r
10155                 destroy : function() {\r
10156                         each(this.controls, function(c) {\r
10157                                 c.destroy();\r
10158                         });\r
10159 \r
10160                         this.controls = null;\r
10161                 }\r
10162 \r
10163                 });\r
10164 })();\r
10165 \r
10166 /* file:jscripts/tiny_mce/classes/WindowManager.js */\r
10167 \r
10168 (function() {\r
10169         var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;\r
10170 \r
10171         tinymce.create('tinymce.WindowManager', {\r
10172                 WindowManager : function(ed) {\r
10173                         var t = this;\r
10174 \r
10175                         t.editor = ed;\r
10176                         t.onOpen = new Dispatcher(t);\r
10177                         t.onClose = new Dispatcher(t);\r
10178                         t.params = {};\r
10179                         t.features = {};\r
10180                 },\r
10181 \r
10182                 open : function(s, p) {\r
10183                         var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort(), u;\r
10184 \r
10185                         // Default some options\r
10186                         s = s || {};\r
10187                         p = p || {};\r
10188                         sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window\r
10189                         sh = isOpera ? vp.h : screen.height;\r
10190                         s.name = s.name || 'mc_' + new Date().getTime();\r
10191                         s.width = parseInt(s.width || 320);\r
10192                         s.height = parseInt(s.height || 240);\r
10193                         s.resizable = true;\r
10194                         s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0);\r
10195                         s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0);\r
10196                         p.inline = false;\r
10197                         p.mce_width = s.width;\r
10198                         p.mce_height = s.height;\r
10199                         p.mce_auto_focus = s.auto_focus;\r
10200 \r
10201                         if (mo) {\r
10202                                 if (isIE) {\r
10203                                         s.center = true;\r
10204                                         s.help = false;\r
10205                                         s.dialogWidth = s.width + 'px';\r
10206                                         s.dialogHeight = s.height + 'px';\r
10207                                         s.scroll = s.scrollbars || false;\r
10208                                 } else\r
10209                                         s.modal = s.alwaysRaised = s.dialog = s.centerscreen = s.dependent = true;\r
10210                         }\r
10211 \r
10212                         // Build features string\r
10213                         each(s, function(v, k) {\r
10214                                 if (tinymce.is(v, 'boolean'))\r
10215                                         v = v ? 'yes' : 'no';\r
10216 \r
10217                                 if (!/^(name|url)$/.test(k)) {\r
10218                                         if (isIE && mo)\r
10219                                                 f += (f ? ';' : '') + k + ':' + v;\r
10220                                         else\r
10221                                                 f += (f ? ',' : '') + k + '=' + v;\r
10222                                 }\r
10223                         });\r
10224 \r
10225                         t.features = s;\r
10226                         t.params = p;\r
10227                         t.onOpen.dispatch(t, s, p);\r
10228 \r
10229                         u = s.url || s.file;\r
10230                         if (tinymce.relaxedDomain)\r
10231                                 u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;\r
10232 \r
10233                         try {\r
10234                                 if (isIE && mo) {\r
10235                                         w = 1;\r
10236                                         window.showModalDialog(s.url || s.file, window, f);\r
10237                                 } else\r
10238                                         w = window.open(u, s.name, f);\r
10239                         } catch (ex) {\r
10240                                 // Ignore\r
10241                         }\r
10242 \r
10243                         if (!w)\r
10244                                 alert(t.editor.getLang('popup_blocked'));\r
10245                 },\r
10246 \r
10247                 close : function(w) {\r
10248                         w.close();\r
10249                         this.onClose.dispatch(this);\r
10250                 },\r
10251 \r
10252                 createInstance : function(cl, a, b, c, d, e) {\r
10253                         var f = tinymce.resolve(cl);\r
10254 \r
10255                         return new f(a, b, c, d, e);\r
10256                 },\r
10257 \r
10258                 confirm : function(t, cb, s) {\r
10259                         cb.call(s || this, confirm(this._decode(this.editor.getLang(t, t))));\r
10260                 },\r
10261 \r
10262                 alert : function(tx, cb, s) {\r
10263                         var t = this;\r
10264         \r
10265                         alert(t._decode(t.editor.getLang(tx, tx)));\r
10266 \r
10267                         if (cb)\r
10268                                 cb.call(s || t);\r
10269                 },\r
10270 \r
10271                 // Internal functions\r
10272 \r
10273                 _decode : function(s) {\r
10274                         return tinymce.DOM.decode(s).replace(/\\n/g, '\n');\r
10275                 }\r
10276 \r
10277                 });\r
10278 }());