]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/tiny_mce/classes/tinymce.js
Release 6.2.2
[Github/sugarcrm.git] / include / javascript / tiny_mce / classes / tinymce.js
1 /**
2  * tinymce.js
3  *
4  * Copyright 2009, Moxiecode Systems AB
5  * Released under LGPL License.
6  *
7  * License: http://tinymce.moxiecode.com/license
8  * Contributing: http://tinymce.moxiecode.com/contributing
9  */
10
11 (function(win) {
12         var whiteSpaceRe = /^\s*|\s*$/g,
13                 undefined, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
14
15         /**
16          * Core namespace with core functionality for the TinyMCE API all sub classes will be added to this namespace/object.
17          *
18          * @static
19          * @class tinymce
20          * @example
21          * // Using each method
22          * tinymce.each([1, 2, 3], function(v, i) {
23          *   console.log(i + '=' + v);
24          * });
25          *
26          * // Checking for a specific browser
27          * if (tinymce.isIE)
28          *   console.log("IE");
29          */
30         var tinymce = {
31                 /**
32                  * Major version of TinyMCE build.
33                  *
34                  * @property majorVersion
35                  * @type String
36                  */
37                 majorVersion : '@@tinymce_major_version@@',
38
39                 /**
40                  * Major version of TinyMCE build.
41                  *
42                  * @property minorVersion
43                  * @type String
44                  */
45                 minorVersion : '@@tinymce_minor_version@@',
46
47                 /**
48                  * Release date of TinyMCE build.
49                  *
50                  * @property releaseDate
51                  * @type String
52                  */
53                 releaseDate : '@@tinymce_release_date@@',
54
55                 /**
56                  * Initializes the TinyMCE global namespace this will setup browser detection and figure out where TinyMCE is running from.
57                  */
58                 _init : function() {
59                         var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
60
61                         /**
62                          * Constant that is true if the browser is Opera.
63                          *
64                          * @property isOpera
65                          * @type Boolean
66                          * @final
67                          */
68                         t.isOpera = win.opera && opera.buildNumber;
69
70                         /**
71                          * Constant that is true if the browser is WebKit (Safari/Chrome).
72                          *
73                          * @property isWebKit
74                          * @type Boolean
75                          * @final
76                          */
77                         t.isWebKit = /WebKit/.test(ua);
78
79                         /**
80                          * Constant that is true if the browser is IE.
81                          *
82                          * @property isIE
83                          * @type Boolean
84                          * @final
85                          */
86                         t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
87
88                         /**
89                          * Constant that is true if the browser is IE 6 or older.
90                          *
91                          * @property isIE6
92                          * @type Boolean
93                          * @final
94                          */
95                         t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
96
97                         /**
98                          * Constant that is true if the browser is Gecko.
99                          *
100                          * @property isGecko
101                          * @type Boolean
102                          * @final
103                          */
104                         t.isGecko = !t.isWebKit && /Gecko/.test(ua);
105
106                         /**
107                          * Constant that is true if the os is Mac OS.
108                          *
109                          * @property isMac
110                          * @type Boolean
111                          * @final
112                          */
113                         t.isMac = ua.indexOf('Mac') != -1;
114
115                         /**
116                          * Constant that is true if the runtime is Adobe Air.
117                          *
118                          * @property isAir
119                          * @type Boolean
120                          * @final
121                          */
122                         t.isAir = /adobeair/i.test(ua);
123
124                         /**
125                          * Constant that tells if the current browser is an iPhone or iPad.
126                          *
127                          * @property isIDevice
128                          * @type Boolean
129                          * @final
130                          */
131                         t.isIDevice = /(iPad|iPhone)/.test(ua);
132
133                         // TinyMCE .NET webcontrol might be setting the values for TinyMCE
134                         if (win.tinyMCEPreInit) {
135                                 t.suffix = tinyMCEPreInit.suffix;
136                                 t.baseURL = tinyMCEPreInit.base;
137                                 t.query = tinyMCEPreInit.query;
138                                 return;
139                         }
140
141                         // Get suffix and base
142                         t.suffix = '';
143
144                         // If base element found, add that infront of baseURL
145                         nl = d.getElementsByTagName('base');
146                         for (i=0; i<nl.length; i++) {
147                                 if (v = nl[i].href) {
148                                         // Host only value like http://site.com or http://site.com:8008
149                                         if (/^https?:\/\/[^\/]+$/.test(v))
150                                                 v += '/';
151
152                                         base = v ? v.match(/.*\//)[0] : ''; // Get only directory
153                                 }
154                         }
155
156                         function getBase(n) {
157                                 if (n.src && /tiny_mce(|_gzip|_jquery|_prototype|_full)(_dev|_src)?.js/.test(n.src)) {
158                                         if (/_(src|dev)\.js/g.test(n.src))
159                                                 t.suffix = '_src';
160
161                                         if ((p = n.src.indexOf('?')) != -1)
162                                                 t.query = n.src.substring(p + 1);
163
164                                         t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
165
166                                         // If path to script is relative and a base href was found add that one infront
167                                         // the src property will always be an absolute one on non IE browsers and IE 8
168                                         // so this logic will basically only be executed on older IE versions
169                                         if (base && t.baseURL.indexOf('://') == -1 && t.baseURL.indexOf('/') !== 0)
170                                                 t.baseURL = base + t.baseURL;
171
172                                         return t.baseURL;
173                                 }
174
175                                 return null;
176                         };
177
178                         // Check document
179                         nl = d.getElementsByTagName('script');
180                         for (i=0; i<nl.length; i++) {
181                                 if (getBase(nl[i]))
182                                         return;
183                         }
184
185                         // Check head
186                         n = d.getElementsByTagName('head')[0];
187                         if (n) {
188                                 nl = n.getElementsByTagName('script');
189                                 for (i=0; i<nl.length; i++) {
190                                         if (getBase(nl[i]))
191                                                 return;
192                                 }
193                         }
194
195                         return;
196                 },
197
198                 /**
199                  * Checks if a object is of a specific type for example an array.
200                  *
201                  * @method is
202                  * @param {Object} o Object to check type of.
203                  * @param {string} t Optional type to check for.
204                  * @return {Boolean} true/false if the object is of the specified type.
205                  */
206                 is : function(o, t) {
207                         if (!t)
208                                 return o !== undefined;
209
210                         if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
211                                 return true;
212
213                         return typeof(o) == t;
214                 },
215
216                 /**
217                  * Makes a name/object map out of an array with names.
218                  *
219                  * @method makeMap
220                  * @param {Array/String} items Items to make map out of.
221                  * @param {String} delim Optional delimiter to split string by.
222                  * @param {Object} map Optional map to add items to.
223                  * @return {Object} Name/value map of items.
224                  */
225                 makeMap : function(items, delim, map) {
226                         var i;
227
228                         items = items || [];
229                         delim = delim || ',';
230
231                         if (typeof(items) == "string")
232                                 items = items.split(delim);
233
234                         map = map || {};
235
236                         i = items.length;
237                         while (i--)
238                                 map[items[i]] = {};
239
240                         return map;
241                 },
242
243                 /**
244                  * Performs an iteration of all items in a collection such as an object or array. This method will execure the
245                  * callback function for each item in the collection, if the callback returns false the iteration will terminate.
246                  * The callback has the following format: cb(value, key_or_index).
247                  *
248                  * @method each
249                  * @param {Object} o Collection to iterate.
250                  * @param {function} cb Callback function to execute for each item.
251                  * @param {Object} s Optional scope to execute the callback in.
252                  * @example
253                  * // Iterate an array
254                  * tinymce.each([1,2,3], function(v, i) {
255                  *     console.debug("Value: " + v + ", Index: " + i);
256                  * });
257                  * 
258                  * // Iterate an object
259                  * tinymce.each({a : 1, b : 2, c: 3], function(v, k) {
260                  *     console.debug("Value: " + v + ", Key: " + k);
261                  * });
262                  */
263                 each : function(o, cb, s) {
264                         var n, l;
265
266                         if (!o)
267                                 return 0;
268
269                         s = s || o;
270
271                         if (o.length !== undefined) {
272                                 // Indexed arrays, needed for Safari
273                                 for (n=0, l = o.length; n < l; n++) {
274                                         if (cb.call(s, o[n], n, o) === false)
275                                                 return 0;
276                                 }
277                         } else {
278                                 // Hashtables
279                                 for (n in o) {
280                                         if (o.hasOwnProperty(n)) {
281                                                 if (cb.call(s, o[n], n, o) === false)
282                                                         return 0;
283                                         }
284                                 }
285                         }
286
287                         return 1;
288                 },
289
290                 // #ifndef jquery
291
292                 /**
293                  * Creates a new array by the return value of each iteration function call. This enables you to convert
294                  * one array list into another.
295                  *
296                  * @method map
297                  * @param {Array} a Array of items to iterate.
298                  * @param {function} f Function to call for each item. It's return value will be the new value.
299                  * @return {Array} Array with new values based on function return values.
300                  */
301                 map : function(a, f) {
302                         var o = [];
303
304                         tinymce.each(a, function(v) {
305                                 o.push(f(v));
306                         });
307
308                         return o;
309                 },
310
311                 /**
312                  * Filters out items from the input array by calling the specified function for each item.
313                  * If the function returns false the item will be excluded if it returns true it will be included.
314                  *
315                  * @method grep
316                  * @param {Array} a Array of items to loop though.
317                  * @param {function} f Function to call for each item. Include/exclude depends on it's return value.
318                  * @return {Array} New array with values imported and filtered based in input.
319                  * @example
320                  * // Filter out some items, this will return an array with 4 and 5
321                  * var items = tinymce.grep([1,2,3,4,5], function(v) {return v > 3;});
322                  */
323                 grep : function(a, f) {
324                         var o = [];
325
326                         tinymce.each(a, function(v) {
327                                 if (!f || f(v))
328                                         o.push(v);
329                         });
330
331                         return o;
332                 },
333
334                 /**
335                  * Returns the index of a value in an array, this method will return -1 if the item wasn't found.
336                  *
337                  * @method inArray
338                  * @param {Array} a Array/Object to search for value in.
339                  * @param {Object} v Value to check for inside the array.
340                  * @return {Number/String} Index of item inside the array inside an object. Or -1 if it wasn't found.
341                  * @example
342                  * // Get index of value in array this will alert 1 since 2 is at that index
343                  * alert(tinymce.inArray([1,2,3], 2));
344                  */
345                 inArray : function(a, v) {
346                         var i, l;
347
348                         if (a) {
349                                 for (i = 0, l = a.length; i < l; i++) {
350                                         if (a[i] === v)
351                                                 return i;
352                                 }
353                         }
354
355                         return -1;
356                 },
357
358                 /**
359                  * Extends an object with the specified other object(s).
360                  *
361                  * @method extend
362                  * @param {Object} o Object to extend with new items.
363                  * @param {Object} e..n Object(s) to extend the specified object with.
364                  * @return {Object} o New extended object, same reference as the input object.
365                  * @example
366                  * // Extends obj1 with two new fields
367                  * var obj = tinymce.extend(obj1, {
368                  *     somefield1 : 'a',
369                  *     somefield2 : 'a'
370                  * });
371                  * 
372                  * // Extends obj with obj2 and obj3
373                  * tinymce.extend(obj, obj2, obj3);
374                  */
375                 extend : function(o, e) {
376                         var i, l, a = arguments;
377
378                         for (i = 1, l = a.length; i < l; i++) {
379                                 e = a[i];
380
381                                 tinymce.each(e, function(v, n) {
382                                         if (v !== undefined)
383                                                 o[n] = v;
384                                 });
385                         }
386
387                         return o;
388                 },
389
390                 // #endif
391
392                 /**
393                  * Removes whitespace from the beginning and end of a string.
394                  *
395                  * @method trim
396                  * @param {String} s String to remove whitespace from.
397                  * @return {String} New string with removed whitespace.
398                  */
399                 trim : function(s) {
400                         return (s ? '' + s : '').replace(whiteSpaceRe, '');
401                 },
402
403                 /**
404                  * Creates a class, subclass or static singleton.
405                  * More details on this method can be found in the Wiki.
406                  *
407                  * @method create
408                  * @param {String} s Class name, inheritage and prefix.
409                  * @param {Object} p Collection of methods to add to the class.
410                  * @param {Object} root Optional root object defaults to the global window object.
411                  * @example
412                  * // Creates a basic class
413                  * tinymce.create('tinymce.somepackage.SomeClass', {
414                  *     SomeClass : function() {
415                  *         // Class constructor
416                  *     },
417                  * 
418                  *     method : function() {
419                  *         // Some method
420                  *     }
421                  * });
422                  *
423                  * // Creates a basic subclass class
424                  * tinymce.create('tinymce.somepackage.SomeSubClass:tinymce.somepackage.SomeClass', {
425                  *     SomeSubClass: function() {
426                  *         // Class constructor
427                  *         this.parent(); // Call parent constructor
428                  *     },
429                  * 
430                  *     method : function() {
431                  *         // Some method
432                  *         this.parent(); // Call parent method
433                  *     },
434                  * 
435                  *     'static' : {
436                  *         staticMethod : function() {
437                  *             // Static method
438                  *         }
439                  *     }
440                  * });
441                  *
442                  * // Creates a singleton/static class
443                  * tinymce.create('static tinymce.somepackage.SomeSingletonClass', {
444                  *     method : function() {
445                  *         // Some method
446                  *     }
447                  * });
448                  */
449                 create : function(s, p, root) {
450                         var t = this, sp, ns, cn, scn, c, de = 0;
451
452                         // Parse : <prefix> <class>:<super class>
453                         s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
454                         cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name
455
456                         // Create namespace for new class
457                         ns = t.createNS(s[3].replace(/\.\w+$/, ''), root);
458
459                         // Class already exists
460                         if (ns[cn])
461                                 return;
462
463                         // Make pure static class
464                         if (s[2] == 'static') {
465                                 ns[cn] = p;
466
467                                 if (this.onCreate)
468                                         this.onCreate(s[2], s[3], ns[cn]);
469
470                                 return;
471                         }
472
473                         // Create default constructor
474                         if (!p[cn]) {
475                                 p[cn] = function() {};
476                                 de = 1;
477                         }
478
479                         // Add constructor and methods
480                         ns[cn] = p[cn];
481                         t.extend(ns[cn].prototype, p);
482
483                         // Extend
484                         if (s[5]) {
485                                 sp = t.resolve(s[5]).prototype;
486                                 scn = s[5].match(/\.(\w+)$/i)[1]; // Class name
487
488                                 // Extend constructor
489                                 c = ns[cn];
490                                 if (de) {
491                                         // Add passthrough constructor
492                                         ns[cn] = function() {
493                                                 return sp[scn].apply(this, arguments);
494                                         };
495                                 } else {
496                                         // Add inherit constructor
497                                         ns[cn] = function() {
498                                                 this.parent = sp[scn];
499                                                 return c.apply(this, arguments);
500                                         };
501                                 }
502                                 ns[cn].prototype[cn] = ns[cn];
503
504                                 // Add super methods
505                                 t.each(sp, function(f, n) {
506                                         ns[cn].prototype[n] = sp[n];
507                                 });
508
509                                 // Add overridden methods
510                                 t.each(p, function(f, n) {
511                                         // Extend methods if needed
512                                         if (sp[n]) {
513                                                 ns[cn].prototype[n] = function() {
514                                                         this.parent = sp[n];
515                                                         return f.apply(this, arguments);
516                                                 };
517                                         } else {
518                                                 if (n != cn)
519                                                         ns[cn].prototype[n] = f;
520                                         }
521                                 });
522                         }
523
524                         // Add static methods
525                         t.each(p['static'], function(f, n) {
526                                 ns[cn][n] = f;
527                         });
528
529                         if (this.onCreate)
530                                 this.onCreate(s[2], s[3], ns[cn].prototype);
531                 },
532
533                 /**
534                  * Executed the specified function for each item in a object tree.
535                  *
536                  * @method walk
537                  * @param {Object} o Object tree to walk though.
538                  * @param {function} f Function to call for each item.
539                  * @param {String} n Optional name of collection inside the objects to walk for example childNodes.
540                  * @param {String} s Optional scope to execute the function in.
541                  */
542                 walk : function(o, f, n, s) {
543                         s = s || this;
544
545                         if (o) {
546                                 if (n)
547                                         o = o[n];
548
549                                 tinymce.each(o, function(o, i) {
550                                         if (f.call(s, o, i, n) === false)
551                                                 return false;
552
553                                         tinymce.walk(o, f, n, s);
554                                 });
555                         }
556                 },
557
558                 /**
559                  * Creates a namespace on a specific object.
560                  *
561                  * @method createNS
562                  * @param {String} n Namespace to create for example a.b.c.d.
563                  * @param {Object} o Optional object to add namespace to, defaults to window.
564                  * @return {Object} New namespace object the last item in path.
565                  * @example
566                  * // Create some namespace
567                  * tinymce.createNS('tinymce.somepackage.subpackage');
568                  *
569                  * // Add a singleton
570                  * var tinymce.somepackage.subpackage.SomeSingleton = {
571                  *     method : function() {
572                  *         // Some method
573                  *     }
574                  * };
575                  */
576                 createNS : function(n, o) {
577                         var i, v;
578
579                         o = o || win;
580
581                         n = n.split('.');
582                         for (i=0; i<n.length; i++) {
583                                 v = n[i];
584
585                                 if (!o[v])
586                                         o[v] = {};
587
588                                 o = o[v];
589                         }
590
591                         return o;
592                 },
593
594                 /**
595                  * Resolves a string and returns the object from a specific structure.
596                  *
597                  * @method resolve
598                  * @param {String} n Path to resolve for example a.b.c.d.
599                  * @param {Object} o Optional object to search though, defaults to window.
600                  * @return {Object} Last object in path or null if it couldn't be resolved.
601                  * @example
602                  * // Resolve a path into an object reference
603                  * var obj = tinymce.resolve('a.b.c.d');
604                  */
605                 resolve : function(n, o) {
606                         var i, l;
607
608                         o = o || win;
609
610                         n = n.split('.');
611                         for (i = 0, l = n.length; i < l; i++) {
612                                 o = o[n[i]];
613
614                                 if (!o)
615                                         break;
616                         }
617
618                         return o;
619                 },
620
621                 /**
622                  * Adds an unload handler to the document. This handler will be executed when the document gets unloaded.
623                  * This method is useful for dealing with browser memory leaks where it might be vital to remove DOM references etc.
624                  *
625                  * @method addUnload
626                  * @param {function} f Function to execute before the document gets unloaded.
627                  * @param {Object} s Optional scope to execute the function in.
628                  * @return {function} Returns the specified unload handler function.
629                  * @example
630                  * // Fixes a leak with a DOM element that was palces in the someObject
631                  * tinymce.addUnload(function() {
632                  *     // Null DOM element to reduce IE memory leak
633                  *     someObject.someElement = null;
634                  * });
635                  */
636                 addUnload : function(f, s) {
637                         var t = this;
638
639                         f = {func : f, scope : s || this};
640
641                         if (!t.unloads) {
642                                 function unload() {
643                                         var li = t.unloads, o, n;
644
645                                         if (li) {
646                                                 // Call unload handlers
647                                                 for (n in li) {
648                                                         o = li[n];
649
650                                                         if (o && o.func)
651                                                                 o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy
652                                                 }
653
654                                                 // Detach unload function
655                                                 if (win.detachEvent) {
656                                                         win.detachEvent('onbeforeunload', fakeUnload);
657                                                         win.detachEvent('onunload', unload);
658                                                 } else if (win.removeEventListener)
659                                                         win.removeEventListener('unload', unload, false);
660
661                                                 // Destroy references
662                                                 t.unloads = o = li = w = unload = 0;
663
664                                                 // Run garbarge collector on IE
665                                                 if (win.CollectGarbage)
666                                                         CollectGarbage();
667                                         }
668                                 };
669
670                                 function fakeUnload() {
671                                         var d = document;
672
673                                         // Is there things still loading, then do some magic
674                                         if (d.readyState == 'interactive') {
675                                                 function stop() {
676                                                         // Prevent memory leak
677                                                         d.detachEvent('onstop', stop);
678
679                                                         // Call unload handler
680                                                         if (unload)
681                                                                 unload();
682
683                                                         d = 0;
684                                                 };
685
686                                                 // Fire unload when the currently loading page is stopped
687                                                 if (d)
688                                                         d.attachEvent('onstop', stop);
689
690                                                 // Remove onstop listener after a while to prevent the unload function
691                                                 // to execute if the user presses cancel in an onbeforeunload
692                                                 // confirm dialog and then presses the browser stop button
693                                                 win.setTimeout(function() {
694                                                         if (d)
695                                                                 d.detachEvent('onstop', stop);
696                                                 }, 0);
697                                         }
698                                 };
699
700                                 // Attach unload handler
701                                 if (win.attachEvent) {
702                                         win.attachEvent('onunload', unload);
703                                         win.attachEvent('onbeforeunload', fakeUnload);
704                                 } else if (win.addEventListener)
705                                         win.addEventListener('unload', unload, false);
706
707                                 // Setup initial unload handler array
708                                 t.unloads = [f];
709                         } else
710                                 t.unloads.push(f);
711
712                         return f;
713                 },
714
715                 /**
716                  * Removes the specified function form the unload handler list.
717                  *
718                  * @method removeUnload
719                  * @param {function} f Function to remove from unload handler list.
720                  * @return {function} Removed function name or null if it wasn't found.
721                  */
722                 removeUnload : function(f) {
723                         var u = this.unloads, r = null;
724
725                         tinymce.each(u, function(o, i) {
726                                 if (o && o.func == f) {
727                                         u.splice(i, 1);
728                                         r = f;
729                                         return false;
730                                 }
731                         });
732
733                         return r;
734                 },
735
736                 /**
737                  * Splits a string but removes the whitespace before and after each value.
738                  *
739                  * @method explode
740                  * @param {string} s String to split.
741                  * @param {string} d Delimiter to split by.
742                  * @example
743                  * // Split a string into an array with a,b,c
744                  * var arr = tinymce.explode('a, b,   c');
745                  */
746                 explode : function(s, d) {
747                         return s ? tinymce.map(s.split(d || ','), tinymce.trim) : s;
748                 },
749
750                 _addVer : function(u) {
751                         var v;
752
753                         if (!this.query)
754                                 return u;
755
756                         v = (u.indexOf('?') == -1 ? '?' : '&') + this.query;
757
758                         if (u.indexOf('#') == -1)
759                                 return u + v;
760
761                         return u.replace('#', v + '#');
762                 },
763
764                 // Fix function for IE 9 where regexps isn't working correctly
765                 // Todo: remove me once MS fixes the bug
766                 _replace : function(find, replace, str) {
767                         // On IE9 we have to fake $x replacement
768                         if (isRegExpBroken) {
769                                 return str.replace(find, function() {
770                                         var val = replace, args = arguments, i;
771
772                                         for (i = 0; i < args.length - 2; i++) {
773                                                 if (args[i] === undefined) {
774                                                         val = val.replace(new RegExp('\\$' + i, 'g'), '');
775                                                 } else {
776                                                         val = val.replace(new RegExp('\\$' + i, 'g'), args[i]);
777                                                 }
778                                         }
779
780                                         return val;
781                                 });
782                         }
783
784                         return str.replace(find, replace);
785                 }
786
787                 /**#@-*/
788         };
789
790         // Initialize the API
791         tinymce._init();
792
793         // Expose tinymce namespace to the global namespace (window)
794         win.tinymce = win.tinyMCE = tinymce;
795
796         // Describe the different namespaces
797
798         /**
799          * Root level namespace this contains classes directly releated to the TinyMCE editor.
800          *
801          * @namespace tinymce
802          */
803
804         /**
805          * Contains classes for handling the browsers DOM.
806          *
807          * @namespace tinymce.dom
808          */
809
810         /**
811          * Contains html parser and serializer logic.
812          *
813          * @namespace tinymce.html
814          */
815
816         /**
817          * Contains the different UI types such as buttons, listboxes etc.
818          *
819          * @namespace tinymce.ui
820          */
821
822         /**
823          * Contains various utility classes such as json parser, cookies etc.
824          *
825          * @namespace tinymce.util
826          */
827
828         /**
829          * Contains plugin classes.
830          *
831          * @namespace tinymce.plugins
832          */
833 })(window);