| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869 | 
							- /**
 
-  * tinymce.js
 
-  *
 
-  * Copyright 2009, Moxiecode Systems AB
 
-  * Released under LGPL License.
 
-  *
 
-  * License: http://tinymce.moxiecode.com/license
 
-  * Contributing: http://tinymce.moxiecode.com/contributing
 
-  */
 
- (function(win) {
 
- 	var whiteSpaceRe = /^\s*|\s*$/g,
 
- 		undefined, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
 
- 	/**
 
- 	 * Core namespace with core functionality for the TinyMCE API all sub classes will be added to this namespace/object.
 
- 	 *
 
- 	 * @static
 
- 	 * @class tinymce
 
- 	 * @example
 
- 	 * // Using each method
 
- 	 * tinymce.each([1, 2, 3], function(v, i) {
 
- 	 *   console.log(i + '=' + v);
 
- 	 * });
 
- 	 *
 
- 	 * // Checking for a specific browser
 
- 	 * if (tinymce.isIE)
 
- 	 *   console.log("IE");
 
- 	 */
 
- 	var tinymce = {
 
- 		/**
 
- 		 * Major version of TinyMCE build.
 
- 		 *
 
- 		 * @property majorVersion
 
- 		 * @type String
 
- 		 */
 
- 		majorVersion : '@@tinymce_major_version@@',
 
- 		/**
 
- 		 * Major version of TinyMCE build.
 
- 		 *
 
- 		 * @property minorVersion
 
- 		 * @type String
 
- 		 */
 
- 		minorVersion : '@@tinymce_minor_version@@',
 
- 		/**
 
- 		 * Release date of TinyMCE build.
 
- 		 *
 
- 		 * @property releaseDate
 
- 		 * @type String
 
- 		 */
 
- 		releaseDate : '@@tinymce_release_date@@',
 
- 		/**
 
- 		 * Initializes the TinyMCE global namespace this will setup browser detection and figure out where TinyMCE is running from.
 
- 		 */
 
- 		_init : function() {
 
- 			var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
 
- 			/**
 
- 			 * Constant that is true if the browser is Opera.
 
- 			 *
 
- 			 * @property isOpera
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isOpera = win.opera && opera.buildNumber;
 
- 			/**
 
- 			 * Constant that is true if the browser is WebKit (Safari/Chrome).
 
- 			 *
 
- 			 * @property isWebKit
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isWebKit = /WebKit/.test(ua);
 
- 			/**
 
- 			 * Constant that is true if the browser is IE.
 
- 			 *
 
- 			 * @property isIE
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
 
- 			/**
 
- 			 * Constant that is true if the browser is IE 6 or older.
 
- 			 *
 
- 			 * @property isIE6
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
 
- 			/**
 
- 			 * Constant that is true if the browser is IE 7.
 
- 			 *
 
- 			 * @property isIE7
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIE7 = t.isIE && /MSIE [7]/.test(ua);
 
- 			/**
 
- 			 * Constant that is true if the browser is IE 8.
 
- 			 *
 
- 			 * @property isIE8
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIE8 = t.isIE && /MSIE [8]/.test(ua);
 
- 			/**
 
- 			 * Constant that is true if the browser is IE 9.
 
- 			 *
 
- 			 * @property isIE9
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIE9 = t.isIE && /MSIE [9]/.test(ua);
 
- 			/**
 
- 			 * Constant that is true if the browser is Gecko.
 
- 			 *
 
- 			 * @property isGecko
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isGecko = !t.isWebKit && /Gecko/.test(ua);
 
- 			/**
 
- 			 * Constant that is true if the os is Mac OS.
 
- 			 *
 
- 			 * @property isMac
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isMac = ua.indexOf('Mac') != -1;
 
- 			/**
 
- 			 * Constant that is true if the runtime is Adobe Air.
 
- 			 *
 
- 			 * @property isAir
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isAir = /adobeair/i.test(ua);
 
- 			/**
 
- 			 * Constant that tells if the current browser is an iPhone or iPad.
 
- 			 *
 
- 			 * @property isIDevice
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIDevice = /(iPad|iPhone)/.test(ua);
 
- 			
 
- 			/**
 
- 			 * Constant that is true if the current browser is running on iOS 5 or greater.
 
- 			 *
 
- 			 * @property isIOS5
 
- 			 * @type Boolean
 
- 			 * @final
 
- 			 */
 
- 			t.isIOS5 = t.isIDevice && ua.match(/AppleWebKit\/(\d*)/)[1]>=534;
 
- 			// TinyMCE .NET webcontrol might be setting the values for TinyMCE
 
- 			if (win.tinyMCEPreInit) {
 
- 				t.suffix = tinyMCEPreInit.suffix;
 
- 				t.baseURL = tinyMCEPreInit.base;
 
- 				t.query = tinyMCEPreInit.query;
 
- 				return;
 
- 			}
 
- 			// Get suffix and base
 
- 			t.suffix = '';
 
- 			// If base element found, add that infront of baseURL
 
- 			nl = d.getElementsByTagName('base');
 
- 			for (i=0; i<nl.length; i++) {
 
- 				if (v = nl[i].href) {
 
- 					// Host only value like http://site.com or http://site.com:8008
 
- 					if (/^https?:\/\/[^\/]+$/.test(v))
 
- 						v += '/';
 
- 					base = v ? v.match(/.*\//)[0] : ''; // Get only directory
 
- 				}
 
- 			}
 
- 			function getBase(n) {
 
- 				if (n.src && /tiny_mce(|_gzip|_jquery|_prototype|_full)(_dev|_src)?.js/.test(n.src)) {
 
- 					if (/_(src|dev)\.js/g.test(n.src))
 
- 						t.suffix = '_src';
 
- 					if ((p = n.src.indexOf('?')) != -1)
 
- 						t.query = n.src.substring(p + 1);
 
- 					t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
 
- 					// If path to script is relative and a base href was found add that one infront
 
- 					// the src property will always be an absolute one on non IE browsers and IE 8
 
- 					// so this logic will basically only be executed on older IE versions
 
- 					if (base && t.baseURL.indexOf('://') == -1 && t.baseURL.indexOf('/') !== 0)
 
- 						t.baseURL = base + t.baseURL;
 
- 					return t.baseURL;
 
- 				}
 
- 				return null;
 
- 			};
 
- 			// Check document
 
- 			nl = d.getElementsByTagName('script');
 
- 			for (i=0; i<nl.length; i++) {
 
- 				if (getBase(nl[i]))
 
- 					return;
 
- 			}
 
- 			// Check head
 
- 			n = d.getElementsByTagName('head')[0];
 
- 			if (n) {
 
- 				nl = n.getElementsByTagName('script');
 
- 				for (i=0; i<nl.length; i++) {
 
- 					if (getBase(nl[i]))
 
- 						return;
 
- 				}
 
- 			}
 
- 			return;
 
- 		},
 
- 		/**
 
- 		 * Checks if a object is of a specific type for example an array.
 
- 		 *
 
- 		 * @method is
 
- 		 * @param {Object} o Object to check type of.
 
- 		 * @param {string} t Optional type to check for.
 
- 		 * @return {Boolean} true/false if the object is of the specified type.
 
- 		 */
 
- 		is : function(o, t) {
 
- 			if (!t)
 
- 				return o !== undefined;
 
- 			if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
 
- 				return true;
 
- 			return typeof(o) == t;
 
- 		},
 
- 		/**
 
- 		 * Makes a name/object map out of an array with names.
 
- 		 *
 
- 		 * @method makeMap
 
- 		 * @param {Array/String} items Items to make map out of.
 
- 		 * @param {String} delim Optional delimiter to split string by.
 
- 		 * @param {Object} map Optional map to add items to.
 
- 		 * @return {Object} Name/value map of items.
 
- 		 */
 
- 		makeMap : function(items, delim, map) {
 
- 			var i;
 
- 			items = items || [];
 
- 			delim = delim || ',';
 
- 			if (typeof(items) == "string")
 
- 				items = items.split(delim);
 
- 			map = map || {};
 
- 			i = items.length;
 
- 			while (i--)
 
- 				map[items[i]] = {};
 
- 			return map;
 
- 		},
 
- 		/**
 
- 		 * Performs an iteration of all items in a collection such as an object or array. This method will execure the
 
- 		 * callback function for each item in the collection, if the callback returns false the iteration will terminate.
 
- 		 * The callback has the following format: cb(value, key_or_index).
 
- 		 *
 
- 		 * @method each
 
- 		 * @param {Object} o Collection to iterate.
 
- 		 * @param {function} cb Callback function to execute for each item.
 
- 		 * @param {Object} s Optional scope to execute the callback in.
 
- 		 * @example
 
- 		 * // Iterate an array
 
- 		 * tinymce.each([1,2,3], function(v, i) {
 
- 		 *     console.debug("Value: " + v + ", Index: " + i);
 
- 		 * });
 
- 		 * 
 
- 		 * // Iterate an object
 
- 		 * tinymce.each({a : 1, b : 2, c: 3], function(v, k) {
 
- 		 *     console.debug("Value: " + v + ", Key: " + k);
 
- 		 * });
 
- 		 */
 
- 		each : function(o, cb, s) {
 
- 			var n, l;
 
- 			if (!o)
 
- 				return 0;
 
- 			s = s || o;
 
- 			if (o.length !== undefined) {
 
- 				// Indexed arrays, needed for Safari
 
- 				for (n=0, l = o.length; n < l; n++) {
 
- 					if (cb.call(s, o[n], n, o) === false)
 
- 						return 0;
 
- 				}
 
- 			} else {
 
- 				// Hashtables
 
- 				for (n in o) {
 
- 					if (o.hasOwnProperty(n)) {
 
- 						if (cb.call(s, o[n], n, o) === false)
 
- 							return 0;
 
- 					}
 
- 				}
 
- 			}
 
- 			return 1;
 
- 		},
 
- 		// #ifndef jquery
 
- 		/**
 
- 		 * Creates a new array by the return value of each iteration function call. This enables you to convert
 
- 		 * one array list into another.
 
- 		 *
 
- 		 * @method map
 
- 		 * @param {Array} a Array of items to iterate.
 
- 		 * @param {function} f Function to call for each item. It's return value will be the new value.
 
- 		 * @return {Array} Array with new values based on function return values.
 
- 		 */
 
- 		map : function(a, f) {
 
- 			var o = [];
 
- 			tinymce.each(a, function(v) {
 
- 				o.push(f(v));
 
- 			});
 
- 			return o;
 
- 		},
 
- 		/**
 
- 		 * Filters out items from the input array by calling the specified function for each item.
 
- 		 * If the function returns false the item will be excluded if it returns true it will be included.
 
- 		 *
 
- 		 * @method grep
 
- 		 * @param {Array} a Array of items to loop though.
 
- 		 * @param {function} f Function to call for each item. Include/exclude depends on it's return value.
 
- 		 * @return {Array} New array with values imported and filtered based in input.
 
- 		 * @example
 
- 		 * // Filter out some items, this will return an array with 4 and 5
 
- 		 * var items = tinymce.grep([1,2,3,4,5], function(v) {return v > 3;});
 
- 		 */
 
- 		grep : function(a, f) {
 
- 			var o = [];
 
- 			tinymce.each(a, function(v) {
 
- 				if (!f || f(v))
 
- 					o.push(v);
 
- 			});
 
- 			return o;
 
- 		},
 
- 		/**
 
- 		 * Returns the index of a value in an array, this method will return -1 if the item wasn't found.
 
- 		 *
 
- 		 * @method inArray
 
- 		 * @param {Array} a Array/Object to search for value in.
 
- 		 * @param {Object} v Value to check for inside the array.
 
- 		 * @return {Number/String} Index of item inside the array inside an object. Or -1 if it wasn't found.
 
- 		 * @example
 
- 		 * // Get index of value in array this will alert 1 since 2 is at that index
 
- 		 * alert(tinymce.inArray([1,2,3], 2));
 
- 		 */
 
- 		inArray : function(a, v) {
 
- 			var i, l;
 
- 			if (a) {
 
- 				for (i = 0, l = a.length; i < l; i++) {
 
- 					if (a[i] === v)
 
- 						return i;
 
- 				}
 
- 			}
 
- 			return -1;
 
- 		},
 
- 		/**
 
- 		 * Extends an object with the specified other object(s).
 
- 		 *
 
- 		 * @method extend
 
- 		 * @param {Object} o Object to extend with new items.
 
- 		 * @param {Object} e..n Object(s) to extend the specified object with.
 
- 		 * @return {Object} o New extended object, same reference as the input object.
 
- 		 * @example
 
- 		 * // Extends obj1 with two new fields
 
- 		 * var obj = tinymce.extend(obj1, {
 
- 		 *     somefield1 : 'a',
 
- 		 *     somefield2 : 'a'
 
- 		 * });
 
- 		 * 
 
- 		 * // Extends obj with obj2 and obj3
 
- 		 * tinymce.extend(obj, obj2, obj3);
 
- 		 */
 
- 		extend : function(o, e) {
 
- 			var i, l, a = arguments;
 
- 			for (i = 1, l = a.length; i < l; i++) {
 
- 				e = a[i];
 
- 				tinymce.each(e, function(v, n) {
 
- 					if (v !== undefined)
 
- 						o[n] = v;
 
- 				});
 
- 			}
 
- 			return o;
 
- 		},
 
- 		// #endif
 
- 		/**
 
- 		 * Removes whitespace from the beginning and end of a string.
 
- 		 *
 
- 		 * @method trim
 
- 		 * @param {String} s String to remove whitespace from.
 
- 		 * @return {String} New string with removed whitespace.
 
- 		 */
 
- 		trim : function(s) {
 
- 			return (s ? '' + s : '').replace(whiteSpaceRe, '');
 
- 		},
 
- 		/**
 
- 		 * Creates a class, subclass or static singleton.
 
- 		 * More details on this method can be found in the Wiki.
 
- 		 *
 
- 		 * @method create
 
- 		 * @param {String} s Class name, inheritage and prefix.
 
- 		 * @param {Object} p Collection of methods to add to the class.
 
- 		 * @param {Object} root Optional root object defaults to the global window object.
 
- 		 * @example
 
- 		 * // Creates a basic class
 
- 		 * tinymce.create('tinymce.somepackage.SomeClass', {
 
- 		 *     SomeClass : function() {
 
- 		 *         // Class constructor
 
- 		 *     },
 
- 		 * 
 
- 		 *     method : function() {
 
- 		 *         // Some method
 
- 		 *     }
 
- 		 * });
 
- 		 *
 
- 		 * // Creates a basic subclass class
 
- 		 * tinymce.create('tinymce.somepackage.SomeSubClass:tinymce.somepackage.SomeClass', {
 
- 		 *     SomeSubClass: function() {
 
- 		 *         // Class constructor
 
- 		 *         this.parent(); // Call parent constructor
 
- 		 *     },
 
- 		 * 
 
- 		 *     method : function() {
 
- 		 *         // Some method
 
- 		 *         this.parent(); // Call parent method
 
- 		 *     },
 
- 		 * 
 
- 		 *     'static' : {
 
- 		 *         staticMethod : function() {
 
- 		 *             // Static method
 
- 		 *         }
 
- 		 *     }
 
- 		 * });
 
- 		 *
 
- 		 * // Creates a singleton/static class
 
- 		 * tinymce.create('static tinymce.somepackage.SomeSingletonClass', {
 
- 		 *     method : function() {
 
- 		 *         // Some method
 
- 		 *     }
 
- 		 * });
 
- 		 */
 
- 		create : function(s, p, root) {
 
- 			var t = this, sp, ns, cn, scn, c, de = 0;
 
- 			// Parse : <prefix> <class>:<super class>
 
- 			s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
 
- 			cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name
 
- 			// Create namespace for new class
 
- 			ns = t.createNS(s[3].replace(/\.\w+$/, ''), root);
 
- 			// Class already exists
 
- 			if (ns[cn])
 
- 				return;
 
- 			// Make pure static class
 
- 			if (s[2] == 'static') {
 
- 				ns[cn] = p;
 
- 				if (this.onCreate)
 
- 					this.onCreate(s[2], s[3], ns[cn]);
 
- 				return;
 
- 			}
 
- 			// Create default constructor
 
- 			if (!p[cn]) {
 
- 				p[cn] = function() {};
 
- 				de = 1;
 
- 			}
 
- 			// Add constructor and methods
 
- 			ns[cn] = p[cn];
 
- 			t.extend(ns[cn].prototype, p);
 
- 			// Extend
 
- 			if (s[5]) {
 
- 				sp = t.resolve(s[5]).prototype;
 
- 				scn = s[5].match(/\.(\w+)$/i)[1]; // Class name
 
- 				// Extend constructor
 
- 				c = ns[cn];
 
- 				if (de) {
 
- 					// Add passthrough constructor
 
- 					ns[cn] = function() {
 
- 						return sp[scn].apply(this, arguments);
 
- 					};
 
- 				} else {
 
- 					// Add inherit constructor
 
- 					ns[cn] = function() {
 
- 						this.parent = sp[scn];
 
- 						return c.apply(this, arguments);
 
- 					};
 
- 				}
 
- 				ns[cn].prototype[cn] = ns[cn];
 
- 				// Add super methods
 
- 				t.each(sp, function(f, n) {
 
- 					ns[cn].prototype[n] = sp[n];
 
- 				});
 
- 				// Add overridden methods
 
- 				t.each(p, function(f, n) {
 
- 					// Extend methods if needed
 
- 					if (sp[n]) {
 
- 						ns[cn].prototype[n] = function() {
 
- 							this.parent = sp[n];
 
- 							return f.apply(this, arguments);
 
- 						};
 
- 					} else {
 
- 						if (n != cn)
 
- 							ns[cn].prototype[n] = f;
 
- 					}
 
- 				});
 
- 			}
 
- 			// Add static methods
 
- 			t.each(p['static'], function(f, n) {
 
- 				ns[cn][n] = f;
 
- 			});
 
- 			if (this.onCreate)
 
- 				this.onCreate(s[2], s[3], ns[cn].prototype);
 
- 		},
 
- 		/**
 
- 		 * Executed the specified function for each item in a object tree.
 
- 		 *
 
- 		 * @method walk
 
- 		 * @param {Object} o Object tree to walk though.
 
- 		 * @param {function} f Function to call for each item.
 
- 		 * @param {String} n Optional name of collection inside the objects to walk for example childNodes.
 
- 		 * @param {String} s Optional scope to execute the function in.
 
- 		 */
 
- 		walk : function(o, f, n, s) {
 
- 			s = s || this;
 
- 			if (o) {
 
- 				if (n)
 
- 					o = o[n];
 
- 				tinymce.each(o, function(o, i) {
 
- 					if (f.call(s, o, i, n) === false)
 
- 						return false;
 
- 					tinymce.walk(o, f, n, s);
 
- 				});
 
- 			}
 
- 		},
 
- 		/**
 
- 		 * Creates a namespace on a specific object.
 
- 		 *
 
- 		 * @method createNS
 
- 		 * @param {String} n Namespace to create for example a.b.c.d.
 
- 		 * @param {Object} o Optional object to add namespace to, defaults to window.
 
- 		 * @return {Object} New namespace object the last item in path.
 
- 		 * @example
 
- 		 * // Create some namespace
 
- 		 * tinymce.createNS('tinymce.somepackage.subpackage');
 
- 		 *
 
- 		 * // Add a singleton
 
- 		 * var tinymce.somepackage.subpackage.SomeSingleton = {
 
- 		 *     method : function() {
 
- 		 *         // Some method
 
- 		 *     }
 
- 		 * };
 
- 		 */
 
- 		createNS : function(n, o) {
 
- 			var i, v;
 
- 			o = o || win;
 
- 			n = n.split('.');
 
- 			for (i=0; i<n.length; i++) {
 
- 				v = n[i];
 
- 				if (!o[v])
 
- 					o[v] = {};
 
- 				o = o[v];
 
- 			}
 
- 			return o;
 
- 		},
 
- 		/**
 
- 		 * Resolves a string and returns the object from a specific structure.
 
- 		 *
 
- 		 * @method resolve
 
- 		 * @param {String} n Path to resolve for example a.b.c.d.
 
- 		 * @param {Object} o Optional object to search though, defaults to window.
 
- 		 * @return {Object} Last object in path or null if it couldn't be resolved.
 
- 		 * @example
 
- 		 * // Resolve a path into an object reference
 
- 		 * var obj = tinymce.resolve('a.b.c.d');
 
- 		 */
 
- 		resolve : function(n, o) {
 
- 			var i, l;
 
- 			o = o || win;
 
- 			n = n.split('.');
 
- 			for (i = 0, l = n.length; i < l; i++) {
 
- 				o = o[n[i]];
 
- 				if (!o)
 
- 					break;
 
- 			}
 
- 			return o;
 
- 		},
 
- 		/**
 
- 		 * Adds an unload handler to the document. This handler will be executed when the document gets unloaded.
 
- 		 * This method is useful for dealing with browser memory leaks where it might be vital to remove DOM references etc.
 
- 		 *
 
- 		 * @method addUnload
 
- 		 * @param {function} f Function to execute before the document gets unloaded.
 
- 		 * @param {Object} s Optional scope to execute the function in.
 
- 		 * @return {function} Returns the specified unload handler function.
 
- 		 * @example
 
- 		 * // Fixes a leak with a DOM element that was palces in the someObject
 
- 		 * tinymce.addUnload(function() {
 
- 		 *     // Null DOM element to reduce IE memory leak
 
- 		 *     someObject.someElement = null;
 
- 		 * });
 
- 		 */
 
- 		addUnload : function(f, s) {
 
- 			var t = this;
 
- 			f = {func : f, scope : s || this};
 
- 			if (!t.unloads) {
 
- 				function unload() {
 
- 					var li = t.unloads, o, n;
 
- 					if (li) {
 
- 						// Call unload handlers
 
- 						for (n in li) {
 
- 							o = li[n];
 
- 							if (o && o.func)
 
- 								o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy
 
- 						}
 
- 						// Detach unload function
 
- 						if (win.detachEvent) {
 
- 							win.detachEvent('onbeforeunload', fakeUnload);
 
- 							win.detachEvent('onunload', unload);
 
- 						} else if (win.removeEventListener)
 
- 							win.removeEventListener('unload', unload, false);
 
- 						// Destroy references
 
- 						t.unloads = o = li = w = unload = 0;
 
- 						// Run garbarge collector on IE
 
- 						if (win.CollectGarbage)
 
- 							CollectGarbage();
 
- 					}
 
- 				};
 
- 				function fakeUnload() {
 
- 					var d = document;
 
- 					// Is there things still loading, then do some magic
 
- 					if (d.readyState == 'interactive') {
 
- 						function stop() {
 
- 							// Prevent memory leak
 
- 							d.detachEvent('onstop', stop);
 
- 							// Call unload handler
 
- 							if (unload)
 
- 								unload();
 
- 							d = 0;
 
- 						};
 
- 						// Fire unload when the currently loading page is stopped
 
- 						if (d)
 
- 							d.attachEvent('onstop', stop);
 
- 						// Remove onstop listener after a while to prevent the unload function
 
- 						// to execute if the user presses cancel in an onbeforeunload
 
- 						// confirm dialog and then presses the browser stop button
 
- 						win.setTimeout(function() {
 
- 							if (d)
 
- 								d.detachEvent('onstop', stop);
 
- 						}, 0);
 
- 					}
 
- 				};
 
- 				// Attach unload handler
 
- 				if (win.attachEvent) {
 
- 					win.attachEvent('onunload', unload);
 
- 					win.attachEvent('onbeforeunload', fakeUnload);
 
- 				} else if (win.addEventListener)
 
- 					win.addEventListener('unload', unload, false);
 
- 				// Setup initial unload handler array
 
- 				t.unloads = [f];
 
- 			} else
 
- 				t.unloads.push(f);
 
- 			return f;
 
- 		},
 
- 		/**
 
- 		 * Removes the specified function form the unload handler list.
 
- 		 *
 
- 		 * @method removeUnload
 
- 		 * @param {function} f Function to remove from unload handler list.
 
- 		 * @return {function} Removed function name or null if it wasn't found.
 
- 		 */
 
- 		removeUnload : function(f) {
 
- 			var u = this.unloads, r = null;
 
- 			tinymce.each(u, function(o, i) {
 
- 				if (o && o.func == f) {
 
- 					u.splice(i, 1);
 
- 					r = f;
 
- 					return false;
 
- 				}
 
- 			});
 
- 			return r;
 
- 		},
 
- 		/**
 
- 		 * Splits a string but removes the whitespace before and after each value.
 
- 		 *
 
- 		 * @method explode
 
- 		 * @param {string} s String to split.
 
- 		 * @param {string} d Delimiter to split by.
 
- 		 * @example
 
- 		 * // Split a string into an array with a,b,c
 
- 		 * var arr = tinymce.explode('a, b,   c');
 
- 		 */
 
- 		explode : function(s, d) {
 
- 			return s ? tinymce.map(s.split(d || ','), tinymce.trim) : s;
 
- 		},
 
- 		_addVer : function(u) {
 
- 			var v;
 
- 			if (!this.query)
 
- 				return u;
 
- 			v = (u.indexOf('?') == -1 ? '?' : '&') + this.query;
 
- 			if (u.indexOf('#') == -1)
 
- 				return u + v;
 
- 			return u.replace('#', v + '#');
 
- 		},
 
- 		// Fix function for IE 9 where regexps isn't working correctly
 
- 		// Todo: remove me once MS fixes the bug
 
- 		_replace : function(find, replace, str) {
 
- 			// On IE9 we have to fake $x replacement
 
- 			if (isRegExpBroken) {
 
- 				return str.replace(find, function() {
 
- 					var val = replace, args = arguments, i;
 
- 					for (i = 0; i < args.length - 2; i++) {
 
- 						if (args[i] === undefined) {
 
- 							val = val.replace(new RegExp('\\$' + i, 'g'), '');
 
- 						} else {
 
- 							val = val.replace(new RegExp('\\$' + i, 'g'), args[i]);
 
- 						}
 
- 					}
 
- 					return val;
 
- 				});
 
- 			}
 
- 			return str.replace(find, replace);
 
- 		}
 
- 		/**#@-*/
 
- 	};
 
- 	// Initialize the API
 
- 	tinymce._init();
 
- 	// Expose tinymce namespace to the global namespace (window)
 
- 	win.tinymce = win.tinyMCE = tinymce;
 
- 	// Describe the different namespaces
 
- 	/**
 
- 	 * Root level namespace this contains classes directly releated to the TinyMCE editor.
 
- 	 *
 
- 	 * @namespace tinymce
 
- 	 */
 
- 	/**
 
- 	 * Contains classes for handling the browsers DOM.
 
- 	 *
 
- 	 * @namespace tinymce.dom
 
- 	 */
 
- 	/**
 
- 	 * Contains html parser and serializer logic.
 
- 	 *
 
- 	 * @namespace tinymce.html
 
- 	 */
 
- 	/**
 
- 	 * Contains the different UI types such as buttons, listboxes etc.
 
- 	 *
 
- 	 * @namespace tinymce.ui
 
- 	 */
 
- 	/**
 
- 	 * Contains various utility classes such as json parser, cookies etc.
 
- 	 *
 
- 	 * @namespace tinymce.util
 
- 	 */
 
- 	/**
 
- 	 * Contains plugin classes.
 
- 	 *
 
- 	 * @namespace tinymce.plugins
 
- 	 */
 
- })(window);
 
 
  |