includes/clientside/tinymce/tiny_mce_src.js
changeset 1193 e3b94bd055dc
parent 778 57ce13805b6f
equal deleted inserted replaced
1192:5882f0eebb34 1193:e3b94bd055dc
     1 
       
     2 /* file:jscripts/tiny_mce/classes/tinymce.js */
       
     3 
       
     4 var tinymce = {
     1 var tinymce = {
     5 	majorVersion : '3',
     2 	majorVersion : '3',
     6 	minorVersion : '2.1.1',
     3 	minorVersion : '2.7',
     7 	releaseDate : '2008-11-27',
     4 	releaseDate : '2009-09-22',
     8 
     5 
     9 	_init : function() {
     6 	_init : function() {
    10 		var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
     7 		var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
    11 
     8 
    12 		// Browser checks
       
    13 		t.isOpera = w.opera && opera.buildNumber;
     9 		t.isOpera = w.opera && opera.buildNumber;
       
    10 
    14 		t.isWebKit = /WebKit/.test(ua);
    11 		t.isWebKit = /WebKit/.test(ua);
    15 		t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt;
    12 
    16 		t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
    13 		t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
       
    14 
    17 		t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
    15 		t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
       
    16 
    18 		t.isGecko = !t.isWebKit && /Gecko/.test(ua);
    17 		t.isGecko = !t.isWebKit && /Gecko/.test(ua);
       
    18 
    19 		t.isMac = ua.indexOf('Mac') != -1;
    19 		t.isMac = ua.indexOf('Mac') != -1;
       
    20 
    20 		t.isAir = /adobeair/i.test(ua);
    21 		t.isAir = /adobeair/i.test(ua);
    21 
    22 
    22 		// TinyMCE .NET webcontrol might be setting the values for TinyMCE
    23 		// TinyMCE .NET webcontrol might be setting the values for TinyMCE
    23 		if (w.tinyMCEPreInit) {
    24 		if (w.tinyMCEPreInit) {
    24 			t.suffix = tinyMCEPreInit.suffix;
    25 			t.suffix = tinyMCEPreInit.suffix;
    41 				base = v ? v.match(/.*\//)[0] : ''; // Get only directory
    42 				base = v ? v.match(/.*\//)[0] : ''; // Get only directory
    42 			}
    43 			}
    43 		}
    44 		}
    44 
    45 
    45 		function getBase(n) {
    46 		function getBase(n) {
    46 			if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) {
    47 			if (n.src && /tiny_mce(|_gzip|_jquery|_prototype)(_dev|_src)?.js/.test(n.src)) {
    47 				if (/_(src|dev)\.js/g.test(n.src))
    48 				if (/_(src|dev)\.js/g.test(n.src))
    48 					t.suffix = '_src';
    49 					t.suffix = '_src';
    49 
    50 
    50 				if ((p = n.src.indexOf('?')) != -1)
    51 				if ((p = n.src.indexOf('?')) != -1)
    51 					t.query = n.src.substring(p + 1);
    52 					t.query = n.src.substring(p + 1);
    52 
    53 
    53 				t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
    54 				t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
    54 
    55 
    55 				// If path to script is relative and a base href was found add that one infront
    56 				// If path to script is relative and a base href was found add that one infront
    56 				if (base && t.baseURL.indexOf('://') == -1)
    57 				// the src property will always be an absolute one on non IE browsers and IE 8
       
    58 				// so this logic will basically only be executed on older IE versions
       
    59 				if (base && t.baseURL.indexOf('://') == -1 && t.baseURL.indexOf('/') !== 0)
    57 					t.baseURL = base + t.baseURL;
    60 					t.baseURL = base + t.baseURL;
    58 
    61 
    59 				return t.baseURL;
    62 				return t.baseURL;
    60 			}
    63 			}
    61 
    64 
    86 		var n = typeof(o);
    89 		var n = typeof(o);
    87 
    90 
    88 		if (!t)
    91 		if (!t)
    89 			return n != 'undefined';
    92 			return n != 'undefined';
    90 
    93 
    91 		if (t == 'array' && (o instanceof Array))
    94 		if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
    92 			return true;
    95 			return true;
    93 
    96 
    94 		return n == t;
    97 		return n == t;
    95 	},
    98 	},
    96 
       
    97 	// #if !jquery
       
    98 
    99 
    99 	each : function(o, cb, s) {
   100 	each : function(o, cb, s) {
   100 		var n, l;
   101 		var n, l;
   101 
   102 
   102 		if (!o)
   103 		if (!o)
   121 		}
   122 		}
   122 
   123 
   123 		return 1;
   124 		return 1;
   124 	},
   125 	},
   125 
   126 
       
   127 
   126 	map : function(a, f) {
   128 	map : function(a, f) {
   127 		var o = [];
   129 		var o = [];
   128 
   130 
   129 		tinymce.each(a, function(v) {
   131 		tinymce.each(a, function(v) {
   130 			o.push(f(v));
   132 			o.push(f(v));
   170 		}
   172 		}
   171 
   173 
   172 		return o;
   174 		return o;
   173 	},
   175 	},
   174 
   176 
       
   177 
   175 	trim : function(s) {
   178 	trim : function(s) {
   176 		return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');
   179 		return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');
   177 	},
   180 	},
   178 
       
   179 	// #endif
       
   180 
   181 
   181 	create : function(s, p) {
   182 	create : function(s, p) {
   182 		var t = this, sp, ns, cn, scn, c, de = 0;
   183 		var t = this, sp, ns, cn, scn, c, de = 0;
   183 
   184 
   184 		// Parse : <prefix> <class>:<super class>
   185 		// Parse : <prefix> <class>:<super class>
   300 		var i, l;
   301 		var i, l;
   301 
   302 
   302 		o = o || window;
   303 		o = o || window;
   303 
   304 
   304 		n = n.split('.');
   305 		n = n.split('.');
   305 		for (i=0, l = n.length; i<l; i++) {
   306 		for (i = 0, l = n.length; i < l; i++) {
   306 			o = o[n[i]];
   307 			o = o[n[i]];
   307 
   308 
   308 			if (!o)
   309 			if (!o)
   309 				break;
   310 				break;
   310 		}
   311 		}
   336 						w.detachEvent('onunload', unload);
   337 						w.detachEvent('onunload', unload);
   337 					} else if (w.removeEventListener)
   338 					} else if (w.removeEventListener)
   338 						w.removeEventListener('unload', unload, false);
   339 						w.removeEventListener('unload', unload, false);
   339 
   340 
   340 					// Destroy references
   341 					// Destroy references
   341 					t.unloads = o = li = w = unload = null;
   342 					t.unloads = o = li = w = unload = 0;
   342 
   343 
   343 					// Run garbarge collector on IE
   344 					// Run garbarge collector on IE
   344 					if (window.CollectGarbage)
   345 					if (window.CollectGarbage)
   345 						window.CollectGarbage();
   346 						window.CollectGarbage();
   346 				}
   347 				}
   354 					function stop() {
   355 					function stop() {
   355 						// Prevent memory leak
   356 						// Prevent memory leak
   356 						d.detachEvent('onstop', stop);
   357 						d.detachEvent('onstop', stop);
   357 
   358 
   358 						// Call unload handler
   359 						// Call unload handler
   359 						unload();
   360 						if (unload)
   360 
   361 							unload();
   361 						d = null;
   362 
       
   363 						d = 0;
   362 					};
   364 					};
   363 
   365 
   364 					// Fire unload when the currently loading page is stopped
   366 					// Fire unload when the currently loading page is stopped
   365 					d.attachEvent('onstop', stop);
   367 					if (d)
       
   368 						d.attachEvent('onstop', stop);
   366 
   369 
   367 					// Remove onstop listener after a while to prevent the unload function
   370 					// Remove onstop listener after a while to prevent the unload function
   368 					// to execute if the user presses cancel in an onbeforeunload
   371 					// to execute if the user presses cancel in an onbeforeunload
   369 					// confirm dialog and then presses the browser stop button
   372 					// confirm dialog and then presses the browser stop button
   370 					window.setTimeout(function() {
   373 					window.setTimeout(function() {
   371 						d.detachEvent('onstop', stop);
   374 						if (d)
       
   375 							d.detachEvent('onstop', stop);
   372 					}, 0);
   376 					}, 0);
   373 				}
   377 				}
   374 			};
   378 			};
   375 
   379 
   376 			// Attach unload handler
   380 			// Attach unload handler
   425 // Required for GZip AJAX loading
   429 // Required for GZip AJAX loading
   426 window.tinymce = tinymce;
   430 window.tinymce = tinymce;
   427 
   431 
   428 // Initialize the API
   432 // Initialize the API
   429 tinymce._init();
   433 tinymce._init();
   430 
       
   431 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */
       
   432 
       
   433 
       
   434 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */
       
   435 
       
   436 
       
   437 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */
       
   438 
       
   439 tinymce.create('tinymce.util.Dispatcher', {
   434 tinymce.create('tinymce.util.Dispatcher', {
   440 	scope : null,
   435 	scope : null,
   441 	listeners : null,
   436 	listeners : null,
   442 
   437 
   443 	Dispatcher : function(s) {
   438 	Dispatcher : function(s) {
   486 
   481 
   487 		return s;
   482 		return s;
   488 	}
   483 	}
   489 
   484 
   490 	});
   485 	});
   491 
       
   492 /* file:jscripts/tiny_mce/classes/util/URI.js */
       
   493 
       
   494 (function() {
   486 (function() {
   495 	var each = tinymce.each;
   487 	var each = tinymce.each;
   496 
   488 
   497 	tinymce.create('tinymce.util.URI', {
   489 	tinymce.create('tinymce.util.URI', {
   498 		URI : function(u, s) {
   490 		URI : function(u, s) {
   499 			var t = this, o, a, b;
   491 			var t = this, o, a, b;
   500 
   492 
       
   493 			// Trim whitespace
       
   494 			u = tinymce.trim(u);
       
   495 
   501 			// Default settings
   496 			// Default settings
   502 			s = t.settings = s || {};
   497 			s = t.settings = s || {};
   503 
   498 
   504 			// Strange app protocol or local anchor
   499 			// Strange app protocol or local anchor
   505 			if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {
   500 			if (/^(mailto|tel|news|javascript|about|data):/i.test(u) || /^\s*#/.test(u)) {
   506 				t.source = u;
   501 				t.source = u;
   507 				return;
   502 				return;
   508 			}
   503 			}
   509 
   504 
   510 			// Absolute path with no host, fake host and protocol
   505 			// Absolute path with no host, fake host and protocol
   511 			if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
   506 			if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
   512 				u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
   507 				u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
   513 
   508 
   514 			// Relative path
   509 			// Relative path http:// or protocol relative //path
   515 			if (u.indexOf(':/') === -1 && u.indexOf('//') !== 0)
   510 			if (!/^\w*:?\/\//.test(u))
   516 				u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
   511 				u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
   517 
   512 
   518 			// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
   513 			// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
   519 			u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
   514 			u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
   520 			u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
   515 			u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
   588 		},
   583 		},
   589 	
   584 	
   590 		toAbsolute : function(u, nh) {
   585 		toAbsolute : function(u, nh) {
   591 			var u = new tinymce.util.URI(u, {base_uri : this});
   586 			var u = new tinymce.util.URI(u, {base_uri : this});
   592 
   587 
   593 			return u.getURI(this.host == u.host ? nh : 0);
   588 			return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
   594 		},
   589 		},
   595 
   590 
   596 		toRelPath : function(base, path) {
   591 		toRelPath : function(base, path) {
   597 			var items, bp = 0, out = '', i, l;
   592 			var items, bp = 0, out = '', i, l;
   598 
   593 
   634 
   629 
   635 			return out;
   630 			return out;
   636 		},
   631 		},
   637 
   632 
   638 		toAbsPath : function(base, path) {
   633 		toAbsPath : function(base, path) {
   639 			var i, nb = 0, o = [];
   634 			var i, nb = 0, o = [], tr, outPath;
   640 
   635 
   641 			// Split paths
   636 			// Split paths
       
   637 			tr = /\/$/.test(path) ? '/' : '';
   642 			base = base.split('/');
   638 			base = base.split('/');
   643 			path = path.split('/');
   639 			path = path.split('/');
   644 
   640 
   645 			// Remove empty chunks
   641 			// Remove empty chunks
   646 			each(base, function(k) {
   642 			each(base, function(k) {
   673 
   669 
   674 			i = base.length - nb;
   670 			i = base.length - nb;
   675 
   671 
   676 			// If /a/b/c or /
   672 			// If /a/b/c or /
   677 			if (i <= 0)
   673 			if (i <= 0)
   678 				return '/' + o.reverse().join('/');
   674 				outPath = o.reverse().join('/');
   679 
   675 			else
   680 			return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');
   676 				outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/');
       
   677 
       
   678 			// Add front / if it's needed
       
   679 			if (outPath.indexOf('/') !== 0)
       
   680 				outPath = '/' + outPath;
       
   681 
       
   682 			// Add traling / if it's needed
       
   683 			if (tr && outPath.lastIndexOf('/') !== outPath.length - 1)
       
   684 				outPath += tr;
       
   685 
       
   686 			return outPath;
   681 		},
   687 		},
   682 
   688 
   683 		getURI : function(nh) {
   689 		getURI : function(nh) {
   684 			var s, t = this;
   690 			var s, t = this;
   685 
   691 
   713 				t.source = s;
   719 				t.source = s;
   714 			}
   720 			}
   715 
   721 
   716 			return t.source;
   722 			return t.source;
   717 		}
   723 		}
   718 
   724 	});
   719 		});
       
   720 })();
   725 })();
   721 
       
   722 /* file:jscripts/tiny_mce/classes/util/Cookie.js */
       
   723 
       
   724 (function() {
   726 (function() {
   725 	var each = tinymce.each;
   727 	var each = tinymce.each;
   726 
   728 
   727 	tinymce.create('static tinymce.util.Cookie', {
   729 	tinymce.create('static tinymce.util.Cookie', {
   728 		getHash : function(n) {
   730 		getHash : function(n) {
   787 
   789 
   788 			d.setTime(d.getTime() - 1000);
   790 			d.setTime(d.getTime() - 1000);
   789 
   791 
   790 			this.set(n, '', d, p, d);
   792 			this.set(n, '', d, p, d);
   791 		}
   793 		}
   792 
   794 	});
   793 		});
       
   794 })();
   795 })();
   795 
       
   796 /* file:jscripts/tiny_mce/classes/util/JSON.js */
       
   797 
       
   798 tinymce.create('static tinymce.util.JSON', {
   796 tinymce.create('static tinymce.util.JSON', {
   799 	serialize : function(o) {
   797 	serialize : function(o) {
   800 		var i, v, s = tinymce.util.JSON.serialize, t;
   798 		var i, v, s = tinymce.util.JSON.serialize, t;
   801 
   799 
   802 		if (o == null)
   800 		if (o == null)
   818 				return '\\u' + '0000'.substring(a.length) + a;
   816 				return '\\u' + '0000'.substring(a.length) + a;
   819 			}) + '"';
   817 			}) + '"';
   820 		}
   818 		}
   821 
   819 
   822 		if (t == 'object') {
   820 		if (t == 'object') {
   823 			if (o instanceof Array) {
   821 			if (o.hasOwnProperty && o instanceof Array) {
   824 					for (i=0, v = '['; i<o.length; i++)
   822 					for (i=0, v = '['; i<o.length; i++)
   825 						v += (i > 0 ? ',' : '') + s(o[i]);
   823 						v += (i > 0 ? ',' : '') + s(o[i]);
   826 
   824 
   827 					return v + ']';
   825 					return v + ']';
   828 				}
   826 				}
   845 			// Ignore
   843 			// Ignore
   846 		}
   844 		}
   847 	}
   845 	}
   848 
   846 
   849 	});
   847 	});
   850 
       
   851 /* file:jscripts/tiny_mce/classes/util/XHR.js */
       
   852 
       
   853 tinymce.create('static tinymce.util.XHR', {
   848 tinymce.create('static tinymce.util.XHR', {
   854 	send : function(o) {
   849 	send : function(o) {
   855 		var x, t, w = window, c = 0;
   850 		var x, t, w = window, c = 0;
   856 
   851 
   857 		// Default settings
   852 		// Default settings
   881 			x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);
   876 			x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);
   882 
   877 
   883 			if (o.content_type)
   878 			if (o.content_type)
   884 				x.setRequestHeader('Content-Type', o.content_type);
   879 				x.setRequestHeader('Content-Type', o.content_type);
   885 
   880 
       
   881 			x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
       
   882 
   886 			x.send(o.data);
   883 			x.send(o.data);
   887 
   884 
   888 			function ready() {
   885 			function ready() {
   889 				if (!o.async || x.readyState == 4 || c++ > 10000) {
   886 				if (!o.async || x.readyState == 4 || c++ > 10000) {
   890 					if (o.success && c < 10000 && x.status == 200)
   887 					if (o.success && c < 10000 && x.status == 200)
   902 				return ready();
   899 				return ready();
   903 
   900 
   904 			// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
   901 			// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
   905 			t = w.setTimeout(ready, 10);
   902 			t = w.setTimeout(ready, 10);
   906 		}
   903 		}
   907 
   904 	}
   908 		}
       
   909 });
   905 });
   910 
       
   911 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */
       
   912 
       
   913 (function() {
   906 (function() {
   914 	var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
   907 	var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
   915 
   908 
   916 	tinymce.create('tinymce.util.JSONRequest', {
   909 	tinymce.create('tinymce.util.JSONRequest', {
   917 		JSONRequest : function(s) {
   910 		JSONRequest : function(s) {
   959 		'static' : {
   952 		'static' : {
   960 			sendRPC : function(o) {
   953 			sendRPC : function(o) {
   961 				return new tinymce.util.JSONRequest().send(o);
   954 				return new tinymce.util.JSONRequest().send(o);
   962 			}
   955 			}
   963 		}
   956 		}
   964 
   957 	});
   965 		});
   958 }());(function(tinymce) {
   966 }());
       
   967 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */
       
   968 
       
   969 (function() {
       
   970 	// Shorten names
   959 	// Shorten names
   971 	var each = tinymce.each, is = tinymce.is;
   960 	var each = tinymce.each, is = tinymce.is;
   972 	var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE;
   961 	var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE;
   973 
   962 
   974 	tinymce.create('tinymce.dom.DOMUtils', {
   963 	tinymce.create('tinymce.dom.DOMUtils', {
   975 		doc : null,
   964 		doc : null,
   976 		root : null,
   965 		root : null,
   977 		files : null,
   966 		files : null,
   978 		listeners : {},
       
   979 		pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,
   967 		pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,
   980 		cache : {},
       
   981 		idPattern : /^#[\w]+$/,
       
   982 		elmPattern : /^[\w_*]+$/,
       
   983 		elmClassPattern : /^([\w_]*)\.([\w_]+)$/,
       
   984 		props : {
   968 		props : {
   985 			"for" : "htmlFor",
   969 			"for" : "htmlFor",
   986 			"class" : "className",
   970 			"class" : "className",
   987 			className : "className",
   971 			className : "className",
   988 			checked : "checked",
   972 			checked : "checked",
  1005 			t.cssFlicker = false;
   989 			t.cssFlicker = false;
  1006 			t.counter = 0;
   990 			t.counter = 0;
  1007 			t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 
   991 			t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 
  1008 			t.stdMode = d.documentMode === 8;
   992 			t.stdMode = d.documentMode === 8;
  1009 
   993 
  1010 			this.settings = s = tinymce.extend({
   994 			t.settings = s = tinymce.extend({
  1011 				keep_values : false,
   995 				keep_values : false,
  1012 				hex_colors : 1,
   996 				hex_colors : 1,
  1013 				process_html : 1
   997 				process_html : 1
  1014 			}, s);
   998 			}, s);
  1015 
   999 
  1082 				h : parseInt(h) || e.offsetHeight || e.clientHeight
  1066 				h : parseInt(h) || e.offsetHeight || e.clientHeight
  1083 			};
  1067 			};
  1084 		},
  1068 		},
  1085 
  1069 
  1086 		getParent : function(n, f, r) {
  1070 		getParent : function(n, f, r) {
  1087 			var na, se = this.settings;
  1071 			return this.getParents(n, f, r, false);
  1088 
  1072 		},
  1089 			n = this.get(n);
  1073 
       
  1074 		getParents : function(n, f, r, c) {
       
  1075 			var t = this, na, se = t.settings, o = [];
       
  1076 
       
  1077 			n = t.get(n);
       
  1078 			c = c === undefined;
  1090 
  1079 
  1091 			if (se.strict_root)
  1080 			if (se.strict_root)
  1092 				r = r || this.getRoot();
  1081 				r = r || t.getRoot();
  1093 
  1082 
  1094 			// Wrap node name as func
  1083 			// Wrap node name as func
  1095 			if (is(f, 'string')) {
  1084 			if (is(f, 'string')) {
  1096 				na = f.toUpperCase();
  1085 				na = f;
  1097 
  1086 
  1098 				f = function(n) {
  1087 				if (f === '*') {
  1099 					var s = false;
  1088 					f = function(n) {return n.nodeType == 1;};
  1100 
  1089 				} else {
  1101 					// Any element
  1090 					f = function(n) {
  1102 					if (n.nodeType == 1 && na === '*') {
  1091 						return t.is(n, na);
  1103 						s = true;
  1092 					};
  1104 						return false;
  1093 				}
  1105 					}
       
  1106 
       
  1107 					each(na.split(','), function(v) {
       
  1108 						if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName.toUpperCase() == v)) {
       
  1109 							s = true;
       
  1110 							return false; // Break loop
       
  1111 						}
       
  1112 					});
       
  1113 
       
  1114 					return s;
       
  1115 				};
       
  1116 			}
  1094 			}
  1117 
  1095 
  1118 			while (n) {
  1096 			while (n) {
  1119 				if (n == r)
  1097 				if (n == r || !n.nodeType || n.nodeType === 9)
  1120 					return null;
  1098 					break;
  1121 
  1099 
  1122 				if (f(n))
  1100 				if (!f || f(n)) {
  1123 					return n;
  1101 					if (c)
       
  1102 						o.push(n);
       
  1103 					else
       
  1104 						return n;
       
  1105 				}
  1124 
  1106 
  1125 				n = n.parentNode;
  1107 				n = n.parentNode;
  1126 			}
  1108 			}
  1127 
  1109 
  1128 			return null;
  1110 			return c ? o : null;
  1129 		},
  1111 		},
  1130 
  1112 
  1131 		get : function(e) {
  1113 		get : function(e) {
  1132 			var n;
  1114 			var n;
  1133 
  1115 
  1141 			}
  1123 			}
  1142 
  1124 
  1143 			return e;
  1125 			return e;
  1144 		},
  1126 		},
  1145 
  1127 
  1146 		
  1128 		getNext : function(node, selector) {
  1147 		// #if !jquery
  1129 			return this._findSib(node, selector, 'nextSibling');
       
  1130 		},
       
  1131 
       
  1132 		getPrev : function(node, selector) {
       
  1133 			return this._findSib(node, selector, 'previousSibling');
       
  1134 		},
       
  1135 
  1148 
  1136 
  1149 		select : function(pa, s) {
  1137 		select : function(pa, s) {
  1150 			var t = this, cs, c, pl, o = [], x, i, l, n, xp;
  1138 			var t = this;
  1151 
  1139 
  1152 			s = t.get(s) || t.doc;
  1140 			return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []);
  1153 
  1141 		},
  1154 			// Look for native support and use that if it's found
  1142 
  1155 			if (s.querySelectorAll) {
  1143 		is : function(n, patt) {
  1156 				// Element scope then use temp id
  1144 			return tinymce.dom.Sizzle.matches(patt, n.nodeType ? [n] : n).length > 0;
  1157 				// We need to do this to be compatible with other implementations
  1145 		},
  1158 				// See bug report: http://bugs.webkit.org/show_bug.cgi?id=17461
  1146 
  1159 				if (s != t.doc) {
       
  1160 					i = s.id;
       
  1161 					s.id = '_mc_tmp';
       
  1162 					pa = '#_mc_tmp ' + pa;
       
  1163 				}
       
  1164 
       
  1165 				// Select elements
       
  1166 				l = tinymce.grep(s.querySelectorAll(pa));
       
  1167 
       
  1168 				// Restore old id
       
  1169 				s.id = i;
       
  1170 
       
  1171 				return l;
       
  1172 			}
       
  1173 
       
  1174 			if (!t.selectorRe)
       
  1175 				t.selectorRe = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i;;
       
  1176 
       
  1177 			// Air doesn't support eval due to security sandboxing and querySelectorAll isn't supported yet
       
  1178 			if (tinymce.isAir) {
       
  1179 				each(tinymce.explode(pa), function(v) {
       
  1180 					if (!(xp = t.cache[v])) {
       
  1181 						xp = '';
       
  1182 
       
  1183 						each(v.split(' '), function(v) {
       
  1184 							v = t.selectorRe.exec(v);
       
  1185 
       
  1186 							xp += v[1] ? '//' + v[1] : '//*';
       
  1187 
       
  1188 							// Id
       
  1189 							if (v[2])
       
  1190 								xp += "[@id='" + v[2] + "']";
       
  1191 
       
  1192 							// Class
       
  1193 							if (v[3]) {
       
  1194 								each(v[3].split('.'), function(n) {
       
  1195 									xp += "[@class = '" + n + "' or contains(concat(' ', @class, ' '), ' " + n + " ')]";
       
  1196 								});
       
  1197 							}
       
  1198 						});
       
  1199 
       
  1200 						t.cache[v] = xp;
       
  1201 					}
       
  1202 
       
  1203 					xp = t.doc.evaluate(xp, s, null, 4, null);
       
  1204 
       
  1205 					while (n = xp.iterateNext())
       
  1206 						o.push(n);
       
  1207 				});
       
  1208 
       
  1209 				return o;
       
  1210 			}
       
  1211 
       
  1212 			if (t.settings.strict) {
       
  1213 				function get(s, n) {
       
  1214 					return s.getElementsByTagName(n.toLowerCase());
       
  1215 				};
       
  1216 			} else {
       
  1217 				function get(s, n) {
       
  1218 					return s.getElementsByTagName(n);
       
  1219 				};
       
  1220 			}
       
  1221 
       
  1222 			// Simple element pattern. For example: "p" or "*"
       
  1223 			if (t.elmPattern.test(pa)) {
       
  1224 				x = get(s, pa);
       
  1225 
       
  1226 				for (i = 0, l = x.length; i<l; i++)
       
  1227 					o.push(x[i]);
       
  1228 
       
  1229 				return o;
       
  1230 			}
       
  1231 
       
  1232 			// Simple class pattern. For example: "p.class" or ".class"
       
  1233 			if (t.elmClassPattern.test(pa)) {
       
  1234 				pl = t.elmClassPattern.exec(pa);
       
  1235 				x = get(s, pl[1] || '*');
       
  1236 				c = ' ' + pl[2] + ' ';
       
  1237 
       
  1238 				for (i = 0, l = x.length; i<l; i++) {
       
  1239 					n = x[i];
       
  1240 
       
  1241 					if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1)
       
  1242 						o.push(n);
       
  1243 				}
       
  1244 
       
  1245 				return o;
       
  1246 			}
       
  1247 
       
  1248 			function collect(n) {
       
  1249 				if (!n.mce_save) {
       
  1250 					n.mce_save = 1;
       
  1251 					o.push(n);
       
  1252 				}
       
  1253 			};
       
  1254 
       
  1255 			function collectIE(n) {
       
  1256 				if (!n.getAttribute('mce_save')) {
       
  1257 					n.setAttribute('mce_save', '1');
       
  1258 					o.push(n);
       
  1259 				}
       
  1260 			};
       
  1261 
       
  1262 			function find(n, f, r) {
       
  1263 				var i, l, nl = get(r, n);
       
  1264 
       
  1265 				for (i = 0, l = nl.length; i < l; i++)
       
  1266 					f(nl[i]);
       
  1267 			};
       
  1268 
       
  1269 			each(pa.split(','), function(v, i) {
       
  1270 				v = tinymce.trim(v);
       
  1271 
       
  1272 				// Simple element pattern, most common in TinyMCE
       
  1273 				if (t.elmPattern.test(v)) {
       
  1274 					each(get(s, v), function(n) {
       
  1275 						collect(n);
       
  1276 					});
       
  1277 
       
  1278 					return;
       
  1279 				}
       
  1280 
       
  1281 				// Simple element pattern with class, fairly common in TinyMCE
       
  1282 				if (t.elmClassPattern.test(v)) {
       
  1283 					x = t.elmClassPattern.exec(v);
       
  1284 
       
  1285 					each(get(s, x[1]), function(n) {
       
  1286 						if (t.hasClass(n, x[2]))
       
  1287 							collect(n);
       
  1288 					});
       
  1289 
       
  1290 					return;
       
  1291 				}
       
  1292 
       
  1293 				if (!(cs = t.cache[pa])) {
       
  1294 					cs = 'x=(function(cf, s) {';
       
  1295 					pl = v.split(' ');
       
  1296 
       
  1297 					each(pl, function(v) {
       
  1298 						var p = t.selectorRe.exec(v);
       
  1299 
       
  1300 						// Find elements
       
  1301 						p[1] = p[1] || '*';
       
  1302 						cs += 'find("' + p[1] + '", function(n) {';
       
  1303 
       
  1304 						// Check id
       
  1305 						if (p[2])
       
  1306 							cs += 'if (n.id !== "' + p[2] + '") return;';
       
  1307 
       
  1308 						// Check classes
       
  1309 						if (p[3]) {
       
  1310 							cs += 'var c = " " + n.className + " ";';
       
  1311 							cs += 'if (';
       
  1312 							c = '';
       
  1313 							each(p[3].split('.'), function(v) {
       
  1314 								if (v)
       
  1315 									c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1';
       
  1316 							});
       
  1317 							cs += c + ') return;';
       
  1318 						}
       
  1319 					});
       
  1320 
       
  1321 					cs += 'cf(n);';
       
  1322 
       
  1323 					for (i = pl.length - 1; i >= 0; i--)
       
  1324 						cs += '}, ' + (i ? 'n' : 's') + ');';
       
  1325 
       
  1326 					cs += '})';
       
  1327 
       
  1328 					// Compile CSS pattern function
       
  1329 					t.cache[pa] = cs = eval(cs);
       
  1330 				}
       
  1331 
       
  1332 				// Run selector function
       
  1333 				cs(isIE ? collectIE : collect, s);
       
  1334 			});
       
  1335 
       
  1336 			// Cleanup
       
  1337 			each(o, function(n) {
       
  1338 				if (isIE)
       
  1339 					n.removeAttribute('mce_save');
       
  1340 				else
       
  1341 					delete n.mce_save;
       
  1342 			});
       
  1343 
       
  1344 			return o;
       
  1345 		},
       
  1346 
       
  1347 		// #endif
       
  1348 
  1147 
  1349 		add : function(p, n, a, h, c) {
  1148 		add : function(p, n, a, h, c) {
  1350 			var t = this;
  1149 			var t = this;
  1351 
  1150 
  1352 			return this.run(p, function(p) {
  1151 			return this.run(p, function(p) {
  1385 
  1184 
  1386 			return o + ' />';
  1185 			return o + ' />';
  1387 		},
  1186 		},
  1388 
  1187 
  1389 		remove : function(n, k) {
  1188 		remove : function(n, k) {
       
  1189 			var t = this;
       
  1190 
  1390 			return this.run(n, function(n) {
  1191 			return this.run(n, function(n) {
  1391 				var p, g;
  1192 				var p, g, i;
  1392 
  1193 
  1393 				p = n.parentNode;
  1194 				p = n.parentNode;
  1394 
  1195 
  1395 				if (!p)
  1196 				if (!p)
  1396 					return null;
  1197 					return null;
  1397 
  1198 
  1398 				if (k) {
  1199 				if (k) {
  1399 					each (n.childNodes, function(c) {
  1200 					for (i = n.childNodes.length - 1; i >= 0; i--)
  1400 						p.insertBefore(c.cloneNode(true), n);
  1201 						t.insertAfter(n.childNodes[i], n);
  1401 					});
  1202 
       
  1203 					//each(n.childNodes, function(c) {
       
  1204 					//	p.insertBefore(c.cloneNode(true), n);
       
  1205 					//});
  1402 				}
  1206 				}
  1403 
  1207 
  1404 				// Fix IE psuedo leak
  1208 				// Fix IE psuedo leak
  1405 		/*		if (isIE) {
  1209 				if (t.fixPsuedoLeaks) {
  1406 					p = n.cloneNode(true);
  1210 					p = n.cloneNode(true);
  1407 					n.outerHTML = '';
  1211 					k = 'IELeakGarbageBin';
       
  1212 					g = t.get(k) || t.add(t.doc.body, 'div', {id : k, style : 'display:none'});
       
  1213 					g.appendChild(n);
       
  1214 					g.innerHTML = '';
  1408 
  1215 
  1409 					return p;
  1216 					return p;
  1410 				}*/
  1217 				}
  1411 
  1218 
  1412 				return p.removeChild(n);
  1219 				return p.removeChild(n);
  1413 			});
  1220 			});
  1414 		},
  1221 		},
  1415 
       
  1416 		// #if !jquery
       
  1417 
  1222 
  1418 		setStyle : function(n, na, v) {
  1223 		setStyle : function(n, na, v) {
  1419 			var t = this;
  1224 			var t = this;
  1420 
  1225 
  1421 			return t.run(n, function(e) {
  1226 			return t.run(n, function(e) {
  1582 					t.setAttrib(e, n, v);
  1387 					t.setAttrib(e, n, v);
  1583 				});
  1388 				});
  1584 			});
  1389 			});
  1585 		},
  1390 		},
  1586 
  1391 
  1587 		// #endif
       
  1588 
       
  1589 		getAttrib : function(e, n, dv) {
  1392 		getAttrib : function(e, n, dv) {
  1590 			var v, t = this;
  1393 			var v, t = this;
  1591 
  1394 
  1592 			e = t.get(e);
  1395 			e = t.get(e);
  1593 
  1396 
  1610 				v = v && v.nodeValue ? v.nodeValue : v;
  1413 				v = v && v.nodeValue ? v.nodeValue : v;
  1611 			}
  1414 			}
  1612 
  1415 
  1613 			if (!v)
  1416 			if (!v)
  1614 				v = e.getAttribute(n, 2);
  1417 				v = e.getAttribute(n, 2);
       
  1418 
       
  1419 			// Check boolean attribs
       
  1420 			if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) {
       
  1421 				if (e[t.props[n]] === true && v === '')
       
  1422 					return n;
       
  1423 
       
  1424 				return v ? n : '';
       
  1425 			}
       
  1426 
       
  1427 			// Inner input elements will override attributes on form elements
       
  1428 			if (e.nodeName === "FORM" && e.getAttributeNode(n))
       
  1429 				return e.getAttributeNode(n).nodeValue;
  1615 
  1430 
  1616 			if (n === 'style') {
  1431 			if (n === 'style') {
  1617 				v = v || e.style.cssText;
  1432 				v = v || e.style.cssText;
  1618 
  1433 
  1619 				if (v) {
  1434 				if (v) {
  1639 
  1454 
  1640 						break;
  1455 						break;
  1641 
  1456 
  1642 					case 'size':
  1457 					case 'size':
  1643 						// IE returns +0 as default value for size
  1458 						// IE returns +0 as default value for size
  1644 						if (v === '+0' || v === 20)
  1459 						if (v === '+0' || v === 20 || v === 0)
  1645 							v = '';
  1460 							v = '';
  1646 
  1461 
  1647 						break;
  1462 						break;
  1648 
  1463 
  1649 					case 'width':
  1464 					case 'width':
  1670 						if (v === 32768 || v === 2147483647 || v === '32768')
  1485 						if (v === 32768 || v === 2147483647 || v === '32768')
  1671 							v = '';
  1486 							v = '';
  1672 
  1487 
  1673 						break;
  1488 						break;
  1674 
  1489 
       
  1490 					case 'multiple':
  1675 					case 'compact':
  1491 					case 'compact':
  1676 					case 'noshade':
  1492 					case 'noshade':
  1677 					case 'nowrap':
  1493 					case 'nowrap':
  1678 						if (v === 65535)
  1494 						if (v === 65535)
  1679 							return n;
  1495 							return n;
  1685 						break;
  1501 						break;
  1686 
  1502 
  1687 					default:
  1503 					default:
  1688 						// IE has odd anonymous function for event attributes
  1504 						// IE has odd anonymous function for event attributes
  1689 						if (n.indexOf('on') === 0 && v)
  1505 						if (n.indexOf('on') === 0 && v)
  1690 							v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
  1506 							v = ('' + v).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1');
  1691 				}
  1507 				}
  1692 			}
  1508 			}
  1693 
  1509 
  1694 			return (v !== undefined && v !== null && v !== '') ? '' + v : dv;
  1510 			return (v !== undefined && v !== null && v !== '') ? '' + v : dv;
  1695 		},
  1511 		},
  1696 
  1512 
  1697 		getPos : function(n) {
  1513 		getPos : function(n, ro) {
  1698 			var t = this, x = 0, y = 0, e, d = t.doc, r;
  1514 			var t = this, x = 0, y = 0, e, d = t.doc, r;
  1699 
  1515 
  1700 			n = t.get(n);
  1516 			n = t.get(n);
  1701 
  1517 			ro = ro || d.body;
  1702 			// Use getBoundingClientRect on IE, Opera has it but it's not perfect
  1518 
  1703 			if (n && isIE) {
  1519 			if (n) {
  1704 				n = n.getBoundingClientRect();
  1520 				// Use getBoundingClientRect on IE, Opera has it but it's not perfect
  1705 				e = t.boxModel ? d.documentElement : d.body;
  1521 				if (isIE && !t.stdMode) {
  1706 				x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border
  1522 					n = n.getBoundingClientRect();
  1707 				x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;
  1523 					e = t.boxModel ? d.documentElement : d.body;
  1708 				n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
  1524 					x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border
  1709 
  1525 					x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;
  1710 				return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};
  1526 					n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
  1711 			}
  1527 
  1712 
  1528 					return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};
  1713 			r = n;
  1529 				}
  1714 			while (r) {
  1530 
  1715 				x += r.offsetLeft || 0;
  1531 				r = n;
  1716 				y += r.offsetTop || 0;
  1532 				while (r && r != ro && r.nodeType) {
  1717 				r = r.offsetParent;
  1533 					x += r.offsetLeft || 0;
  1718 			}
  1534 					y += r.offsetTop || 0;
  1719 
  1535 					r = r.offsetParent;
  1720 			r = n;
  1536 				}
  1721 			while (r) {
  1537 
  1722 				// Opera 9.25 bug fix, fixed in 9.50
  1538 				r = n.parentNode;
  1723 				if (!/^table-row|inline.*/i.test(t.getStyle(r, "display", 1))) {
  1539 				while (r && r != ro && r.nodeType) {
  1724 					x -= r.scrollLeft || 0;
  1540 					x -= r.scrollLeft || 0;
  1725 					y -= r.scrollTop || 0;
  1541 					y -= r.scrollTop || 0;
  1726 				}
  1542 					r = r.parentNode;
  1727 
  1543 				}
  1728 				r = r.parentNode;
       
  1729 
       
  1730 				if (r == d.body)
       
  1731 					break;
       
  1732 			}
  1544 			}
  1733 
  1545 
  1734 			return {x : x, y : y};
  1546 			return {x : x, y : y};
  1735 		},
  1547 		},
  1736 
  1548 
  1854 
  1666 
  1855 			return s;
  1667 			return s;
  1856 		},
  1668 		},
  1857 
  1669 
  1858 		loadCSS : function(u) {
  1670 		loadCSS : function(u) {
  1859 			var t = this, d = t.doc;
  1671 			var t = this, d = t.doc, head;
  1860 
  1672 
  1861 			if (!u)
  1673 			if (!u)
  1862 				u = '';
  1674 				u = '';
  1863 
  1675 
       
  1676 			head = t.select('head')[0];
       
  1677 
  1864 			each(u.split(','), function(u) {
  1678 			each(u.split(','), function(u) {
       
  1679 				var link;
       
  1680 
  1865 				if (t.files[u])
  1681 				if (t.files[u])
  1866 					return;
  1682 					return;
  1867 
  1683 
  1868 				t.files[u] = true;
  1684 				t.files[u] = true;
  1869 				t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : tinymce._addVer(u)});
  1685 				link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)});
       
  1686 
       
  1687 				// IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug
       
  1688 				// This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading
       
  1689 				// It's ugly but it seems to work fine.
       
  1690 				if (isIE && d.documentMode) {
       
  1691 					link.onload = function() {
       
  1692 						d.recalc();
       
  1693 						link.onload = null;
       
  1694 					};
       
  1695 				}
       
  1696 
       
  1697 				head.appendChild(link);
  1870 			});
  1698 			});
  1871 		},
  1699 		},
  1872 
       
  1873 		// #if !jquery
       
  1874 
  1700 
  1875 		addClass : function(e, c) {
  1701 		addClass : function(e, c) {
  1876 			return this.run(e, function(e) {
  1702 			return this.run(e, function(e) {
  1877 				var o;
  1703 				var o;
  1878 
  1704 
  1927 		isHidden : function(e) {
  1753 		isHidden : function(e) {
  1928 			e = this.get(e);
  1754 			e = this.get(e);
  1929 
  1755 
  1930 			return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';
  1756 			return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';
  1931 		},
  1757 		},
  1932 
       
  1933 		// #endif
       
  1934 
  1758 
  1935 		uniqueId : function(p) {
  1759 		uniqueId : function(p) {
  1936 			return (!p ? 'mce_' : p) + (this.counter++);
  1760 			return (!p ? 'mce_' : p) + (this.counter++);
  1937 		},
  1761 		},
  1938 
  1762 
  1999 
  1823 
  2000 					// Time to fix the madness IE left us
  1824 					// Time to fix the madness IE left us
  2001 					if (x) {
  1825 					if (x) {
  2002 						// So if we replace the p elements with divs and mark them and then replace them back to paragraphs
  1826 						// So if we replace the p elements with divs and mark them and then replace them back to paragraphs
  2003 						// after we use innerHTML we can fix the DOM tree
  1827 						// after we use innerHTML we can fix the DOM tree
  2004 						h = h.replace(/<p ([^>]+)>|<p>/g, '<div $1 mce_tmp="1">');
  1828 						h = h.replace(/<p ([^>]+)>|<p>/ig, '<div $1 mce_tmp="1">');
  2005 						h = h.replace(/<\/p>/g, '</div>');
  1829 						h = h.replace(/<\/p>/g, '</div>');
  2006 
  1830 
  2007 						// Set the new HTML with DIVs
  1831 						// Set the new HTML with DIVs
  2008 						set();
  1832 						set();
  2009 
  1833 
  2050 				return h;
  1874 				return h;
  2051 			});
  1875 			});
  2052 		},
  1876 		},
  2053 
  1877 
  2054 		processHTML : function(h) {
  1878 		processHTML : function(h) {
  2055 			var t = this, s = t.settings;
  1879 			var t = this, s = t.settings, codeBlocks = [];
  2056 
  1880 
  2057 			if (!s.process_html)
  1881 			if (!s.process_html)
  2058 				return h;
  1882 				return h;
  2059 
  1883 
  2060 			// Convert strong and em to b and i in FF since it can't handle them
  1884 			// Convert strong and em to b and i in FF since it can't handle them
  2070 			h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open
  1894 			h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open
  2071 
  1895 
  2072 			// Store away src and href in mce_src and mce_href since browsers mess them up
  1896 			// Store away src and href in mce_src and mce_href since browsers mess them up
  2073 			if (s.keep_values) {
  1897 			if (s.keep_values) {
  2074 				// Wrap scripts and styles in comments for serialization purposes
  1898 				// Wrap scripts and styles in comments for serialization purposes
  2075 				if (/<script|style/.test(h)) {
  1899 				if (/<script|noscript|style/i.test(h)) {
  2076 					function trim(s) {
  1900 					function trim(s) {
  2077 						// Remove prefix and suffix code for element
  1901 						// Remove prefix and suffix code for element
  2078 						s = s.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n');
  1902 						s = s.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n');
  2079 						s = s.replace(/^[\r\n]*|[\r\n]*$/g, '');
  1903 						s = s.replace(/^[\r\n]*|[\r\n]*$/g, '');
  2080 						s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<!\[CDATA\[|<!--|<!\[CDATA\[)[\r\n]*/g, '');
  1904 						s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<!\[CDATA\[|<!--|<!\[CDATA\[)[\r\n]*/g, '');
  2081 						s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->|\]\]-->)\s*$/g, '');
  1905 						s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->|\]\]-->)\s*$/g, '');
  2082 
  1906 
  2083 						return s;
  1907 						return s;
  2084 					};
  1908 					};
  2085 
  1909 
  2086 					// Preserve script elements
  1910 					// Wrap the script contents in CDATA and keep them from executing
  2087 					h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g, function(v, a, b) {
  1911 					h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/gi, function(v, attribs, text) {
  2088 						// Remove prefix and suffix code for script element
       
  2089 						b = trim(b);
       
  2090 
       
  2091 						// Force type attribute
  1912 						// Force type attribute
  2092 						if (!a)
  1913 						if (!attribs)
  2093 							a = ' type="text/javascript"';
  1914 							attribs = ' type="text/javascript"';
  2094 
  1915 
  2095 						// Wrap contents in a comment
  1916 						// Convert the src attribute of the scripts
  2096 						if (b)
  1917 						attribs = attribs.replace(/src=\"([^\"]+)\"?/i, function(a, url) {
  2097 							b = '<!--\n' + b + '\n// -->';
  1918 							if (s.url_converter)
  2098 
  1919 								url = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(url), 'src', 'script'));
  2099 						// Output fake element
  1920 
  2100 						return '<mce:script' + a + '>' + b + '</mce:script>';
  1921 							return 'mce_src="' + url + '"';
       
  1922 						});
       
  1923 
       
  1924 						// Wrap text contents
       
  1925 						if (tinymce.trim(text)) {
       
  1926 							codeBlocks.push(trim(text));
       
  1927 							text = '<!--\nMCE_SCRIPT:' + (codeBlocks.length - 1) + '\n// -->';
       
  1928 						}
       
  1929 
       
  1930 						return '<mce:script' + attribs + '>' + text + '</mce:script>';
  2101 					});
  1931 					});
  2102 
  1932 
  2103 					// Preserve style elements
  1933 					// Wrap style elements
  2104 					h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g, function(v, a, b) {
  1934 					h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/gi, function(v, attribs, text) {
  2105 						b = trim(b);
  1935 						// Wrap text contents
  2106 						return '<mce:style' + a + '><!--\n' + b + '\n--></mce:style><style' + a + ' mce_bogus="1">' + b + '</style>';
  1936 						if (text) {
       
  1937 							codeBlocks.push(trim(text));
       
  1938 							text = '<!--\nMCE_SCRIPT:' + (codeBlocks.length - 1) + '\n-->';
       
  1939 						}
       
  1940 
       
  1941 						return '<mce:style' + attribs + '>' + text + '</mce:style><style ' + attribs + ' mce_bogus="1">' + text + '</style>';
  2107 					});
  1942 					});
       
  1943 
       
  1944 					// Wrap noscript elements
       
  1945 					h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {
       
  1946 						return '<mce:noscript' + attribs + '><!--' + t.encode(text).replace(/--/g, '&#45;&#45;') + '--></mce:noscript>';
       
  1947 					});
  2108 				}
  1948 				}
  2109 
  1949 
  2110 				h = h.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g, '<!--[CDATA[$1]]-->');
  1950 				h = h.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g, '<!--[CDATA[$1]]-->');
       
  1951 
       
  1952 				// Remove false bool attributes and force attributes into xhtml style attr="attr"
       
  1953 				h = h.replace(/<([\w:]+) [^>]*(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)[^>]*>/gi, function(val) {
       
  1954 					function handle(val, name, value) {
       
  1955 						// Remove false/0 attribs
       
  1956 						if (value === 'false' || value === '0')
       
  1957 							return '';
       
  1958 
       
  1959 						return ' ' + name + '="' + name + '"';
       
  1960 					};
       
  1961 
       
  1962 					val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\"]([^\"]+)[\"]/gi, handle); // W3C
       
  1963 					val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\']([^\']+)[\']/gi, handle); // W3C
       
  1964 					val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=([^\s\"\'>]+)/gi, handle); // IE
       
  1965 					val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)([\s>])/gi, ' $1="$1"$2'); // Force attr="attr"
       
  1966 
       
  1967 					return val;
       
  1968 				});
  2111 
  1969 
  2112 				// Process all tags with src, href or style
  1970 				// Process all tags with src, href or style
  2113 				h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) {
  1971 				h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) {
  2114 					function handle(m, b, c) {
  1972 					function handle(m, b, c) {
  2115 						var u = c;
  1973 						var u = c;
  2117 						// Tag already got a mce_ version
  1975 						// Tag already got a mce_ version
  2118 						if (a.indexOf('mce_' + b) != -1)
  1976 						if (a.indexOf('mce_' + b) != -1)
  2119 							return m;
  1977 							return m;
  2120 
  1978 
  2121 						if (b == 'style') {
  1979 						if (b == 'style') {
  2122 							// Why did I need this one?
       
  2123 							//if (isIE)
       
  2124 							//	u = t.serializeStyle(t.parseStyle(u));
       
  2125 
       
  2126 							// No mce_style for elements with these since they might get resized by the user
  1980 							// No mce_style for elements with these since they might get resized by the user
  2127 							if (t._isRes(c))
  1981 							if (t._isRes(c))
  2128 								return m;
  1982 								return m;
  2129 
  1983 
  2130 							if (s.hex_colors) {
  1984 							// Parse and serialize the style to convert for example uppercase styles like "BORDER: 1px"
  2131 								u = u.replace(/rgb\([^\)]+\)/g, function(v) {
  1985 							u = t.encode(t.serializeStyle(t.parseStyle(u)));
  2132 									return t.toHex(v);
       
  2133 								});
       
  2134 							}
       
  2135 
       
  2136 							if (s.url_converter) {
       
  2137 								u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {
       
  2138 									return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';
       
  2139 								});
       
  2140 							}
       
  2141 						} else if (b != 'coords' && b != 'shape') {
  1986 						} else if (b != 'coords' && b != 'shape') {
  2142 							if (s.url_converter)
  1987 							if (s.url_converter)
  2143 								u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));
  1988 								u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));
  2144 						}
  1989 						}
  2145 
  1990 
  2149 					a = a.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi, handle); // W3C
  1994 					a = a.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi, handle); // W3C
  2150 					a = a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi, handle); // W3C
  1995 					a = a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi, handle); // W3C
  2151 
  1996 
  2152 					return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi, handle); // IE
  1997 					return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi, handle); // IE
  2153 				});
  1998 				});
       
  1999 
       
  2000 				// Restore script blocks
       
  2001 				h = h.replace(/MCE_SCRIPT:([0-9]+)/g, function(val, idx) {
       
  2002 					return codeBlocks[idx];
       
  2003 				});
  2154 			}
  2004 			}
  2155 
  2005 
  2156 			return h;
  2006 			return h;
  2157 		},
  2007 		},
  2158 
  2008 
  2162 			e = this.get(e);
  2012 			e = this.get(e);
  2163 
  2013 
  2164 			if (!e)
  2014 			if (!e)
  2165 				return null;
  2015 				return null;
  2166 
  2016 
  2167 			if (isIE)
  2017 			if (e.outerHTML !== undefined)
  2168 				return e.outerHTML;
  2018 				return e.outerHTML;
  2169 
  2019 
  2170 			d = (e.ownerDocument || this.doc).createElement("body");
  2020 			d = (e.ownerDocument || this.doc).createElement("body");
  2171 			d.appendChild(e.cloneNode(true));
  2021 			d.appendChild(e.cloneNode(true));
  2172 
  2022 
  2174 		},
  2024 		},
  2175 
  2025 
  2176 		setOuterHTML : function(e, h, d) {
  2026 		setOuterHTML : function(e, h, d) {
  2177 			var t = this;
  2027 			var t = this;
  2178 
  2028 
       
  2029 			function setHTML(e, h, d) {
       
  2030 				var n, tp;
       
  2031 				
       
  2032 				tp = d.createElement("body");
       
  2033 				tp.innerHTML = h;
       
  2034 
       
  2035 				n = tp.lastChild;
       
  2036 				while (n) {
       
  2037 					t.insertAfter(n.cloneNode(true), e);
       
  2038 					n = n.previousSibling;
       
  2039 				}
       
  2040 
       
  2041 				t.remove(e);
       
  2042 			};
       
  2043 
  2179 			return this.run(e, function(e) {
  2044 			return this.run(e, function(e) {
  2180 				var n, tp;
       
  2181 
       
  2182 				e = t.get(e);
  2045 				e = t.get(e);
  2183 				d = d || e.ownerDocument || t.doc;
  2046 
  2184 
  2047 				// Only set HTML on elements
  2185 				if (isIE && e.nodeType == 1)
  2048 				if (e.nodeType == 1) {
  2186 					e.outerHTML = h;
  2049 					d = d || e.ownerDocument || t.doc;
  2187 				else {
  2050 
  2188 					tp = d.createElement("body");
  2051 					if (isIE) {
  2189 					tp.innerHTML = h;
  2052 						try {
  2190 
  2053 							// Try outerHTML for IE it sometimes produces an unknown runtime error
  2191 					n = tp.lastChild;
  2054 							if (isIE && e.nodeType == 1)
  2192 					while (n) {
  2055 								e.outerHTML = h;
  2193 						t.insertAfter(n.cloneNode(true), e);
  2056 							else
  2194 						n = n.previousSibling;
  2057 								setHTML(e, h, d);
  2195 					}
  2058 						} catch (ex) {
  2196 
  2059 							// Fix for unknown runtime error
  2197 					t.remove(e);
  2060 							setHTML(e, h, d);
       
  2061 						}
       
  2062 					} else
       
  2063 						setHTML(e, h, d);
  2198 				}
  2064 				}
  2199 			});
  2065 			});
  2200 		},
  2066 		},
  2201 
  2067 
  2202 		decode : function(s) {
  2068 		decode : function(s) {
  2240 
  2106 
  2241 				return c;
  2107 				return c;
  2242 			}) : s;
  2108 			}) : s;
  2243 		},
  2109 		},
  2244 
  2110 
  2245 		// #if !jquery
       
  2246 
       
  2247 		insertAfter : function(n, r) {
  2111 		insertAfter : function(n, r) {
  2248 			var t = this;
  2112 			var t = this;
  2249 
  2113 
  2250 			r = t.get(r);
  2114 			r = t.get(r);
  2251 
  2115 
  2262 
  2126 
  2263 				return n;
  2127 				return n;
  2264 			});
  2128 			});
  2265 		},
  2129 		},
  2266 
  2130 
  2267 		// #endif
       
  2268 
       
  2269 		isBlock : function(n) {
  2131 		isBlock : function(n) {
  2270 			if (n.nodeType && n.nodeType !== 1)
  2132 			if (n.nodeType && n.nodeType !== 1)
  2271 				return false;
  2133 				return false;
  2272 
  2134 
  2273 			n = n.nodeName || n;
  2135 			n = n.nodeName || n;
  2274 
  2136 
  2275 			return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);
  2137 			return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TH|TBODY|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);
  2276 		},
  2138 		},
  2277 
       
  2278 		// #if !jquery
       
  2279 
  2139 
  2280 		replace : function(n, o, k) {
  2140 		replace : function(n, o, k) {
       
  2141 			var t = this;
       
  2142 
  2281 			if (is(o, 'array'))
  2143 			if (is(o, 'array'))
  2282 				n = n.cloneNode(true);
  2144 				n = n.cloneNode(true);
  2283 
  2145 
  2284 			return this.run(o, function(o) {
  2146 			return t.run(o, function(o) {
  2285 				if (k) {
  2147 				if (k) {
  2286 					each(o.childNodes, function(c) {
  2148 					each(o.childNodes, function(c) {
  2287 						n.appendChild(c.cloneNode(true));
  2149 						n.appendChild(c.cloneNode(true));
  2288 					});
  2150 					});
  2289 				}
  2151 				}
  2290 
  2152 
  2291 				// Fix IE psuedo leak for elements since replacing elements if fairly common
  2153 				// Fix IE psuedo leak for elements since replacing elements if fairly common
  2292 				// Will break parentNode for some unknown reason
  2154 				// Will break parentNode for some unknown reason
  2293 	/*			if (isIE && o.nodeType === 1) {
  2155 				if (t.fixPsuedoLeaks && o.nodeType === 1) {
  2294 					o.parentNode.insertBefore(n, o);
  2156 					o.parentNode.insertBefore(n, o);
  2295 					o.outerHTML = '';
  2157 					t.remove(o);
  2296 					return n;
  2158 					return n;
  2297 				}*/
  2159 				}
  2298 
  2160 
  2299 				return o.parentNode.replaceChild(n, o);
  2161 				return o.parentNode.replaceChild(n, o);
  2300 			});
  2162 			});
  2301 		},
  2163 		},
  2302 
  2164 
  2303 		// #endif
  2165 		findCommonAncestor : function(a, b) {
       
  2166 			var ps = a, pe;
       
  2167 
       
  2168 			while (ps) {
       
  2169 				pe = b;
       
  2170 
       
  2171 				while (pe && ps != pe)
       
  2172 					pe = pe.parentNode;
       
  2173 
       
  2174 				if (ps == pe)
       
  2175 					break;
       
  2176 
       
  2177 				ps = ps.parentNode;
       
  2178 			}
       
  2179 
       
  2180 			if (!ps && a.ownerDocument)
       
  2181 				return a.ownerDocument.documentElement;
       
  2182 
       
  2183 			return ps;
       
  2184 		},
  2304 
  2185 
  2305 		toHex : function(s) {
  2186 		toHex : function(s) {
  2306 			var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);
  2187 			var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);
  2307 
  2188 
  2308 			function hex(s) {
  2189 			function hex(s) {
  2422 
  2303 
  2423 				// Object will throw exception in IE
  2304 				// Object will throw exception in IE
  2424 				if (n.nodeName == 'OBJECT')
  2305 				if (n.nodeName == 'OBJECT')
  2425 					return n.attributes;
  2306 					return n.attributes;
  2426 
  2307 
       
  2308 				// IE doesn't keep the selected attribute if you clone option elements
       
  2309 				if (n.nodeName === 'OPTION' && this.getAttrib(n, 'selected'))
       
  2310 					o.push({specified : 1, nodeName : 'selected'});
       
  2311 
  2427 				// It's crazy that this is faster in IE but it's because it returns all attributes all the time
  2312 				// It's crazy that this is faster in IE but it's because it returns all attributes all the time
  2428 				n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {
  2313 				n.cloneNode(false).outerHTML.replace(/<\/?[\w:]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=\w+|>/gi, '').replace(/[\w:]+/gi, function(a) {
  2429 					o.push({specified : 1, nodeName : b});
  2314 					o.push({specified : 1, nodeName : a});
  2430 				});
  2315 				});
  2431 
  2316 
  2432 				return o;
  2317 				return o;
  2433 			}
  2318 			}
  2434 
  2319 
  2436 		},
  2321 		},
  2437 
  2322 
  2438 		destroy : function(s) {
  2323 		destroy : function(s) {
  2439 			var t = this;
  2324 			var t = this;
  2440 
  2325 
  2441 			t.win = t.doc = t.root = null;
  2326 			if (t.events)
       
  2327 				t.events.destroy();
       
  2328 
       
  2329 			t.win = t.doc = t.root = t.events = null;
  2442 
  2330 
  2443 			// Manual destroy then remove unload handler
  2331 			// Manual destroy then remove unload handler
  2444 			if (!s)
  2332 			if (!s)
  2445 				tinymce.removeUnload(t.destroy);
  2333 				tinymce.removeUnload(t.destroy);
       
  2334 		},
       
  2335 
       
  2336 		createRng : function() {
       
  2337 			var d = this.doc;
       
  2338 
       
  2339 			return d.createRange ? d.createRange() : new tinymce.dom.Range(this);
       
  2340 		},
       
  2341 
       
  2342 		split : function(pe, e, re) {
       
  2343 			var t = this, r = t.createRng(), bef, aft, pa;
       
  2344 
       
  2345 			// W3C valid browsers tend to leave empty nodes to the left/right side of the contents, this makes sence
       
  2346 			// but we don't want that in our code since it serves no purpose
       
  2347 			// For example if this is chopped:
       
  2348 			//   <p>text 1<span><b>CHOP</b></span>text 2</p>
       
  2349 			// would produce:
       
  2350 			//   <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p>
       
  2351 			// this function will then trim of empty edges and produce:
       
  2352 			//   <p>text 1</p><b>CHOP</b><p>text 2</p>
       
  2353 			function trimEdge(n, na) {
       
  2354 				n = n[na];
       
  2355 
       
  2356 				if (n && n[na] && n[na].nodeType == 1 && isEmpty(n[na]))
       
  2357 					t.remove(n[na]);
       
  2358 			};
       
  2359 
       
  2360 			function isEmpty(n) {
       
  2361 				n = t.getOuterHTML(n);
       
  2362 				n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
       
  2363 				n = n.replace(/<[^>]+>/g, ''); // Remove all tags
       
  2364 
       
  2365 				return n.replace(/[ \t\r\n]+|&nbsp;|&#160;/g, '') == '';
       
  2366 			};
       
  2367 
       
  2368 			// Added until Gecko can create real HTML documents using implementation.createHTMLDocument
       
  2369 			// this is to future proof it if Gecko decides to implement the error checking for range methods.
       
  2370 			function nodeIndex(n) {
       
  2371 				var i = 0;
       
  2372 
       
  2373 				while (n.previousSibling) {
       
  2374 					i++;
       
  2375 					n = n.previousSibling;
       
  2376 				}
       
  2377 
       
  2378 				return i;
       
  2379 			};
       
  2380 
       
  2381 			if (pe && e) {
       
  2382 				// Get before chunk
       
  2383 				r.setStart(pe.parentNode, nodeIndex(pe));
       
  2384 				r.setEnd(e.parentNode, nodeIndex(e));
       
  2385 				bef = r.extractContents();
       
  2386 
       
  2387 				// Get after chunk
       
  2388 				r = t.createRng();
       
  2389 				r.setStart(e.parentNode, nodeIndex(e) + 1);
       
  2390 				r.setEnd(pe.parentNode, nodeIndex(pe) + 1);
       
  2391 				aft = r.extractContents();
       
  2392 
       
  2393 				// Insert chunks and remove parent
       
  2394 				pa = pe.parentNode;
       
  2395 
       
  2396 				// Remove right side edge of the before contents
       
  2397 				trimEdge(bef, 'lastChild');
       
  2398 
       
  2399 				if (!isEmpty(bef))
       
  2400 					pa.insertBefore(bef, pe);
       
  2401 
       
  2402 				if (re)
       
  2403 					pa.replaceChild(re, e);
       
  2404 				else
       
  2405 					pa.insertBefore(e, pe);
       
  2406 
       
  2407 				// Remove left site edge of the after contents
       
  2408 				trimEdge(aft, 'firstChild');
       
  2409 
       
  2410 				if (!isEmpty(aft))
       
  2411 					pa.insertBefore(aft, pe);
       
  2412 
       
  2413 				t.remove(pe);
       
  2414 
       
  2415 				return re || e;
       
  2416 			}
       
  2417 		},
       
  2418 
       
  2419 		bind : function(target, name, func, scope) {
       
  2420 			var t = this;
       
  2421 
       
  2422 			if (!t.events)
       
  2423 				t.events = new tinymce.dom.EventUtils();
       
  2424 
       
  2425 			return t.events.add(target, name, func, scope || this);
       
  2426 		},
       
  2427 
       
  2428 		unbind : function(target, name, func) {
       
  2429 			var t = this;
       
  2430 
       
  2431 			if (!t.events)
       
  2432 				t.events = new tinymce.dom.EventUtils();
       
  2433 
       
  2434 			return t.events.remove(target, name, func);
       
  2435 		},
       
  2436 
       
  2437 
       
  2438 		_findSib : function(node, selector, name) {
       
  2439 			var t = this, f = selector;
       
  2440 
       
  2441 			if (node) {
       
  2442 				// If expression make a function of it using is
       
  2443 				if (is(f, 'string')) {
       
  2444 					f = function(node) {
       
  2445 						return t.is(node, selector);
       
  2446 					};
       
  2447 				}
       
  2448 
       
  2449 				// Loop all siblings
       
  2450 				for (node = node[name]; node; node = node[name]) {
       
  2451 					if (f(node))
       
  2452 						return node;
       
  2453 				}
       
  2454 			}
       
  2455 
       
  2456 			return null;
  2446 		},
  2457 		},
  2447 
  2458 
  2448 		_isRes : function(c) {
  2459 		_isRes : function(c) {
  2449 			// Is live resizble element
  2460 			// Is live resizble element
  2450 			return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c);
  2461 			return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c);
  2477 			}
  2488 			}
  2478 
  2489 
  2479 			return s;
  2490 			return s;
  2480 		}
  2491 		}
  2481 		*/
  2492 		*/
  2482 
  2493 	});
       
  2494 
       
  2495 	tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});
       
  2496 })(tinymce);
       
  2497 (function(ns) {
       
  2498 	// Traverse constants
       
  2499 	var EXTRACT = 0, CLONE = 1, DELETE = 2, extend = tinymce.extend;
       
  2500 
       
  2501 	function indexOf(child, parent) {
       
  2502 		var i, node;
       
  2503 
       
  2504 		if (child.parentNode != parent)
       
  2505 			return -1;
       
  2506 
       
  2507 		for (node = parent.firstChild, i = 0; node != child; node = node.nextSibling)
       
  2508 			i++;
       
  2509 
       
  2510 		return i;
       
  2511 	};
       
  2512 
       
  2513 	function nodeIndex(n) {
       
  2514 		var i = 0;
       
  2515 
       
  2516 		while (n.previousSibling) {
       
  2517 			i++;
       
  2518 			n = n.previousSibling;
       
  2519 		}
       
  2520 
       
  2521 		return i;
       
  2522 	};
       
  2523 
       
  2524 	function getSelectedNode(container, offset) {
       
  2525 		var child;
       
  2526 
       
  2527 		if (container.nodeType == 3 /* TEXT_NODE */)
       
  2528 			return container;
       
  2529 
       
  2530 		if (offset < 0)
       
  2531 			return container;
       
  2532 
       
  2533 		child = container.firstChild;
       
  2534 		while (child != null && offset > 0) {
       
  2535 			--offset;
       
  2536 			child = child.nextSibling;
       
  2537 		}
       
  2538 
       
  2539 		if (child != null)
       
  2540 			return child;
       
  2541 
       
  2542 		return container;
       
  2543 	};
       
  2544 
       
  2545 	// Range constructor
       
  2546 	function Range(dom) {
       
  2547 		var d = dom.doc;
       
  2548 
       
  2549 		extend(this, {
       
  2550 			dom : dom,
       
  2551 
       
  2552 			// Inital states
       
  2553 			startContainer : d,
       
  2554 			startOffset : 0,
       
  2555 			endContainer : d,
       
  2556 			endOffset : 0,
       
  2557 			collapsed : true,
       
  2558 			commonAncestorContainer : d,
       
  2559 
       
  2560 			// Range constants
       
  2561 			START_TO_START : 0,
       
  2562 			START_TO_END : 1,
       
  2563 			END_TO_END : 2,
       
  2564 			END_TO_START : 3
  2483 		});
  2565 		});
  2484 
  2566 	};
  2485 	// Setup page DOM
  2567 
  2486 	tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});
  2568 	// Add range methods
       
  2569 	extend(Range.prototype, {
       
  2570 		setStart : function(n, o) {
       
  2571 			this._setEndPoint(true, n, o);
       
  2572 		},
       
  2573 
       
  2574 		setEnd : function(n, o) {
       
  2575 			this._setEndPoint(false, n, o);
       
  2576 		},
       
  2577 
       
  2578 		setStartBefore : function(n) {
       
  2579 			this.setStart(n.parentNode, nodeIndex(n));
       
  2580 		},
       
  2581 
       
  2582 		setStartAfter : function(n) {
       
  2583 			this.setStart(n.parentNode, nodeIndex(n) + 1);
       
  2584 		},
       
  2585 
       
  2586 		setEndBefore : function(n) {
       
  2587 			this.setEnd(n.parentNode, nodeIndex(n));
       
  2588 		},
       
  2589 
       
  2590 		setEndAfter : function(n) {
       
  2591 			this.setEnd(n.parentNode, nodeIndex(n) + 1);
       
  2592 		},
       
  2593 
       
  2594 		collapse : function(ts) {
       
  2595 			var t = this;
       
  2596 
       
  2597 			if (ts) {
       
  2598 				t.endContainer = t.startContainer;
       
  2599 				t.endOffset = t.startOffset;
       
  2600 			} else {
       
  2601 				t.startContainer = t.endContainer;
       
  2602 				t.startOffset = t.endOffset;
       
  2603 			}
       
  2604 
       
  2605 			t.collapsed = true;
       
  2606 		},
       
  2607 
       
  2608 		selectNode : function(n) {
       
  2609 			this.setStartBefore(n);
       
  2610 			this.setEndAfter(n);
       
  2611 		},
       
  2612 
       
  2613 		selectNodeContents : function(n) {
       
  2614 			this.setStart(n, 0);
       
  2615 			this.setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length);
       
  2616 		},
       
  2617 
       
  2618 		compareBoundaryPoints : function(h, r) {
       
  2619 			var t = this, sc = t.startContainer, so = t.startOffset, ec = t.endContainer, eo = t.endOffset;
       
  2620 
       
  2621 			// Check START_TO_START
       
  2622 			if (h === 0)
       
  2623 				return t._compareBoundaryPoints(sc, so, sc, so);
       
  2624 
       
  2625 			// Check START_TO_END
       
  2626 			if (h === 1)
       
  2627 				return t._compareBoundaryPoints(sc, so, ec, eo);
       
  2628 
       
  2629 			// Check END_TO_END
       
  2630 			if (h === 2)
       
  2631 				return t._compareBoundaryPoints(ec, eo, ec, eo);
       
  2632 
       
  2633 			// Check END_TO_START
       
  2634 			if (h === 3)
       
  2635 				return t._compareBoundaryPoints(ec, eo, sc, so);
       
  2636 		},
       
  2637 
       
  2638 		deleteContents : function() {
       
  2639 			this._traverse(DELETE);
       
  2640 		},
       
  2641 
       
  2642 		extractContents : function() {
       
  2643 			return this._traverse(EXTRACT);
       
  2644 		},
       
  2645 
       
  2646 		cloneContents : function() {
       
  2647 			return this._traverse(CLONE);
       
  2648 		},
       
  2649 
       
  2650 		insertNode : function(n) {
       
  2651 			var t = this, nn, o;
       
  2652 
       
  2653 			// Node is TEXT_NODE or CDATA
       
  2654 			if (n.nodeType === 3 || n.nodeType === 4) {
       
  2655 				nn = t.startContainer.splitText(t.startOffset);
       
  2656 				t.startContainer.parentNode.insertBefore(n, nn);
       
  2657 			} else {
       
  2658 				// Insert element node
       
  2659 				if (t.startContainer.childNodes.length > 0)
       
  2660 					o = t.startContainer.childNodes[t.startOffset];
       
  2661 
       
  2662 				t.startContainer.insertBefore(n, o);
       
  2663 			}
       
  2664 		},
       
  2665 
       
  2666 		surroundContents : function(n) {
       
  2667 			var t = this, f = t.extractContents();
       
  2668 
       
  2669 			t.insertNode(n);
       
  2670 			n.appendChild(f);
       
  2671 			t.selectNode(n);
       
  2672 		},
       
  2673 
       
  2674 		cloneRange : function() {
       
  2675 			var t = this;
       
  2676 
       
  2677 			return extend(new Range(t.dom), {
       
  2678 				startContainer : t.startContainer,
       
  2679 				startOffset : t.startOffset,
       
  2680 				endContainer : t.endContainer,
       
  2681 				endOffset : t.endOffset,
       
  2682 				collapsed : t.collapsed,
       
  2683 				commonAncestorContainer : t.commonAncestorContainer
       
  2684 			});
       
  2685 		},
       
  2686 
       
  2687 /*
       
  2688 		detach : function() {
       
  2689 			// Not implemented
       
  2690 		},
       
  2691 */
       
  2692 		// Internal methods
       
  2693 
       
  2694 		_isCollapsed : function() {
       
  2695 			return (this.startContainer == this.endContainer && this.startOffset == this.endOffset);
       
  2696 		},
       
  2697 
       
  2698 		_compareBoundaryPoints : function (containerA, offsetA, containerB, offsetB) {
       
  2699 			var c, offsetC, n, cmnRoot, childA, childB;
       
  2700 
       
  2701 			// In the first case the boundary-points have the same container. A is before B 
       
  2702 			// if its offset is less than the offset of B, A is equal to B if its offset is 
       
  2703 			// equal to the offset of B, and A is after B if its offset is greater than the 
       
  2704 			// offset of B.
       
  2705 			if (containerA == containerB) {
       
  2706 				if (offsetA == offsetB) {
       
  2707 					return 0; // equal
       
  2708 				} else if (offsetA < offsetB) {
       
  2709 					return -1; // before
       
  2710 				} else {
       
  2711 					return 1; // after
       
  2712 				}
       
  2713 			}
       
  2714 
       
  2715 			// In the second case a child node C of the container of A is an ancestor 
       
  2716 			// container of B. In this case, A is before B if the offset of A is less than or 
       
  2717 			// equal to the index of the child node C and A is after B otherwise.
       
  2718 			c = containerB;
       
  2719 			while (c && c.parentNode != containerA) {
       
  2720 				c = c.parentNode;
       
  2721 			}
       
  2722 			if (c) {
       
  2723 				offsetC = 0;
       
  2724 				n = containerA.firstChild;
       
  2725 
       
  2726 				while (n != c && offsetC < offsetA) {
       
  2727 					offsetC++;
       
  2728 					n = n.nextSibling;
       
  2729 				}
       
  2730 
       
  2731 				if (offsetA <= offsetC) {
       
  2732 					return -1; // before
       
  2733 				} else {
       
  2734 					return 1; // after
       
  2735 				}
       
  2736 			}
       
  2737 
       
  2738 			// In the third case a child node C of the container of B is an ancestor container 
       
  2739 			// of A. In this case, A is before B if the index of the child node C is less than 
       
  2740 			// the offset of B and A is after B otherwise.
       
  2741 			c = containerA;
       
  2742 			while (c && c.parentNode != containerB) {
       
  2743 				c = c.parentNode;
       
  2744 			}
       
  2745 
       
  2746 			if (c) {
       
  2747 				offsetC = 0;
       
  2748 				n = containerB.firstChild;
       
  2749 
       
  2750 				while (n != c && offsetC < offsetB) {
       
  2751 					offsetC++;
       
  2752 					n = n.nextSibling;
       
  2753 				}
       
  2754 
       
  2755 				if (offsetC < offsetB) {
       
  2756 					return -1; // before
       
  2757 				} else {
       
  2758 					return 1; // after
       
  2759 				}
       
  2760 			}
       
  2761 
       
  2762 			// In the fourth case, none of three other cases hold: the containers of A and B 
       
  2763 			// are siblings or descendants of sibling nodes. In this case, A is before B if 
       
  2764 			// the container of A is before the container of B in a pre-order traversal of the
       
  2765 			// Ranges' context tree and A is after B otherwise.
       
  2766 			cmnRoot = this.dom.findCommonAncestor(containerA, containerB);
       
  2767 			childA = containerA;
       
  2768 
       
  2769 			while (childA && childA.parentNode != cmnRoot) {
       
  2770 				childA = childA.parentNode;  
       
  2771 			}
       
  2772 
       
  2773 			if (!childA) {
       
  2774 				childA = cmnRoot;
       
  2775 			}
       
  2776 
       
  2777 			childB = containerB;
       
  2778 			while (childB && childB.parentNode != cmnRoot) {
       
  2779 				childB = childB.parentNode;
       
  2780 			}
       
  2781 
       
  2782 			if (!childB) {
       
  2783 				childB = cmnRoot;
       
  2784 			}
       
  2785 
       
  2786 			if (childA == childB) {
       
  2787 				return 0; // equal
       
  2788 			}
       
  2789 
       
  2790 			n = cmnRoot.firstChild;
       
  2791 			while (n) {
       
  2792 				if (n == childA) {
       
  2793 					return -1; // before
       
  2794 				}
       
  2795 
       
  2796 				if (n == childB) {
       
  2797 					return 1; // after
       
  2798 				}
       
  2799 
       
  2800 				n = n.nextSibling;
       
  2801 			}
       
  2802 		},
       
  2803 
       
  2804 		_setEndPoint : function(st, n, o) {
       
  2805 			var t = this, ec, sc;
       
  2806 
       
  2807 			if (st) {
       
  2808 				t.startContainer = n;
       
  2809 				t.startOffset = o;
       
  2810 			} else {
       
  2811 				t.endContainer = n;
       
  2812 				t.endOffset = o;
       
  2813 			}
       
  2814 
       
  2815 			// If one boundary-point of a Range is set to have a root container 
       
  2816 			// other than the current one for the Range, the Range is collapsed to 
       
  2817 			// the new position. This enforces the restriction that both boundary-
       
  2818 			// points of a Range must have the same root container.
       
  2819 			ec = t.endContainer;
       
  2820 			while (ec.parentNode)
       
  2821 				ec = ec.parentNode;
       
  2822 
       
  2823 			sc = t.startContainer;
       
  2824 			while (sc.parentNode)
       
  2825 				sc = sc.parentNode;
       
  2826 
       
  2827 			if (sc != ec) {
       
  2828 				t.collapse(st);
       
  2829 			} else {
       
  2830 				// The start position of a Range is guaranteed to never be after the 
       
  2831 				// end position. To enforce this restriction, if the start is set to 
       
  2832 				// be at a position after the end, the Range is collapsed to that 
       
  2833 				// position.
       
  2834 				if (t._compareBoundaryPoints(t.startContainer, t.startOffset, t.endContainer, t.endOffset) > 0)
       
  2835 					t.collapse(st);
       
  2836 			}
       
  2837 
       
  2838 			t.collapsed = t._isCollapsed();
       
  2839 			t.commonAncestorContainer = t.dom.findCommonAncestor(t.startContainer, t.endContainer);
       
  2840 		},
       
  2841 
       
  2842 		// This code is heavily "inspired" by the Apache Xerces implementation. I hope they don't mind. :)
       
  2843 
       
  2844 		_traverse : function(how) {
       
  2845 			var t = this, c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep;
       
  2846 
       
  2847 			if (t.startContainer == t.endContainer)
       
  2848 				return t._traverseSameContainer(how);
       
  2849 
       
  2850 			for (c = t.endContainer, p = c.parentNode; p != null; c = p, p = p.parentNode) {
       
  2851 				if (p == t.startContainer)
       
  2852 					return t._traverseCommonStartContainer(c, how);
       
  2853 
       
  2854 				++endContainerDepth;
       
  2855 			}
       
  2856 
       
  2857 			for (c = t.startContainer, p = c.parentNode; p != null; c = p, p = p.parentNode) {
       
  2858 				if (p == t.endContainer)
       
  2859 					return t._traverseCommonEndContainer(c, how);
       
  2860 
       
  2861 				++startContainerDepth;
       
  2862 			}
       
  2863 
       
  2864 			depthDiff = startContainerDepth - endContainerDepth;
       
  2865 
       
  2866 			startNode = t.startContainer;
       
  2867 			while (depthDiff > 0) {
       
  2868 				startNode = startNode.parentNode;
       
  2869 				depthDiff--;
       
  2870 			}
       
  2871 
       
  2872 			endNode = t.endContainer;
       
  2873 			while (depthDiff < 0) {
       
  2874 				endNode = endNode.parentNode;
       
  2875 				depthDiff++;
       
  2876 			}
       
  2877 
       
  2878 			// ascend the ancestor hierarchy until we have a common parent.
       
  2879 			for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) {
       
  2880 				startNode = sp;
       
  2881 				endNode = ep;
       
  2882 			}
       
  2883 
       
  2884 			return t._traverseCommonAncestors(startNode, endNode, how);
       
  2885 		},
       
  2886 
       
  2887 		_traverseSameContainer : function(how) {
       
  2888 			var t = this, frag, s, sub, n, cnt, sibling, xferNode;
       
  2889 
       
  2890 			if (how != DELETE)
       
  2891 				frag = t.dom.doc.createDocumentFragment();
       
  2892 
       
  2893 			// If selection is empty, just return the fragment
       
  2894 			if (t.startOffset == t.endOffset)
       
  2895 				return frag;
       
  2896 
       
  2897 			// Text node needs special case handling
       
  2898 			if (t.startContainer.nodeType == 3 /* TEXT_NODE */) {
       
  2899 				// get the substring
       
  2900 				s = t.startContainer.nodeValue;
       
  2901 				sub = s.substring(t.startOffset, t.endOffset);
       
  2902 
       
  2903 				// set the original text node to its new value
       
  2904 				if (how != CLONE) {
       
  2905 					t.startContainer.deleteData(t.startOffset, t.endOffset - t.startOffset);
       
  2906 
       
  2907 					// Nothing is partially selected, so collapse to start point
       
  2908 					t.collapse(true);
       
  2909 				}
       
  2910 
       
  2911 				if (how == DELETE)
       
  2912 					return null;
       
  2913 
       
  2914 				frag.appendChild(t.dom.doc.createTextNode(sub));
       
  2915 				return frag;
       
  2916 			}
       
  2917 
       
  2918 			// Copy nodes between the start/end offsets.
       
  2919 			n = getSelectedNode(t.startContainer, t.startOffset);
       
  2920 			cnt = t.endOffset - t.startOffset;
       
  2921 
       
  2922 			while (cnt > 0) {
       
  2923 				sibling = n.nextSibling;
       
  2924 				xferNode = t._traverseFullySelected(n, how);
       
  2925 
       
  2926 				if (frag)
       
  2927 					frag.appendChild( xferNode );
       
  2928 
       
  2929 				--cnt;
       
  2930 				n = sibling;
       
  2931 			}
       
  2932 
       
  2933 			// Nothing is partially selected, so collapse to start point
       
  2934 			if (how != CLONE)
       
  2935 				t.collapse(true);
       
  2936 
       
  2937 			return frag;
       
  2938 		},
       
  2939 
       
  2940 		_traverseCommonStartContainer : function(endAncestor, how) {
       
  2941 			var t = this, frag, n, endIdx, cnt, sibling, xferNode;
       
  2942 
       
  2943 			if (how != DELETE)
       
  2944 				frag = t.dom.doc.createDocumentFragment();
       
  2945 
       
  2946 			n = t._traverseRightBoundary(endAncestor, how);
       
  2947 
       
  2948 			if (frag)
       
  2949 				frag.appendChild(n);
       
  2950 
       
  2951 			endIdx = indexOf(endAncestor, t.startContainer);
       
  2952 			cnt = endIdx - t.startOffset;
       
  2953 
       
  2954 			if (cnt <= 0) {
       
  2955 				// Collapse to just before the endAncestor, which 
       
  2956 				// is partially selected.
       
  2957 				if (how != CLONE) {
       
  2958 					t.setEndBefore(endAncestor);
       
  2959 					t.collapse(false);
       
  2960 				}
       
  2961 
       
  2962 				return frag;
       
  2963 			}
       
  2964 
       
  2965 			n = endAncestor.previousSibling;
       
  2966 			while (cnt > 0) {
       
  2967 				sibling = n.previousSibling;
       
  2968 				xferNode = t._traverseFullySelected(n, how);
       
  2969 
       
  2970 				if (frag)
       
  2971 					frag.insertBefore(xferNode, frag.firstChild);
       
  2972 
       
  2973 				--cnt;
       
  2974 				n = sibling;
       
  2975 			}
       
  2976 
       
  2977 			// Collapse to just before the endAncestor, which 
       
  2978 			// is partially selected.
       
  2979 			if (how != CLONE) {
       
  2980 				t.setEndBefore(endAncestor);
       
  2981 				t.collapse(false);
       
  2982 			}
       
  2983 
       
  2984 			return frag;
       
  2985 		},
       
  2986 
       
  2987 		_traverseCommonEndContainer : function(startAncestor, how) {
       
  2988 			var t = this, frag, startIdx, n, cnt, sibling, xferNode;
       
  2989 
       
  2990 			if (how != DELETE)
       
  2991 				frag = t.dom.doc.createDocumentFragment();
       
  2992 
       
  2993 			n = t._traverseLeftBoundary(startAncestor, how);
       
  2994 			if (frag)
       
  2995 				frag.appendChild(n);
       
  2996 
       
  2997 			startIdx = indexOf(startAncestor, t.endContainer);
       
  2998 			++startIdx;  // Because we already traversed it....
       
  2999 
       
  3000 			cnt = t.endOffset - startIdx;
       
  3001 			n = startAncestor.nextSibling;
       
  3002 			while (cnt > 0) {
       
  3003 				sibling = n.nextSibling;
       
  3004 				xferNode = t._traverseFullySelected(n, how);
       
  3005 
       
  3006 				if (frag)
       
  3007 					frag.appendChild(xferNode);
       
  3008 
       
  3009 				--cnt;
       
  3010 				n = sibling;
       
  3011 			}
       
  3012 
       
  3013 			if (how != CLONE) {
       
  3014 				t.setStartAfter(startAncestor);
       
  3015 				t.collapse(true);
       
  3016 			}
       
  3017 
       
  3018 			return frag;
       
  3019 		},
       
  3020 
       
  3021 		_traverseCommonAncestors : function(startAncestor, endAncestor, how) {
       
  3022 			var t = this, n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling;
       
  3023 
       
  3024 			if (how != DELETE)
       
  3025 				frag = t.dom.doc.createDocumentFragment();
       
  3026 
       
  3027 			n = t._traverseLeftBoundary(startAncestor, how);
       
  3028 			if (frag)
       
  3029 				frag.appendChild(n);
       
  3030 
       
  3031 			commonParent = startAncestor.parentNode;
       
  3032 			startOffset = indexOf(startAncestor, commonParent);
       
  3033 			endOffset = indexOf(endAncestor, commonParent);
       
  3034 			++startOffset;
       
  3035 
       
  3036 			cnt = endOffset - startOffset;
       
  3037 			sibling = startAncestor.nextSibling;
       
  3038 
       
  3039 			while (cnt > 0) {
       
  3040 				nextSibling = sibling.nextSibling;
       
  3041 				n = t._traverseFullySelected(sibling, how);
       
  3042 
       
  3043 				if (frag)
       
  3044 					frag.appendChild(n);
       
  3045 
       
  3046 				sibling = nextSibling;
       
  3047 				--cnt;
       
  3048 			}
       
  3049 
       
  3050 			n = t._traverseRightBoundary(endAncestor, how);
       
  3051 
       
  3052 			if (frag)
       
  3053 				frag.appendChild(n);
       
  3054 
       
  3055 			if (how != CLONE) {
       
  3056 				t.setStartAfter(startAncestor);
       
  3057 				t.collapse(true);
       
  3058 			}
       
  3059 
       
  3060 			return frag;
       
  3061 		},
       
  3062 
       
  3063 		_traverseRightBoundary : function(root, how) {
       
  3064 			var t = this, next = getSelectedNode(t.endContainer, t.endOffset - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent;
       
  3065 			var isFullySelected = next != t.endContainer;
       
  3066 
       
  3067 			if (next == root)
       
  3068 				return t._traverseNode(next, isFullySelected, false, how);
       
  3069 
       
  3070 			parent = next.parentNode;
       
  3071 			clonedParent = t._traverseNode(parent, false, false, how);
       
  3072 
       
  3073 			while (parent != null) {
       
  3074 				while (next != null) {
       
  3075 					prevSibling = next.previousSibling;
       
  3076 					clonedChild = t._traverseNode(next, isFullySelected, false, how);
       
  3077 
       
  3078 					if (how != DELETE)
       
  3079 						clonedParent.insertBefore(clonedChild, clonedParent.firstChild);
       
  3080 
       
  3081 					isFullySelected = true;
       
  3082 					next = prevSibling;
       
  3083 				}
       
  3084 
       
  3085 				if (parent == root)
       
  3086 					return clonedParent;
       
  3087 
       
  3088 				next = parent.previousSibling;
       
  3089 				parent = parent.parentNode;
       
  3090 
       
  3091 				clonedGrandParent = t._traverseNode(parent, false, false, how);
       
  3092 
       
  3093 				if (how != DELETE)
       
  3094 					clonedGrandParent.appendChild(clonedParent);
       
  3095 
       
  3096 				clonedParent = clonedGrandParent;
       
  3097 			}
       
  3098 
       
  3099 			// should never occur
       
  3100 			return null;
       
  3101 		},
       
  3102 
       
  3103 		_traverseLeftBoundary : function(root, how) {
       
  3104 			var t = this, next = getSelectedNode(t.startContainer, t.startOffset);
       
  3105 			var isFullySelected = next != t.startContainer, parent, clonedParent, nextSibling, clonedChild, clonedGrandParent;
       
  3106 
       
  3107 			if (next == root)
       
  3108 				return t._traverseNode(next, isFullySelected, true, how);
       
  3109 
       
  3110 			parent = next.parentNode;
       
  3111 			clonedParent = t._traverseNode(parent, false, true, how);
       
  3112 
       
  3113 			while (parent != null) {
       
  3114 				while (next != null) {
       
  3115 					nextSibling = next.nextSibling;
       
  3116 					clonedChild = t._traverseNode(next, isFullySelected, true, how);
       
  3117 
       
  3118 					if (how != DELETE)
       
  3119 						clonedParent.appendChild(clonedChild);
       
  3120 
       
  3121 					isFullySelected = true;
       
  3122 					next = nextSibling;
       
  3123 				}
       
  3124 
       
  3125 				if (parent == root)
       
  3126 					return clonedParent;
       
  3127 
       
  3128 				next = parent.nextSibling;
       
  3129 				parent = parent.parentNode;
       
  3130 
       
  3131 				clonedGrandParent = t._traverseNode(parent, false, true, how);
       
  3132 
       
  3133 				if (how != DELETE)
       
  3134 					clonedGrandParent.appendChild(clonedParent);
       
  3135 
       
  3136 				clonedParent = clonedGrandParent;
       
  3137 			}
       
  3138 
       
  3139 			// should never occur
       
  3140 			return null;
       
  3141 		},
       
  3142 
       
  3143 		_traverseNode : function(n, isFullySelected, isLeft, how) {
       
  3144 			var t = this, txtValue, newNodeValue, oldNodeValue, offset, newNode;
       
  3145 
       
  3146 			if (isFullySelected)
       
  3147 				return t._traverseFullySelected(n, how);
       
  3148 
       
  3149 			if (n.nodeType == 3 /* TEXT_NODE */) {
       
  3150 				txtValue = n.nodeValue;
       
  3151 
       
  3152 				if (isLeft) {
       
  3153 					offset = t.startOffset;
       
  3154 					newNodeValue = txtValue.substring(offset);
       
  3155 					oldNodeValue = txtValue.substring(0, offset);
       
  3156 				} else {
       
  3157 					offset = t.endOffset;
       
  3158 					newNodeValue = txtValue.substring(0, offset);
       
  3159 					oldNodeValue = txtValue.substring(offset);
       
  3160 				}
       
  3161 
       
  3162 				if (how != CLONE)
       
  3163 					n.nodeValue = oldNodeValue;
       
  3164 
       
  3165 				if (how == DELETE)
       
  3166 					return null;
       
  3167 
       
  3168 				newNode = n.cloneNode(false);
       
  3169 				newNode.nodeValue = newNodeValue;
       
  3170 
       
  3171 				return newNode;
       
  3172 			}
       
  3173 
       
  3174 			if (how == DELETE)
       
  3175 				return null;
       
  3176 
       
  3177 			return n.cloneNode(false);
       
  3178 		},
       
  3179 
       
  3180 		_traverseFullySelected : function(n, how) {
       
  3181 			var t = this;
       
  3182 
       
  3183 			if (how != DELETE)
       
  3184 				return how == CLONE ? n.cloneNode(true) : n;
       
  3185 
       
  3186 			n.parentNode.removeChild(n);
       
  3187 			return null;
       
  3188 		}
       
  3189 	});
       
  3190 
       
  3191 	ns.Range = Range;
       
  3192 })(tinymce.dom);
       
  3193 (function() {
       
  3194 	function Selection(selection) {
       
  3195 		var t = this, invisibleChar = '\uFEFF', range, lastIERng;
       
  3196 
       
  3197 		function compareRanges(rng1, rng2) {
       
  3198 			if (rng1 && rng2) {
       
  3199 				// Both are control ranges and the selected element matches
       
  3200 				if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))
       
  3201 					return 1;
       
  3202 
       
  3203 				// Both are text ranges and the range matches
       
  3204 				if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))
       
  3205 					return 1;
       
  3206 			}
       
  3207 
       
  3208 			return 0;
       
  3209 		};
       
  3210 
       
  3211 		function getRange() {
       
  3212 			var dom = selection.dom, ieRange = selection.getRng(), domRange = dom.createRng(), startPos, endPos, element, sc, ec, collapsed;
       
  3213 
       
  3214 			function findIndex(element) {
       
  3215 				var nl = element.parentNode.childNodes, i;
       
  3216 
       
  3217 				for (i = nl.length - 1; i >= 0; i--) {
       
  3218 					if (nl[i] == element)
       
  3219 						return i;
       
  3220 				}
       
  3221 
       
  3222 				return -1;
       
  3223 			};
       
  3224 
       
  3225 			function findEndPoint(start) {
       
  3226 				var rng = ieRange.duplicate(), parent, i, nl, n, offset = 0, index = 0, pos, tmpRng;
       
  3227 
       
  3228 				// Insert marker character
       
  3229 				rng.collapse(start);
       
  3230 				parent = rng.parentElement();
       
  3231 				rng.pasteHTML(invisibleChar); // Needs to be a pasteHTML instead of .text = since IE has a bug with nodeValue
       
  3232 
       
  3233 				// Find marker character
       
  3234 				nl = parent.childNodes;
       
  3235 				for (i = 0; i < nl.length; i++) {
       
  3236 					n = nl[i];
       
  3237 
       
  3238 					// Calculate node index excluding text node fragmentation
       
  3239 					if (i > 0 && (n.nodeType !== 3 || nl[i - 1].nodeType !== 3))
       
  3240 						index++;
       
  3241 
       
  3242 					// If text node then calculate offset
       
  3243 					if (n.nodeType === 3) {
       
  3244 						// Look for marker
       
  3245 						pos = n.nodeValue.indexOf(invisibleChar);
       
  3246 						if (pos !== -1) {
       
  3247 							offset += pos;
       
  3248 							break;
       
  3249 						}
       
  3250 
       
  3251 						offset += n.nodeValue.length;
       
  3252 					} else
       
  3253 						offset = 0;
       
  3254 				}
       
  3255 
       
  3256 				// Remove marker character
       
  3257 				rng.moveStart('character', -1);
       
  3258 				rng.text = '';
       
  3259 
       
  3260 				return {index : index, offset : offset, parent : parent};
       
  3261 			};
       
  3262 
       
  3263 			// If selection is outside the current document just return an empty range
       
  3264 			element = ieRange.item ? ieRange.item(0) : ieRange.parentElement();
       
  3265 			if (element.ownerDocument != dom.doc)
       
  3266 				return domRange;
       
  3267 
       
  3268 			// Handle control selection or text selection of a image
       
  3269 			if (ieRange.item || !element.hasChildNodes()) {
       
  3270 				domRange.setStart(element.parentNode, findIndex(element));
       
  3271 				domRange.setEnd(domRange.startContainer, domRange.startOffset + 1);
       
  3272 
       
  3273 				return domRange;
       
  3274 			}
       
  3275 
       
  3276 			// Check collapsed state
       
  3277 			collapsed = selection.isCollapsed();
       
  3278 
       
  3279 			// Find start and end pos index and offset
       
  3280 			startPos = findEndPoint(true);
       
  3281 			endPos = findEndPoint(false);
       
  3282 
       
  3283 			// Normalize the elements to avoid fragmented dom
       
  3284 			startPos.parent.normalize();
       
  3285 			endPos.parent.normalize();
       
  3286 
       
  3287 			// Set start container and offset
       
  3288 			sc = startPos.parent.childNodes[Math.min(startPos.index, startPos.parent.childNodes.length - 1)];
       
  3289 
       
  3290 			if (sc.nodeType != 3)
       
  3291 				domRange.setStart(startPos.parent, startPos.index);
       
  3292 			else
       
  3293 				domRange.setStart(startPos.parent.childNodes[startPos.index], startPos.offset);
       
  3294 
       
  3295 			// Set end container and offset
       
  3296 			ec = endPos.parent.childNodes[Math.min(endPos.index, endPos.parent.childNodes.length - 1)];
       
  3297 
       
  3298 			if (ec.nodeType != 3) {
       
  3299 				if (!collapsed)
       
  3300 					endPos.index++;
       
  3301 
       
  3302 				domRange.setEnd(endPos.parent, endPos.index);
       
  3303 			} else
       
  3304 				domRange.setEnd(endPos.parent.childNodes[endPos.index], endPos.offset);
       
  3305 
       
  3306 			// If not collapsed then make sure offsets are valid
       
  3307 			if (!collapsed) {
       
  3308 				sc = domRange.startContainer;
       
  3309 				if (sc.nodeType == 1)
       
  3310 					domRange.setStart(sc, Math.min(domRange.startOffset, sc.childNodes.length));
       
  3311 
       
  3312 				ec = domRange.endContainer;
       
  3313 				if (ec.nodeType == 1)
       
  3314 					domRange.setEnd(ec, Math.min(domRange.endOffset, ec.childNodes.length));
       
  3315 			}
       
  3316 
       
  3317 			// Restore selection to new range
       
  3318 			t.addRange(domRange);
       
  3319 
       
  3320 			return domRange;
       
  3321 		};
       
  3322 
       
  3323 		this.addRange = function(rng) {
       
  3324 			var ieRng, body = selection.dom.doc.body, startPos, endPos, sc, so, ec, eo;
       
  3325 
       
  3326 			// Setup some shorter versions
       
  3327 			sc = rng.startContainer;
       
  3328 			so = rng.startOffset;
       
  3329 			ec = rng.endContainer;
       
  3330 			eo = rng.endOffset;
       
  3331 			ieRng = body.createTextRange();
       
  3332 
       
  3333 			// Find element
       
  3334 			sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc;
       
  3335 			ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec;
       
  3336 
       
  3337 			// Single element selection
       
  3338 			if (sc == ec && sc.nodeType == 1) {
       
  3339 				// Make control selection for some elements
       
  3340 				if (/^(IMG|TABLE)$/.test(sc.nodeName) && so != eo) {
       
  3341 					ieRng = body.createControlRange();
       
  3342 					ieRng.addElement(sc);
       
  3343 				} else {
       
  3344 					ieRng = body.createTextRange();
       
  3345 
       
  3346 					// Padd empty elements with invisible character
       
  3347 					if (!sc.hasChildNodes() && sc.canHaveHTML)
       
  3348 						sc.innerHTML = invisibleChar;
       
  3349 
       
  3350 					// Select element contents
       
  3351 					ieRng.moveToElementText(sc);
       
  3352 
       
  3353 					// If it's only containing a padding remove it so the caret remains
       
  3354 					if (sc.innerHTML == invisibleChar) {
       
  3355 						ieRng.collapse(true);
       
  3356 						sc.removeChild(sc.firstChild);
       
  3357 					}
       
  3358 				}
       
  3359 
       
  3360 				if (so == eo)
       
  3361 					ieRng.collapse(eo <= rng.endContainer.childNodes.length - 1);
       
  3362 
       
  3363 				ieRng.select();
       
  3364 
       
  3365 				return;
       
  3366 			}
       
  3367 
       
  3368 			function getCharPos(container, offset) {
       
  3369 				var nodeVal, rng, pos;
       
  3370 
       
  3371 				if (container.nodeType != 3)
       
  3372 					return -1;
       
  3373 
       
  3374 				nodeVal = container.nodeValue;
       
  3375 				rng = body.createTextRange();
       
  3376 
       
  3377 				// Insert marker at offset position
       
  3378 				container.nodeValue = nodeVal.substring(0, offset) + invisibleChar + nodeVal.substring(offset);
       
  3379 
       
  3380 				// Find char pos of marker and remove it
       
  3381 				rng.moveToElementText(container.parentNode);
       
  3382 				rng.findText(invisibleChar);
       
  3383 				pos = Math.abs(rng.moveStart('character', -0xFFFFF));
       
  3384 				container.nodeValue = nodeVal;
       
  3385 
       
  3386 				return pos;
       
  3387 			};
       
  3388 
       
  3389 			// Collapsed range
       
  3390 			if (rng.collapsed) {
       
  3391 				pos = getCharPos(sc, so);
       
  3392 
       
  3393 				ieRng = body.createTextRange();
       
  3394 				ieRng.move('character', pos);
       
  3395 				ieRng.select();
       
  3396 
       
  3397 				return;
       
  3398 			} else {
       
  3399 				// If same text container
       
  3400 				if (sc == ec && sc.nodeType == 3) {
       
  3401 					startPos = getCharPos(sc, so);
       
  3402 
       
  3403 					ieRng = body.createTextRange();
       
  3404 					ieRng.move('character', startPos);
       
  3405 					ieRng.moveEnd('character', eo - so);
       
  3406 					ieRng.select();
       
  3407 
       
  3408 					return;
       
  3409 				}
       
  3410 
       
  3411 				// Get caret positions
       
  3412 				startPos = getCharPos(sc, so);
       
  3413 				endPos = getCharPos(ec, eo);
       
  3414 				ieRng = body.createTextRange();
       
  3415 
       
  3416 				// Move start of range to start character position or start element
       
  3417 				if (startPos == -1) {
       
  3418 					ieRng.moveToElementText(sc);
       
  3419 					startPos = 0;
       
  3420 				} else
       
  3421 					ieRng.move('character', startPos);
       
  3422 
       
  3423 				// Move end of range to end character position or end element
       
  3424 				tmpRng = body.createTextRange();
       
  3425 
       
  3426 				if (endPos == -1)
       
  3427 					tmpRng.moveToElementText(ec);
       
  3428 				else
       
  3429 					tmpRng.move('character', endPos);
       
  3430 
       
  3431 				ieRng.setEndPoint('EndToEnd', tmpRng);
       
  3432 				ieRng.select();
       
  3433 
       
  3434 				return;
       
  3435 			}
       
  3436 		};
       
  3437 
       
  3438 		this.getRangeAt = function() {
       
  3439 			// Setup new range if the cache is empty
       
  3440 			if (!range || !compareRanges(lastIERng, selection.getRng())) {
       
  3441 				range = getRange();
       
  3442 
       
  3443 				// Store away text range for next call
       
  3444 				lastIERng = selection.getRng();
       
  3445 			}
       
  3446 
       
  3447 			// Return cached range
       
  3448 			return range;
       
  3449 		};
       
  3450 
       
  3451 		this.destroy = function() {
       
  3452 			// Destroy cached range and last IE range to avoid memory leaks
       
  3453 			lastIERng = range = null;
       
  3454 		};
       
  3455 	};
       
  3456 
       
  3457 	// Expose the selection object
       
  3458 	tinymce.dom.TridentSelection = Selection;
  2487 })();
  3459 })();
  2488 
  3460 
  2489 /* file:jscripts/tiny_mce/classes/dom/Event.js */
  3461 /*
  2490 
  3462  * Sizzle CSS Selector Engine - v1.0
  2491 (function() {
  3463  *  Copyright 2009, The Dojo Foundation
       
  3464  *  Released under the MIT, BSD, and GPL Licenses.
       
  3465  *  More information: http://sizzlejs.com/
       
  3466  */
       
  3467 (function(){
       
  3468 
       
  3469 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
       
  3470 	done = 0,
       
  3471 	toString = Object.prototype.toString,
       
  3472 	hasDuplicate = false;
       
  3473 
       
  3474 var Sizzle = function(selector, context, results, seed) {
       
  3475 	results = results || [];
       
  3476 	var origContext = context = context || document;
       
  3477 
       
  3478 	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
       
  3479 		return [];
       
  3480 	}
       
  3481 	
       
  3482 	if ( !selector || typeof selector !== "string" ) {
       
  3483 		return results;
       
  3484 	}
       
  3485 
       
  3486 	var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context);
       
  3487 	
       
  3488 	// Reset the position of the chunker regexp (start from head)
       
  3489 	chunker.lastIndex = 0;
       
  3490 	
       
  3491 	while ( (m = chunker.exec(selector)) !== null ) {
       
  3492 		parts.push( m[1] );
       
  3493 		
       
  3494 		if ( m[2] ) {
       
  3495 			extra = RegExp.rightContext;
       
  3496 			break;
       
  3497 		}
       
  3498 	}
       
  3499 
       
  3500 	if ( parts.length > 1 && origPOS.exec( selector ) ) {
       
  3501 		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
       
  3502 			set = posProcess( parts[0] + parts[1], context );
       
  3503 		} else {
       
  3504 			set = Expr.relative[ parts[0] ] ?
       
  3505 				[ context ] :
       
  3506 				Sizzle( parts.shift(), context );
       
  3507 
       
  3508 			while ( parts.length ) {
       
  3509 				selector = parts.shift();
       
  3510 
       
  3511 				if ( Expr.relative[ selector ] )
       
  3512 					selector += parts.shift();
       
  3513 
       
  3514 				set = posProcess( selector, set );
       
  3515 			}
       
  3516 		}
       
  3517 	} else {
       
  3518 		// Take a shortcut and set the context if the root selector is an ID
       
  3519 		// (but not if it'll be faster if the inner selector is an ID)
       
  3520 		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
       
  3521 				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
       
  3522 			var ret = Sizzle.find( parts.shift(), context, contextXML );
       
  3523 			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
       
  3524 		}
       
  3525 
       
  3526 		if ( context ) {
       
  3527 			var ret = seed ?
       
  3528 				{ expr: parts.pop(), set: makeArray(seed) } :
       
  3529 				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
       
  3530 			set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
       
  3531 
       
  3532 			if ( parts.length > 0 ) {
       
  3533 				checkSet = makeArray(set);
       
  3534 			} else {
       
  3535 				prune = false;
       
  3536 			}
       
  3537 
       
  3538 			while ( parts.length ) {
       
  3539 				var cur = parts.pop(), pop = cur;
       
  3540 
       
  3541 				if ( !Expr.relative[ cur ] ) {
       
  3542 					cur = "";
       
  3543 				} else {
       
  3544 					pop = parts.pop();
       
  3545 				}
       
  3546 
       
  3547 				if ( pop == null ) {
       
  3548 					pop = context;
       
  3549 				}
       
  3550 
       
  3551 				Expr.relative[ cur ]( checkSet, pop, contextXML );
       
  3552 			}
       
  3553 		} else {
       
  3554 			checkSet = parts = [];
       
  3555 		}
       
  3556 	}
       
  3557 
       
  3558 	if ( !checkSet ) {
       
  3559 		checkSet = set;
       
  3560 	}
       
  3561 
       
  3562 	if ( !checkSet ) {
       
  3563 		throw "Syntax error, unrecognized expression: " + (cur || selector);
       
  3564 	}
       
  3565 
       
  3566 	if ( toString.call(checkSet) === "[object Array]" ) {
       
  3567 		if ( !prune ) {
       
  3568 			results.push.apply( results, checkSet );
       
  3569 		} else if ( context && context.nodeType === 1 ) {
       
  3570 			for ( var i = 0; checkSet[i] != null; i++ ) {
       
  3571 				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
       
  3572 					results.push( set[i] );
       
  3573 				}
       
  3574 			}
       
  3575 		} else {
       
  3576 			for ( var i = 0; checkSet[i] != null; i++ ) {
       
  3577 				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
       
  3578 					results.push( set[i] );
       
  3579 				}
       
  3580 			}
       
  3581 		}
       
  3582 	} else {
       
  3583 		makeArray( checkSet, results );
       
  3584 	}
       
  3585 
       
  3586 	if ( extra ) {
       
  3587 		Sizzle( extra, origContext, results, seed );
       
  3588 		Sizzle.uniqueSort( results );
       
  3589 	}
       
  3590 
       
  3591 	return results;
       
  3592 };
       
  3593 
       
  3594 Sizzle.uniqueSort = function(results){
       
  3595 	if ( sortOrder ) {
       
  3596 		hasDuplicate = false;
       
  3597 		results.sort(sortOrder);
       
  3598 
       
  3599 		if ( hasDuplicate ) {
       
  3600 			for ( var i = 1; i < results.length; i++ ) {
       
  3601 				if ( results[i] === results[i-1] ) {
       
  3602 					results.splice(i--, 1);
       
  3603 				}
       
  3604 			}
       
  3605 		}
       
  3606 	}
       
  3607 };
       
  3608 
       
  3609 Sizzle.matches = function(expr, set){
       
  3610 	return Sizzle(expr, null, null, set);
       
  3611 };
       
  3612 
       
  3613 Sizzle.find = function(expr, context, isXML){
       
  3614 	var set, match;
       
  3615 
       
  3616 	if ( !expr ) {
       
  3617 		return [];
       
  3618 	}
       
  3619 
       
  3620 	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
       
  3621 		var type = Expr.order[i], match;
       
  3622 		
       
  3623 		if ( (match = Expr.match[ type ].exec( expr )) ) {
       
  3624 			var left = RegExp.leftContext;
       
  3625 
       
  3626 			if ( left.substr( left.length - 1 ) !== "\\" ) {
       
  3627 				match[1] = (match[1] || "").replace(/\\/g, "");
       
  3628 				set = Expr.find[ type ]( match, context, isXML );
       
  3629 				if ( set != null ) {
       
  3630 					expr = expr.replace( Expr.match[ type ], "" );
       
  3631 					break;
       
  3632 				}
       
  3633 			}
       
  3634 		}
       
  3635 	}
       
  3636 
       
  3637 	if ( !set ) {
       
  3638 		set = context.getElementsByTagName("*");
       
  3639 	}
       
  3640 
       
  3641 	return {set: set, expr: expr};
       
  3642 };
       
  3643 
       
  3644 Sizzle.filter = function(expr, set, inplace, not){
       
  3645 	var old = expr, result = [], curLoop = set, match, anyFound,
       
  3646 		isXMLFilter = set && set[0] && isXML(set[0]);
       
  3647 
       
  3648 	while ( expr && set.length ) {
       
  3649 		for ( var type in Expr.filter ) {
       
  3650 			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
       
  3651 				var filter = Expr.filter[ type ], found, item;
       
  3652 				anyFound = false;
       
  3653 
       
  3654 				if ( curLoop == result ) {
       
  3655 					result = [];
       
  3656 				}
       
  3657 
       
  3658 				if ( Expr.preFilter[ type ] ) {
       
  3659 					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
       
  3660 
       
  3661 					if ( !match ) {
       
  3662 						anyFound = found = true;
       
  3663 					} else if ( match === true ) {
       
  3664 						continue;
       
  3665 					}
       
  3666 				}
       
  3667 
       
  3668 				if ( match ) {
       
  3669 					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
       
  3670 						if ( item ) {
       
  3671 							found = filter( item, match, i, curLoop );
       
  3672 							var pass = not ^ !!found;
       
  3673 
       
  3674 							if ( inplace && found != null ) {
       
  3675 								if ( pass ) {
       
  3676 									anyFound = true;
       
  3677 								} else {
       
  3678 									curLoop[i] = false;
       
  3679 								}
       
  3680 							} else if ( pass ) {
       
  3681 								result.push( item );
       
  3682 								anyFound = true;
       
  3683 							}
       
  3684 						}
       
  3685 					}
       
  3686 				}
       
  3687 
       
  3688 				if ( found !== undefined ) {
       
  3689 					if ( !inplace ) {
       
  3690 						curLoop = result;
       
  3691 					}
       
  3692 
       
  3693 					expr = expr.replace( Expr.match[ type ], "" );
       
  3694 
       
  3695 					if ( !anyFound ) {
       
  3696 						return [];
       
  3697 					}
       
  3698 
       
  3699 					break;
       
  3700 				}
       
  3701 			}
       
  3702 		}
       
  3703 
       
  3704 		// Improper expression
       
  3705 		if ( expr == old ) {
       
  3706 			if ( anyFound == null ) {
       
  3707 				throw "Syntax error, unrecognized expression: " + expr;
       
  3708 			} else {
       
  3709 				break;
       
  3710 			}
       
  3711 		}
       
  3712 
       
  3713 		old = expr;
       
  3714 	}
       
  3715 
       
  3716 	return curLoop;
       
  3717 };
       
  3718 
       
  3719 var Expr = Sizzle.selectors = {
       
  3720 	order: [ "ID", "NAME", "TAG" ],
       
  3721 	match: {
       
  3722 		ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
       
  3723 		CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
       
  3724 		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
       
  3725 		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
       
  3726 		TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
       
  3727 		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
       
  3728 		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
       
  3729 		PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
       
  3730 	},
       
  3731 	attrMap: {
       
  3732 		"class": "className",
       
  3733 		"for": "htmlFor"
       
  3734 	},
       
  3735 	attrHandle: {
       
  3736 		href: function(elem){
       
  3737 			return elem.getAttribute("href");
       
  3738 		}
       
  3739 	},
       
  3740 	relative: {
       
  3741 		"+": function(checkSet, part, isXML){
       
  3742 			var isPartStr = typeof part === "string",
       
  3743 				isTag = isPartStr && !/\W/.test(part),
       
  3744 				isPartStrNotTag = isPartStr && !isTag;
       
  3745 
       
  3746 			if ( isTag && !isXML ) {
       
  3747 				part = part.toUpperCase();
       
  3748 			}
       
  3749 
       
  3750 			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
       
  3751 				if ( (elem = checkSet[i]) ) {
       
  3752 					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
       
  3753 
       
  3754 					checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
       
  3755 						elem || false :
       
  3756 						elem === part;
       
  3757 				}
       
  3758 			}
       
  3759 
       
  3760 			if ( isPartStrNotTag ) {
       
  3761 				Sizzle.filter( part, checkSet, true );
       
  3762 			}
       
  3763 		},
       
  3764 		">": function(checkSet, part, isXML){
       
  3765 			var isPartStr = typeof part === "string";
       
  3766 
       
  3767 			if ( isPartStr && !/\W/.test(part) ) {
       
  3768 				part = isXML ? part : part.toUpperCase();
       
  3769 
       
  3770 				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
       
  3771 					var elem = checkSet[i];
       
  3772 					if ( elem ) {
       
  3773 						var parent = elem.parentNode;
       
  3774 						checkSet[i] = parent.nodeName === part ? parent : false;
       
  3775 					}
       
  3776 				}
       
  3777 			} else {
       
  3778 				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
       
  3779 					var elem = checkSet[i];
       
  3780 					if ( elem ) {
       
  3781 						checkSet[i] = isPartStr ?
       
  3782 							elem.parentNode :
       
  3783 							elem.parentNode === part;
       
  3784 					}
       
  3785 				}
       
  3786 
       
  3787 				if ( isPartStr ) {
       
  3788 					Sizzle.filter( part, checkSet, true );
       
  3789 				}
       
  3790 			}
       
  3791 		},
       
  3792 		"": function(checkSet, part, isXML){
       
  3793 			var doneName = done++, checkFn = dirCheck;
       
  3794 
       
  3795 			if ( !part.match(/\W/) ) {
       
  3796 				var nodeCheck = part = isXML ? part : part.toUpperCase();
       
  3797 				checkFn = dirNodeCheck;
       
  3798 			}
       
  3799 
       
  3800 			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
       
  3801 		},
       
  3802 		"~": function(checkSet, part, isXML){
       
  3803 			var doneName = done++, checkFn = dirCheck;
       
  3804 
       
  3805 			if ( typeof part === "string" && !part.match(/\W/) ) {
       
  3806 				var nodeCheck = part = isXML ? part : part.toUpperCase();
       
  3807 				checkFn = dirNodeCheck;
       
  3808 			}
       
  3809 
       
  3810 			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
       
  3811 		}
       
  3812 	},
       
  3813 	find: {
       
  3814 		ID: function(match, context, isXML){
       
  3815 			if ( typeof context.getElementById !== "undefined" && !isXML ) {
       
  3816 				var m = context.getElementById(match[1]);
       
  3817 				return m ? [m] : [];
       
  3818 			}
       
  3819 		},
       
  3820 		NAME: function(match, context, isXML){
       
  3821 			if ( typeof context.getElementsByName !== "undefined" ) {
       
  3822 				var ret = [], results = context.getElementsByName(match[1]);
       
  3823 
       
  3824 				for ( var i = 0, l = results.length; i < l; i++ ) {
       
  3825 					if ( results[i].getAttribute("name") === match[1] ) {
       
  3826 						ret.push( results[i] );
       
  3827 					}
       
  3828 				}
       
  3829 
       
  3830 				return ret.length === 0 ? null : ret;
       
  3831 			}
       
  3832 		},
       
  3833 		TAG: function(match, context){
       
  3834 			return context.getElementsByTagName(match[1]);
       
  3835 		}
       
  3836 	},
       
  3837 	preFilter: {
       
  3838 		CLASS: function(match, curLoop, inplace, result, not, isXML){
       
  3839 			match = " " + match[1].replace(/\\/g, "") + " ";
       
  3840 
       
  3841 			if ( isXML ) {
       
  3842 				return match;
       
  3843 			}
       
  3844 
       
  3845 			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
       
  3846 				if ( elem ) {
       
  3847 					if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
       
  3848 						if ( !inplace )
       
  3849 							result.push( elem );
       
  3850 					} else if ( inplace ) {
       
  3851 						curLoop[i] = false;
       
  3852 					}
       
  3853 				}
       
  3854 			}
       
  3855 
       
  3856 			return false;
       
  3857 		},
       
  3858 		ID: function(match){
       
  3859 			return match[1].replace(/\\/g, "");
       
  3860 		},
       
  3861 		TAG: function(match, curLoop){
       
  3862 			for ( var i = 0; curLoop[i] === false; i++ ){}
       
  3863 			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
       
  3864 		},
       
  3865 		CHILD: function(match){
       
  3866 			if ( match[1] == "nth" ) {
       
  3867 				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
       
  3868 				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
       
  3869 					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
       
  3870 					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
       
  3871 
       
  3872 				// calculate the numbers (first)n+(last) including if they are negative
       
  3873 				match[2] = (test[1] + (test[2] || 1)) - 0;
       
  3874 				match[3] = test[3] - 0;
       
  3875 			}
       
  3876 
       
  3877 			// TODO: Move to normal caching system
       
  3878 			match[0] = done++;
       
  3879 
       
  3880 			return match;
       
  3881 		},
       
  3882 		ATTR: function(match, curLoop, inplace, result, not, isXML){
       
  3883 			var name = match[1].replace(/\\/g, "");
       
  3884 			
       
  3885 			if ( !isXML && Expr.attrMap[name] ) {
       
  3886 				match[1] = Expr.attrMap[name];
       
  3887 			}
       
  3888 
       
  3889 			if ( match[2] === "~=" ) {
       
  3890 				match[4] = " " + match[4] + " ";
       
  3891 			}
       
  3892 
       
  3893 			return match;
       
  3894 		},
       
  3895 		PSEUDO: function(match, curLoop, inplace, result, not){
       
  3896 			if ( match[1] === "not" ) {
       
  3897 				// If we're dealing with a complex expression, or a simple one
       
  3898 				if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
       
  3899 					match[3] = Sizzle(match[3], null, null, curLoop);
       
  3900 				} else {
       
  3901 					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
       
  3902 					if ( !inplace ) {
       
  3903 						result.push.apply( result, ret );
       
  3904 					}
       
  3905 					return false;
       
  3906 				}
       
  3907 			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
       
  3908 				return true;
       
  3909 			}
       
  3910 			
       
  3911 			return match;
       
  3912 		},
       
  3913 		POS: function(match){
       
  3914 			match.unshift( true );
       
  3915 			return match;
       
  3916 		}
       
  3917 	},
       
  3918 	filters: {
       
  3919 		enabled: function(elem){
       
  3920 			return elem.disabled === false && elem.type !== "hidden";
       
  3921 		},
       
  3922 		disabled: function(elem){
       
  3923 			return elem.disabled === true;
       
  3924 		},
       
  3925 		checked: function(elem){
       
  3926 			return elem.checked === true;
       
  3927 		},
       
  3928 		selected: function(elem){
       
  3929 			// Accessing this property makes selected-by-default
       
  3930 			// options in Safari work properly
       
  3931 			elem.parentNode.selectedIndex;
       
  3932 			return elem.selected === true;
       
  3933 		},
       
  3934 		parent: function(elem){
       
  3935 			return !!elem.firstChild;
       
  3936 		},
       
  3937 		empty: function(elem){
       
  3938 			return !elem.firstChild;
       
  3939 		},
       
  3940 		has: function(elem, i, match){
       
  3941 			return !!Sizzle( match[3], elem ).length;
       
  3942 		},
       
  3943 		header: function(elem){
       
  3944 			return /h\d/i.test( elem.nodeName );
       
  3945 		},
       
  3946 		text: function(elem){
       
  3947 			return "text" === elem.type;
       
  3948 		},
       
  3949 		radio: function(elem){
       
  3950 			return "radio" === elem.type;
       
  3951 		},
       
  3952 		checkbox: function(elem){
       
  3953 			return "checkbox" === elem.type;
       
  3954 		},
       
  3955 		file: function(elem){
       
  3956 			return "file" === elem.type;
       
  3957 		},
       
  3958 		password: function(elem){
       
  3959 			return "password" === elem.type;
       
  3960 		},
       
  3961 		submit: function(elem){
       
  3962 			return "submit" === elem.type;
       
  3963 		},
       
  3964 		image: function(elem){
       
  3965 			return "image" === elem.type;
       
  3966 		},
       
  3967 		reset: function(elem){
       
  3968 			return "reset" === elem.type;
       
  3969 		},
       
  3970 		button: function(elem){
       
  3971 			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
       
  3972 		},
       
  3973 		input: function(elem){
       
  3974 			return /input|select|textarea|button/i.test(elem.nodeName);
       
  3975 		}
       
  3976 	},
       
  3977 	setFilters: {
       
  3978 		first: function(elem, i){
       
  3979 			return i === 0;
       
  3980 		},
       
  3981 		last: function(elem, i, match, array){
       
  3982 			return i === array.length - 1;
       
  3983 		},
       
  3984 		even: function(elem, i){
       
  3985 			return i % 2 === 0;
       
  3986 		},
       
  3987 		odd: function(elem, i){
       
  3988 			return i % 2 === 1;
       
  3989 		},
       
  3990 		lt: function(elem, i, match){
       
  3991 			return i < match[3] - 0;
       
  3992 		},
       
  3993 		gt: function(elem, i, match){
       
  3994 			return i > match[3] - 0;
       
  3995 		},
       
  3996 		nth: function(elem, i, match){
       
  3997 			return match[3] - 0 == i;
       
  3998 		},
       
  3999 		eq: function(elem, i, match){
       
  4000 			return match[3] - 0 == i;
       
  4001 		}
       
  4002 	},
       
  4003 	filter: {
       
  4004 		PSEUDO: function(elem, match, i, array){
       
  4005 			var name = match[1], filter = Expr.filters[ name ];
       
  4006 
       
  4007 			if ( filter ) {
       
  4008 				return filter( elem, i, match, array );
       
  4009 			} else if ( name === "contains" ) {
       
  4010 				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
       
  4011 			} else if ( name === "not" ) {
       
  4012 				var not = match[3];
       
  4013 
       
  4014 				for ( var i = 0, l = not.length; i < l; i++ ) {
       
  4015 					if ( not[i] === elem ) {
       
  4016 						return false;
       
  4017 					}
       
  4018 				}
       
  4019 
       
  4020 				return true;
       
  4021 			}
       
  4022 		},
       
  4023 		CHILD: function(elem, match){
       
  4024 			var type = match[1], node = elem;
       
  4025 			switch (type) {
       
  4026 				case 'only':
       
  4027 				case 'first':
       
  4028 					while (node = node.previousSibling)  {
       
  4029 						if ( node.nodeType === 1 ) return false;
       
  4030 					}
       
  4031 					if ( type == 'first') return true;
       
  4032 					node = elem;
       
  4033 				case 'last':
       
  4034 					while (node = node.nextSibling)  {
       
  4035 						if ( node.nodeType === 1 ) return false;
       
  4036 					}
       
  4037 					return true;
       
  4038 				case 'nth':
       
  4039 					var first = match[2], last = match[3];
       
  4040 
       
  4041 					if ( first == 1 && last == 0 ) {
       
  4042 						return true;
       
  4043 					}
       
  4044 					
       
  4045 					var doneName = match[0],
       
  4046 						parent = elem.parentNode;
       
  4047 	
       
  4048 					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
       
  4049 						var count = 0;
       
  4050 						for ( node = parent.firstChild; node; node = node.nextSibling ) {
       
  4051 							if ( node.nodeType === 1 ) {
       
  4052 								node.nodeIndex = ++count;
       
  4053 							}
       
  4054 						} 
       
  4055 						parent.sizcache = doneName;
       
  4056 					}
       
  4057 					
       
  4058 					var diff = elem.nodeIndex - last;
       
  4059 					if ( first == 0 ) {
       
  4060 						return diff == 0;
       
  4061 					} else {
       
  4062 						return ( diff % first == 0 && diff / first >= 0 );
       
  4063 					}
       
  4064 			}
       
  4065 		},
       
  4066 		ID: function(elem, match){
       
  4067 			return elem.nodeType === 1 && elem.getAttribute("id") === match;
       
  4068 		},
       
  4069 		TAG: function(elem, match){
       
  4070 			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
       
  4071 		},
       
  4072 		CLASS: function(elem, match){
       
  4073 			return (" " + (elem.className || elem.getAttribute("class")) + " ")
       
  4074 				.indexOf( match ) > -1;
       
  4075 		},
       
  4076 		ATTR: function(elem, match){
       
  4077 			var name = match[1],
       
  4078 				result = Expr.attrHandle[ name ] ?
       
  4079 					Expr.attrHandle[ name ]( elem ) :
       
  4080 					elem[ name ] != null ?
       
  4081 						elem[ name ] :
       
  4082 						elem.getAttribute( name ),
       
  4083 				value = result + "",
       
  4084 				type = match[2],
       
  4085 				check = match[4];
       
  4086 
       
  4087 			return result == null ?
       
  4088 				type === "!=" :
       
  4089 				type === "=" ?
       
  4090 				value === check :
       
  4091 				type === "*=" ?
       
  4092 				value.indexOf(check) >= 0 :
       
  4093 				type === "~=" ?
       
  4094 				(" " + value + " ").indexOf(check) >= 0 :
       
  4095 				!check ?
       
  4096 				value && result !== false :
       
  4097 				type === "!=" ?
       
  4098 				value != check :
       
  4099 				type === "^=" ?
       
  4100 				value.indexOf(check) === 0 :
       
  4101 				type === "$=" ?
       
  4102 				value.substr(value.length - check.length) === check :
       
  4103 				type === "|=" ?
       
  4104 				value === check || value.substr(0, check.length + 1) === check + "-" :
       
  4105 				false;
       
  4106 		},
       
  4107 		POS: function(elem, match, i, array){
       
  4108 			var name = match[2], filter = Expr.setFilters[ name ];
       
  4109 
       
  4110 			if ( filter ) {
       
  4111 				return filter( elem, i, match, array );
       
  4112 			}
       
  4113 		}
       
  4114 	}
       
  4115 };
       
  4116 
       
  4117 var origPOS = Expr.match.POS;
       
  4118 
       
  4119 for ( var type in Expr.match ) {
       
  4120 	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
       
  4121 }
       
  4122 
       
  4123 var makeArray = function(array, results) {
       
  4124 	array = Array.prototype.slice.call( array );
       
  4125 
       
  4126 	if ( results ) {
       
  4127 		results.push.apply( results, array );
       
  4128 		return results;
       
  4129 	}
       
  4130 	
       
  4131 	return array;
       
  4132 };
       
  4133 
       
  4134 // Perform a simple check to determine if the browser is capable of
       
  4135 // converting a NodeList to an array using builtin methods.
       
  4136 try {
       
  4137 	Array.prototype.slice.call( document.documentElement.childNodes );
       
  4138 
       
  4139 // Provide a fallback method if it does not work
       
  4140 } catch(e){
       
  4141 	makeArray = function(array, results) {
       
  4142 		var ret = results || [];
       
  4143 
       
  4144 		if ( toString.call(array) === "[object Array]" ) {
       
  4145 			Array.prototype.push.apply( ret, array );
       
  4146 		} else {
       
  4147 			if ( typeof array.length === "number" ) {
       
  4148 				for ( var i = 0, l = array.length; i < l; i++ ) {
       
  4149 					ret.push( array[i] );
       
  4150 				}
       
  4151 			} else {
       
  4152 				for ( var i = 0; array[i]; i++ ) {
       
  4153 					ret.push( array[i] );
       
  4154 				}
       
  4155 			}
       
  4156 		}
       
  4157 
       
  4158 		return ret;
       
  4159 	};
       
  4160 }
       
  4161 
       
  4162 var sortOrder;
       
  4163 
       
  4164 if ( document.documentElement.compareDocumentPosition ) {
       
  4165 	sortOrder = function( a, b ) {
       
  4166 		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
       
  4167 		if ( ret === 0 ) {
       
  4168 			hasDuplicate = true;
       
  4169 		}
       
  4170 		return ret;
       
  4171 	};
       
  4172 } else if ( "sourceIndex" in document.documentElement ) {
       
  4173 	sortOrder = function( a, b ) {
       
  4174 		var ret = a.sourceIndex - b.sourceIndex;
       
  4175 		if ( ret === 0 ) {
       
  4176 			hasDuplicate = true;
       
  4177 		}
       
  4178 		return ret;
       
  4179 	};
       
  4180 } else if ( document.createRange ) {
       
  4181 	sortOrder = function( a, b ) {
       
  4182 		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
       
  4183 		aRange.setStart(a, 0);
       
  4184 		aRange.setEnd(a, 0);
       
  4185 		bRange.setStart(b, 0);
       
  4186 		bRange.setEnd(b, 0);
       
  4187 		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
       
  4188 		if ( ret === 0 ) {
       
  4189 			hasDuplicate = true;
       
  4190 		}
       
  4191 		return ret;
       
  4192 	};
       
  4193 }
       
  4194 
       
  4195 // Check to see if the browser returns elements by name when
       
  4196 // querying by getElementById (and provide a workaround)
       
  4197 (function(){
       
  4198 	// We're going to inject a fake input element with a specified name
       
  4199 	var form = document.createElement("div"),
       
  4200 		id = "script" + (new Date).getTime();
       
  4201 	form.innerHTML = "<a name='" + id + "'/>";
       
  4202 
       
  4203 	// Inject it into the root element, check its status, and remove it quickly
       
  4204 	var root = document.documentElement;
       
  4205 	root.insertBefore( form, root.firstChild );
       
  4206 
       
  4207 	// The workaround has to do additional checks after a getElementById
       
  4208 	// Which slows things down for other browsers (hence the branching)
       
  4209 	if ( !!document.getElementById( id ) ) {
       
  4210 		Expr.find.ID = function(match, context, isXML){
       
  4211 			if ( typeof context.getElementById !== "undefined" && !isXML ) {
       
  4212 				var m = context.getElementById(match[1]);
       
  4213 				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
       
  4214 			}
       
  4215 		};
       
  4216 
       
  4217 		Expr.filter.ID = function(elem, match){
       
  4218 			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
       
  4219 			return elem.nodeType === 1 && node && node.nodeValue === match;
       
  4220 		};
       
  4221 	}
       
  4222 
       
  4223 	root.removeChild( form );
       
  4224 })();
       
  4225 
       
  4226 (function(){
       
  4227 	// Check to see if the browser returns only elements
       
  4228 	// when doing getElementsByTagName("*")
       
  4229 
       
  4230 	// Create a fake element
       
  4231 	var div = document.createElement("div");
       
  4232 	div.appendChild( document.createComment("") );
       
  4233 
       
  4234 	// Make sure no comments are found
       
  4235 	if ( div.getElementsByTagName("*").length > 0 ) {
       
  4236 		Expr.find.TAG = function(match, context){
       
  4237 			var results = context.getElementsByTagName(match[1]);
       
  4238 
       
  4239 			// Filter out possible comments
       
  4240 			if ( match[1] === "*" ) {
       
  4241 				var tmp = [];
       
  4242 
       
  4243 				for ( var i = 0; results[i]; i++ ) {
       
  4244 					if ( results[i].nodeType === 1 ) {
       
  4245 						tmp.push( results[i] );
       
  4246 					}
       
  4247 				}
       
  4248 
       
  4249 				results = tmp;
       
  4250 			}
       
  4251 
       
  4252 			return results;
       
  4253 		};
       
  4254 	}
       
  4255 
       
  4256 	// Check to see if an attribute returns normalized href attributes
       
  4257 	div.innerHTML = "<a href='#'></a>";
       
  4258 	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
       
  4259 			div.firstChild.getAttribute("href") !== "#" ) {
       
  4260 		Expr.attrHandle.href = function(elem){
       
  4261 			return elem.getAttribute("href", 2);
       
  4262 		};
       
  4263 	}
       
  4264 })();
       
  4265 
       
  4266 if ( document.querySelectorAll ) (function(){
       
  4267 	var oldSizzle = Sizzle, div = document.createElement("div");
       
  4268 	div.innerHTML = "<p class='TEST'></p>";
       
  4269 
       
  4270 	// Safari can't handle uppercase or unicode characters when
       
  4271 	// in quirks mode.
       
  4272 	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
       
  4273 		return;
       
  4274 	}
       
  4275 	
       
  4276 	Sizzle = function(query, context, extra, seed){
       
  4277 		context = context || document;
       
  4278 
       
  4279 		// Only use querySelectorAll on non-XML documents
       
  4280 		// (ID selectors don't work in non-HTML documents)
       
  4281 		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
       
  4282 			try {
       
  4283 				return makeArray( context.querySelectorAll(query), extra );
       
  4284 			} catch(e){}
       
  4285 		}
       
  4286 		
       
  4287 		return oldSizzle(query, context, extra, seed);
       
  4288 	};
       
  4289 
       
  4290 	for ( var prop in oldSizzle ) {
       
  4291 		Sizzle[ prop ] = oldSizzle[ prop ];
       
  4292 	}
       
  4293 })();
       
  4294 
       
  4295 if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
       
  4296 	var div = document.createElement("div");
       
  4297 	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
       
  4298 
       
  4299 	// Opera can't find a second classname (in 9.6)
       
  4300 	if ( div.getElementsByClassName("e").length === 0 )
       
  4301 		return;
       
  4302 
       
  4303 	// Safari caches class attributes, doesn't catch changes (in 3.2)
       
  4304 	div.lastChild.className = "e";
       
  4305 
       
  4306 	if ( div.getElementsByClassName("e").length === 1 )
       
  4307 		return;
       
  4308 
       
  4309 	Expr.order.splice(1, 0, "CLASS");
       
  4310 	Expr.find.CLASS = function(match, context, isXML) {
       
  4311 		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
       
  4312 			return context.getElementsByClassName(match[1]);
       
  4313 		}
       
  4314 	};
       
  4315 })();
       
  4316 
       
  4317 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
       
  4318 	var sibDir = dir == "previousSibling" && !isXML;
       
  4319 	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
       
  4320 		var elem = checkSet[i];
       
  4321 		if ( elem ) {
       
  4322 			if ( sibDir && elem.nodeType === 1 ){
       
  4323 				elem.sizcache = doneName;
       
  4324 				elem.sizset = i;
       
  4325 			}
       
  4326 			elem = elem[dir];
       
  4327 			var match = false;
       
  4328 
       
  4329 			while ( elem ) {
       
  4330 				if ( elem.sizcache === doneName ) {
       
  4331 					match = checkSet[elem.sizset];
       
  4332 					break;
       
  4333 				}
       
  4334 
       
  4335 				if ( elem.nodeType === 1 && !isXML ){
       
  4336 					elem.sizcache = doneName;
       
  4337 					elem.sizset = i;
       
  4338 				}
       
  4339 
       
  4340 				if ( elem.nodeName === cur ) {
       
  4341 					match = elem;
       
  4342 					break;
       
  4343 				}
       
  4344 
       
  4345 				elem = elem[dir];
       
  4346 			}
       
  4347 
       
  4348 			checkSet[i] = match;
       
  4349 		}
       
  4350 	}
       
  4351 }
       
  4352 
       
  4353 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
       
  4354 	var sibDir = dir == "previousSibling" && !isXML;
       
  4355 	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
       
  4356 		var elem = checkSet[i];
       
  4357 		if ( elem ) {
       
  4358 			if ( sibDir && elem.nodeType === 1 ) {
       
  4359 				elem.sizcache = doneName;
       
  4360 				elem.sizset = i;
       
  4361 			}
       
  4362 			elem = elem[dir];
       
  4363 			var match = false;
       
  4364 
       
  4365 			while ( elem ) {
       
  4366 				if ( elem.sizcache === doneName ) {
       
  4367 					match = checkSet[elem.sizset];
       
  4368 					break;
       
  4369 				}
       
  4370 
       
  4371 				if ( elem.nodeType === 1 ) {
       
  4372 					if ( !isXML ) {
       
  4373 						elem.sizcache = doneName;
       
  4374 						elem.sizset = i;
       
  4375 					}
       
  4376 					if ( typeof cur !== "string" ) {
       
  4377 						if ( elem === cur ) {
       
  4378 							match = true;
       
  4379 							break;
       
  4380 						}
       
  4381 
       
  4382 					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
       
  4383 						match = elem;
       
  4384 						break;
       
  4385 					}
       
  4386 				}
       
  4387 
       
  4388 				elem = elem[dir];
       
  4389 			}
       
  4390 
       
  4391 			checkSet[i] = match;
       
  4392 		}
       
  4393 	}
       
  4394 }
       
  4395 
       
  4396 var contains = document.compareDocumentPosition ?  function(a, b){
       
  4397 	return a.compareDocumentPosition(b) & 16;
       
  4398 } : function(a, b){
       
  4399 	return a !== b && (a.contains ? a.contains(b) : true);
       
  4400 };
       
  4401 
       
  4402 var isXML = function(elem){
       
  4403 	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
       
  4404 		!!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
       
  4405 };
       
  4406 
       
  4407 var posProcess = function(selector, context){
       
  4408 	var tmpSet = [], later = "", match,
       
  4409 		root = context.nodeType ? [context] : context;
       
  4410 
       
  4411 	// Position selectors must be done after the filter
       
  4412 	// And so must :not(positional) so we move all PSEUDOs to the end
       
  4413 	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
       
  4414 		later += match[0];
       
  4415 		selector = selector.replace( Expr.match.PSEUDO, "" );
       
  4416 	}
       
  4417 
       
  4418 	selector = Expr.relative[selector] ? selector + "*" : selector;
       
  4419 
       
  4420 	for ( var i = 0, l = root.length; i < l; i++ ) {
       
  4421 		Sizzle( selector, root[i], tmpSet );
       
  4422 	}
       
  4423 
       
  4424 	return Sizzle.filter( later, tmpSet );
       
  4425 };
       
  4426 
       
  4427 // EXPOSE
       
  4428 
       
  4429 window.tinymce.dom.Sizzle = Sizzle;
       
  4430 
       
  4431 })();
       
  4432 
       
  4433 (function(tinymce) {
  2492 	// Shorten names
  4434 	// Shorten names
  2493 	var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;
  4435 	var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;
  2494 
  4436 
  2495 	tinymce.create('static tinymce.dom.Event', {
  4437 	tinymce.create('tinymce.dom.EventUtils', {
  2496 		inits : [],
  4438 		EventUtils : function() {
  2497 		events : [],
  4439 			this.inits = [];
  2498 
  4440 			this.events = [];
  2499 		// #if !jquery
  4441 		},
  2500 
  4442 
  2501 		add : function(o, n, f, s) {
  4443 		add : function(o, n, f, s) {
  2502 			var cb, t = this, el = t.events, r;
  4444 			var cb, t = this, el = t.events, r;
  2503 
  4445 
       
  4446 			if (n instanceof Array) {
       
  4447 				r = [];
       
  4448 
       
  4449 				each(n, function(n) {
       
  4450 					r.push(t.add(o, n, f, s));
       
  4451 				});
       
  4452 
       
  4453 				return r;
       
  4454 			}
       
  4455 
  2504 			// Handle array
  4456 			// Handle array
  2505 			if (o && o instanceof Array) {
  4457 			if (o && o.hasOwnProperty && o instanceof Array) {
  2506 				r = [];
  4458 				r = [];
  2507 
  4459 
  2508 				each(o, function(o) {
  4460 				each(o, function(o) {
  2509 					o = DOM.get(o);
  4461 					o = DOM.get(o);
  2510 					r.push(t.add(o, n, f, s));
  4462 					r.push(t.add(o, n, f, s));
  2518 			if (!o)
  4470 			if (!o)
  2519 				return;
  4471 				return;
  2520 
  4472 
  2521 			// Setup event callback
  4473 			// Setup event callback
  2522 			cb = function(e) {
  4474 			cb = function(e) {
       
  4475 				// Is all events disabled
       
  4476 				if (t.disabled)
       
  4477 					return;
       
  4478 
  2523 				e = e || window.event;
  4479 				e = e || window.event;
  2524 
  4480 
  2525 				// Patch in target in IE it's W3C valid
  4481 				// Patch in target, preventDefault and stopPropagation in IE it's W3C valid
  2526 				if (e && !e.target && isIE)
  4482 				if (e && isIE) {
  2527 					e.target = e.srcElement;
  4483 					if (!e.target)
       
  4484 						e.target = e.srcElement;
       
  4485 
       
  4486 					// Patch in preventDefault, stopPropagation methods for W3C compatibility
       
  4487 					tinymce.extend(e, t._stoppers);
       
  4488 				}
  2528 
  4489 
  2529 				if (!s)
  4490 				if (!s)
  2530 					return f(e);
  4491 					return f(e);
  2531 
  4492 
  2532 				return f.call(s, e);
  4493 				return f.call(s, e);
  2562 
  4523 
  2563 		remove : function(o, n, f) {
  4524 		remove : function(o, n, f) {
  2564 			var t = this, a = t.events, s = false, r;
  4525 			var t = this, a = t.events, s = false, r;
  2565 
  4526 
  2566 			// Handle array
  4527 			// Handle array
  2567 			if (o && o instanceof Array) {
  4528 			if (o && o.hasOwnProperty && o instanceof Array) {
  2568 				r = [];
  4529 				r = [];
  2569 
  4530 
  2570 				each(o, function(o) {
  4531 				each(o, function(o) {
  2571 					o = DOM.get(o);
  4532 					o = DOM.get(o);
  2572 					r.push(t.remove(o, n, f));
  4533 					r.push(t.remove(o, n, f));
  2605 					}
  4566 					}
  2606 				}
  4567 				}
  2607 			}
  4568 			}
  2608 		},
  4569 		},
  2609 
  4570 
  2610 		// #endif
       
  2611 
       
  2612 		cancel : function(e) {
  4571 		cancel : function(e) {
  2613 			if (!e)
  4572 			if (!e)
  2614 				return false;
  4573 				return false;
  2615 
  4574 
  2616 			this.stop(e);
  4575 			this.stop(e);
       
  4576 
  2617 			return this.prevent(e);
  4577 			return this.prevent(e);
  2618 		},
  4578 		},
  2619 
  4579 
  2620 		stop : function(e) {
  4580 		stop : function(e) {
  2621 			if (e.stopPropagation)
  4581 			if (e.stopPropagation)
  2633 				e.returnValue = false;
  4593 				e.returnValue = false;
  2634 
  4594 
  2635 			return false;
  4595 			return false;
  2636 		},
  4596 		},
  2637 
  4597 
  2638 		_unload : function() {
  4598 		destroy : function() {
  2639 			var t = Event;
  4599 			var t = this;
  2640 
  4600 
  2641 			each(t.events, function(e, i) {
  4601 			each(t.events, function(e, i) {
  2642 				t._remove(e.obj, e.name, e.cfunc);
  4602 				t._remove(e.obj, e.name, e.cfunc);
  2643 				e.obj = e.cfunc = null;
  4603 				e.obj = e.cfunc = null;
  2644 			});
  4604 			});
  2669 					// Might fail with permission denined on IE so we just ignore that
  4629 					// Might fail with permission denined on IE so we just ignore that
  2670 				}
  4630 				}
  2671 			}
  4631 			}
  2672 		},
  4632 		},
  2673 
  4633 
  2674 		_pageInit : function() {
  4634 		_pageInit : function(win) {
  2675 			var e = Event;
  4635 			var t = this;
  2676 
  4636 
  2677 			// Safari on Mac fires this twice
  4637 			// Keep it from running more than once
  2678 			if (e.domLoaded)
  4638 			if (t.domLoaded)
  2679 				return;
  4639 				return;
  2680 
  4640 
  2681 			e._remove(window, 'DOMContentLoaded', e._pageInit);
  4641 			t.domLoaded = true;
  2682 			e.domLoaded = true;
  4642 
  2683 
  4643 			each(t.inits, function(c) {
  2684 			each(e.inits, function(c) {
       
  2685 				c();
  4644 				c();
  2686 			});
  4645 			});
  2687 
  4646 
  2688 			e.inits = [];
  4647 			t.inits = [];
  2689 		},
  4648 		},
  2690 
  4649 
  2691 		_wait : function() {
  4650 		_wait : function(win) {
  2692 			var t;
  4651 			var t = this, doc = win.document;
  2693 
  4652 
  2694 			// No need since the document is already loaded
  4653 			// No need since the document is already loaded
  2695 			if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) {
  4654 			if (win.tinyMCE_GZ && tinyMCE_GZ.loaded) {
  2696 				Event.domLoaded = 1;
  4655 				t.domLoaded = 1;
  2697 				return;
  4656 				return;
  2698 			}
  4657 			}
  2699 
  4658 
  2700 			if (isIE && document.location.protocol != 'https:') {
  4659 			// Use IE method
  2701 				// Fake DOMContentLoaded on IE
  4660 			if (doc.attachEvent) {
  2702 				document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');
  4661 				doc.attachEvent("onreadystatechange", function() {
  2703 				DOM.get("__ie_onload").onreadystatechange = function() {
  4662 					if (doc.readyState === "complete") {
  2704 					if (this.readyState == "complete") {
  4663 						doc.detachEvent("onreadystatechange", arguments.callee);
  2705 						Event._pageInit();
  4664 						t._pageInit(win);
  2706 						DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak
       
  2707 					}
  4665 					}
  2708 				};
  4666 				});
  2709 			} else {
  4667 
  2710 				Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);
  4668 				if (doc.documentElement.doScroll && win == win.top) {
  2711 
  4669 					(function() {
  2712 				if (isIE || isWebKit) {
  4670 						if (t.domLoaded)
  2713 					t = setInterval(function() {
  4671 							return;
  2714 						if (/loaded|complete/.test(document.readyState)) {
  4672 
  2715 							clearInterval(t);
  4673 						try {
  2716 							Event._pageInit();
  4674 							// If IE is used, use the trick by Diego Perini
       
  4675 							// http://javascript.nwbox.com/IEContentLoaded/
       
  4676 							doc.documentElement.doScroll("left");
       
  4677 						} catch (ex) {
       
  4678 							setTimeout(arguments.callee, 0);
       
  4679 							return;
  2717 						}
  4680 						}
  2718 					}, 10);
  4681 
  2719 				}
  4682 						t._pageInit(win);
       
  4683 					})();
       
  4684 				}
       
  4685 			} else if (doc.addEventListener) {
       
  4686 				t._add(win, 'DOMContentLoaded', function() {
       
  4687 					t._pageInit(win);
       
  4688 				});
       
  4689 			}
       
  4690 
       
  4691 			t._add(win, 'load', function() {
       
  4692 				t._pageInit(win);
       
  4693 			});
       
  4694 		},
       
  4695 
       
  4696 		_stoppers : {
       
  4697 			preventDefault :  function() {
       
  4698 				this.returnValue = false;
       
  4699 			},
       
  4700 
       
  4701 			stopPropagation : function() {
       
  4702 				this.cancelBubble = true;
  2720 			}
  4703 			}
  2721 		}
  4704 		}
  2722 
  4705 	});
  2723 		});
  4706 
  2724 
  4707 	Event = tinymce.dom.Event = new tinymce.dom.EventUtils();
  2725 	// Shorten name
       
  2726 	Event = tinymce.dom.Event;
       
  2727 
  4708 
  2728 	// Dispatch DOM content loaded event for IE and Safari
  4709 	// Dispatch DOM content loaded event for IE and Safari
  2729 	Event._wait();
  4710 	Event._wait(window);
  2730 	tinymce.addUnload(Event._unload);
  4711 
  2731 })();
  4712 	tinymce.addUnload(function() {
  2732 
  4713 		Event.destroy();
  2733 /* file:jscripts/tiny_mce/classes/dom/Element.js */
  4714 	});
  2734 
  4715 })(tinymce);
  2735 (function() {
  4716 (function(tinymce) {
  2736 	var each = tinymce.each;
  4717 	var each = tinymce.each;
  2737 
  4718 
  2738 	tinymce.create('tinymce.dom.Element', {
  4719 	tinymce.create('tinymce.dom.Element', {
  2739 		Element : function(id, s) {
  4720 		Element : function(id, s) {
  2740 			var t = this, dom, el;
  4721 			var t = this, dom, el;
  2770 				'isHidden',
  4751 				'isHidden',
  2771 				'setHTML',
  4752 				'setHTML',
  2772 				'get'
  4753 				'get'
  2773 			], function(k) {
  4754 			], function(k) {
  2774 				t[k] = function() {
  4755 				t[k] = function() {
  2775 					var a = arguments, o;
  4756 					var a = [id], i;
  2776 
  4757 
  2777 					// Opera fails
  4758 					for (i = 0; i < arguments.length; i++)
  2778 					if (tinymce.isOpera) {
  4759 						a.push(arguments[i]);
  2779 						a = [id];
  4760 
  2780 
  4761 					a = dom[k].apply(dom, a);
  2781 						each(arguments, function(v) {
       
  2782 							a.push(v);
       
  2783 						});
       
  2784 					} else
       
  2785 						Array.prototype.unshift.call(a, el || id);
       
  2786 
       
  2787 					o = dom[k].apply(dom, a);
       
  2788 					t.update(k);
  4762 					t.update(k);
  2789 
  4763 
  2790 					return o;
  4764 					return a;
  2791 				};
  4765 				};
  2792 			});
  4766 			});
  2793 		},
  4767 		},
  2794 
  4768 
  2795 		on : function(n, f, s) {
  4769 		on : function(n, f, s) {
  2861 				dom.setStyle(b, 'height', t.getStyle('height', 1));
  4835 				dom.setStyle(b, 'height', t.getStyle('height', 1));
  2862 				dom.setStyle(b, 'display', t.getStyle('display', 1));
  4836 				dom.setStyle(b, 'display', t.getStyle('display', 1));
  2863 				dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);
  4837 				dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);
  2864 			}
  4838 			}
  2865 		}
  4839 		}
  2866 
  4840 	});
  2867 		});
  4841 })(tinymce);
  2868 })();
  4842 (function(tinymce) {
  2869 
       
  2870 /* file:jscripts/tiny_mce/classes/dom/Selection.js */
       
  2871 
       
  2872 (function() {
       
  2873 	function trimNl(s) {
  4843 	function trimNl(s) {
  2874 		return s.replace(/[\n\r]+/g, '');
  4844 		return s.replace(/[\n\r]+/g, '');
  2875 	};
  4845 	};
  2876 
  4846 
  2877 	// Shorten names
  4847 	// Shorten names
  2893 				'onGetContent'
  4863 				'onGetContent'
  2894 			], function(e) {
  4864 			], function(e) {
  2895 				t[e] = new tinymce.util.Dispatcher(t);
  4865 				t[e] = new tinymce.util.Dispatcher(t);
  2896 			});
  4866 			});
  2897 
  4867 
       
  4868 			// No W3C Range support
       
  4869 			if (!t.win.getSelection)
       
  4870 				t.tridentSel = new tinymce.dom.TridentSelection(t);
       
  4871 
  2898 			// Prevent leaks
  4872 			// Prevent leaks
  2899 			tinymce.addUnload(t.destroy, t);
  4873 			tinymce.addUnload(t.destroy, t);
  2900 		},
  4874 		},
  2901 
  4875 
  2902 		getContent : function(s) {
  4876 		getContent : function(s) {
  2963 				r.setStartBefore(c);
  4937 				r.setStartBefore(c);
  2964 				r.setEndAfter(c);
  4938 				r.setEndAfter(c);
  2965 				t.setRng(r);
  4939 				t.setRng(r);
  2966 
  4940 
  2967 				// Delete the marker, and hopefully the caret gets placed in the right location
  4941 				// Delete the marker, and hopefully the caret gets placed in the right location
  2968 				d.execCommand('Delete', false, null);
  4942 				// Removed this since it seems to remove &nbsp; in FF and simply deleting it
  2969 
  4943 				// doesn't seem to affect the caret position in any browser
  2970 				// In case it's still there
  4944 				//d.execCommand('Delete', false, null);
       
  4945 
       
  4946 				// Remove the caret position
  2971 				t.dom.remove('__caret');
  4947 				t.dom.remove('__caret');
  2972 			} else {
  4948 			} else {
  2973 				if (r.item) {
  4949 				if (r.item) {
  2974 					// Delete content and get caret text selection
  4950 					// Delete content and get caret text selection
  2975 					d.execCommand('Delete', false, null);
  4951 					d.execCommand('Delete', false, null);
  3002 				e = r.startContainer;
  4978 				e = r.startContainer;
  3003 
  4979 
  3004 				if (e.nodeName == 'BODY')
  4980 				if (e.nodeName == 'BODY')
  3005 					return e.firstChild;
  4981 					return e.firstChild;
  3006 
  4982 
  3007 				return t.dom.getParent(e, function(n) {return n.nodeType == 1;});
  4983 				return t.dom.getParent(e, '*');
  3008 			}
  4984 			}
  3009 		},
  4985 		},
  3010 
  4986 
  3011 		getEnd : function() {
  4987 		getEnd : function() {
  3012 			var t = this, r = t.getRng(), e;
  4988 			var t = this, r = t.getRng(), e;
  3027 				e = r.endContainer;
  5003 				e = r.endContainer;
  3028 
  5004 
  3029 				if (e.nodeName == 'BODY')
  5005 				if (e.nodeName == 'BODY')
  3030 					return e.lastChild;
  5006 					return e.lastChild;
  3031 
  5007 
  3032 				return t.dom.getParent(e, function(n) {return n.nodeType == 1;});
  5008 				return t.dom.getParent(e, '*');
  3033 			}
  5009 			}
  3034 		},
  5010 		},
  3035 
  5011 
  3036 		getBookmark : function(si) {
  5012 		getBookmark : function(si) {
  3037 			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;
  5013 			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;
  3038 			sx = vp.x;
  5014 			sx = vp.x;
  3039 			sy = vp.y;
  5015 			sy = vp.y;
  3040 
  5016 
  3041 			// Simple bookmark fast but not as persistent
  5017 			// Simple bookmark fast but not as persistent
  3042 			if (si == 'simple')
  5018 			if (si)
  3043 				return {rng : r, scrollX : sx, scrollY : sy};
  5019 				return {rng : r, scrollX : sx, scrollY : sy};
  3044 
  5020 
  3045 			// Handle IE
  5021 			// Handle IE
  3046 			if (isIE) {
  5022 			if (isIE) {
  3047 				// Control selection
  5023 				// Control selection
  3199 
  5175 
  3200 			t.win.scrollTo(b.scrollX, b.scrollY);
  5176 			t.win.scrollTo(b.scrollX, b.scrollY);
  3201 
  5177 
  3202 			// Handle explorer
  5178 			// Handle explorer
  3203 			if (isIE) {
  5179 			if (isIE) {
       
  5180 				t.tridentSel.destroy();
       
  5181 
  3204 				// Handle simple
  5182 				// Handle simple
  3205 				if (r = b.rng) {
  5183 				if (r = b.rng) {
  3206 					try {
  5184 					try {
  3207 						r.select();
  5185 						r.select();
  3208 					} catch (ex) {
  5186 					} catch (ex) {
  3279 		},
  5257 		},
  3280 
  5258 
  3281 		select : function(n, c) {
  5259 		select : function(n, c) {
  3282 			var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;
  5260 			var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;
  3283 
  5261 
  3284 			function first(n) {
  5262 			function find(n, start) {
  3285 				return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;
  5263 				var walker, o;
  3286 			};
  5264 
  3287 
  5265 				if (n) {
  3288 			function last(n) {
  5266 					walker = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
  3289 				var c, o, w;
  5267 
  3290 
  5268 					// Find first/last non empty text node
  3291 				if (!n)
  5269 					while (n = walker.nextNode()) {
  3292 					return null;
  5270 						o = n;
  3293 
  5271 
  3294 				w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
  5272 						if (tinymce.trim(n.nodeValue).length != 0) {
  3295 				while (c = w.nextNode())
  5273 							if (start)
  3296 					o = c;
  5274 								return n;
       
  5275 							else
       
  5276 								o = n;
       
  5277 						}
       
  5278 					}
       
  5279 				}
  3297 
  5280 
  3298 				return o;
  5281 				return o;
  3299 			};
  5282 			};
  3300 
  5283 
  3301 			if (isIE) {
  5284 			if (isIE) {
  3314 				} catch (ex) {
  5297 				} catch (ex) {
  3315 					// Throws illigal agrument in IE some times
  5298 					// Throws illigal agrument in IE some times
  3316 				}
  5299 				}
  3317 			} else {
  5300 			} else {
  3318 				if (c) {
  5301 				if (c) {
  3319 					fn = first(n);
  5302 					fn = find(n, 1) || t.dom.select('br:first', n)[0];
  3320 					ln = last(n);
  5303 					ln = find(n, 0) || t.dom.select('br:last', n)[0];
  3321 
  5304 
  3322 					if (fn && ln) {
  5305 					if (fn && ln) {
  3323 						//console.debug(fn, ln);
       
  3324 						r = d.createRange();
  5306 						r = d.createRange();
  3325 						r.setStart(fn, 0);
  5307 
  3326 						r.setEnd(ln, ln.nodeValue.length);
  5308 						if (fn.nodeName == 'BR')
       
  5309 							r.setStartBefore(fn);
       
  5310 						else
       
  5311 							r.setStart(fn, 0);
       
  5312 
       
  5313 						if (ln.nodeName == 'BR')
       
  5314 							r.setEndBefore(ln);
       
  5315 						else
       
  5316 							r.setEnd(ln, ln.nodeValue.length);
  3327 					} else
  5317 					} else
  3328 						r.selectNode(n);
  5318 						r.selectNode(n);
  3329 				} else
  5319 				} else
  3330 					r.selectNode(n);
  5320 					r.selectNode(n);
  3331 
  5321 
  3362 			var t = this, w = this.win;
  5352 			var t = this, w = this.win;
  3363 
  5353 
  3364 			return w.getSelection ? w.getSelection() : w.document.selection;
  5354 			return w.getSelection ? w.getSelection() : w.document.selection;
  3365 		},
  5355 		},
  3366 
  5356 
  3367 		getRng : function() {
  5357 		getRng : function(w3c) {
  3368 			var t = this, s = t.getSel(), r;
  5358 			var t = this, s, r;
       
  5359 
       
  5360 			// Found tridentSel object then we need to use that one
       
  5361 			if (w3c && t.tridentSel)
       
  5362 				return t.tridentSel.getRangeAt(0);
  3369 
  5363 
  3370 			try {
  5364 			try {
  3371 				if (s)
  5365 				if (s = t.getSel())
  3372 					r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());
  5366 					r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());
  3373 			} catch (ex) {
  5367 			} catch (ex) {
  3374 				// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
  5368 				// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
  3375 			}
  5369 			}
  3376 
  5370 
  3382 
  5376 
  3383 			return r;
  5377 			return r;
  3384 		},
  5378 		},
  3385 
  5379 
  3386 		setRng : function(r) {
  5380 		setRng : function(r) {
  3387 			var s;
  5381 			var s, t = this;
  3388 
  5382 
  3389 			if (!isIE) {
  5383 			if (!t.tridentSel) {
  3390 				s = this.getSel();
  5384 				s = t.getSel();
  3391 
  5385 
  3392 				if (s) {
  5386 				if (s) {
  3393 					s.removeAllRanges();
  5387 					s.removeAllRanges();
  3394 					s.addRange(r);
  5388 					s.addRange(r);
  3395 				}
  5389 				}
  3396 			} else {
  5390 			} else {
       
  5391 				// Is W3C Range
       
  5392 				if (r.cloneRange) {
       
  5393 					t.tridentSel.addRange(r);
       
  5394 					return;
       
  5395 				}
       
  5396 
       
  5397 				// Is IE specific range
  3397 				try {
  5398 				try {
  3398 					r.select();
  5399 					r.select();
  3399 				} catch (ex) {
  5400 				} catch (ex) {
  3400 					// Needed for some odd IE bug #1843306
  5401 					// Needed for some odd IE bug #1843306
  3401 				}
  5402 				}
  3432 								e = r.startContainer.childNodes[r.startOffset];
  5433 								e = r.startContainer.childNodes[r.startOffset];
  3433 						}
  5434 						}
  3434 					}
  5435 					}
  3435 				}
  5436 				}
  3436 
  5437 
  3437 				return t.dom.getParent(e, function(n) {
  5438 				return t.dom.getParent(e, '*');
  3438 					return n.nodeType == 1;
       
  3439 				});
       
  3440 			}
  5439 			}
  3441 
  5440 
  3442 			return r.item ? r.item(0) : r.parentElement();
  5441 			return r.item ? r.item(0) : r.parentElement();
       
  5442 		},
       
  5443 
       
  5444 		getSelectedBlocks : function(st, en) {
       
  5445 			var t = this, dom = t.dom, sb, eb, n, bl = [];
       
  5446 
       
  5447 			sb = dom.getParent(st || t.getStart(), dom.isBlock);
       
  5448 			eb = dom.getParent(en || t.getEnd(), dom.isBlock);
       
  5449 
       
  5450 			if (sb)
       
  5451 				bl.push(sb);
       
  5452 
       
  5453 			if (sb && eb && sb != eb) {
       
  5454 				n = sb;
       
  5455 
       
  5456 				while ((n = n.nextSibling) && n != eb) {
       
  5457 					if (dom.isBlock(n))
       
  5458 						bl.push(n);
       
  5459 				}
       
  5460 			}
       
  5461 
       
  5462 			if (eb && sb != eb)
       
  5463 				bl.push(eb);
       
  5464 
       
  5465 			return bl;
  3443 		},
  5466 		},
  3444 
  5467 
  3445 		destroy : function(s) {
  5468 		destroy : function(s) {
  3446 			var t = this;
  5469 			var t = this;
  3447 
  5470 
  3448 			t.win = null;
  5471 			t.win = null;
       
  5472 
       
  5473 			if (t.tridentSel)
       
  5474 				t.tridentSel.destroy();
  3449 
  5475 
  3450 			// Manual destroy then remove unload handler
  5476 			// Manual destroy then remove unload handler
  3451 			if (!s)
  5477 			if (!s)
  3452 				tinymce.removeUnload(t.destroy);
  5478 				tinymce.removeUnload(t.destroy);
  3453 		}
  5479 		}
  3454 
  5480 	});
  3455 		});
  5481 })(tinymce);
  3456 })();
  5482 (function(tinymce) {
  3457 
       
  3458 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */
       
  3459 
       
  3460 (function() {
       
  3461 	tinymce.create('tinymce.dom.XMLWriter', {
  5483 	tinymce.create('tinymce.dom.XMLWriter', {
  3462 		node : null,
  5484 		node : null,
  3463 
  5485 
  3464 		XMLWriter : function(s) {
  5486 		XMLWriter : function(s) {
  3465 			// Get XML document
  5487 			// Get XML document
  3521 
  5543 
  3522 			this.node.appendChild(this.doc.createTextNode(v));
  5544 			this.node.appendChild(this.doc.createTextNode(v));
  3523 		},
  5545 		},
  3524 
  5546 
  3525 		writeCDATA : function(v) {
  5547 		writeCDATA : function(v) {
  3526 			this.node.appendChild(this.doc.createCDATA(v));
  5548 			this.node.appendChild(this.doc.createCDATASection(v));
  3527 		},
  5549 		},
  3528 
  5550 
  3529 		writeComment : function(v) {
  5551 		writeComment : function(v) {
  3530 			// Fix for bug #2035694
  5552 			// Fix for bug #2035694
  3531 			if (tinymce.isIE)
  5553 			if (tinymce.isIE)
  3544 			if (this.valid)
  5566 			if (this.valid)
  3545 				h = h.replace(/\%MCGT%/g, '&gt;');
  5567 				h = h.replace(/\%MCGT%/g, '&gt;');
  3546 
  5568 
  3547 			return h;
  5569 			return h;
  3548 		}
  5570 		}
  3549 
  5571 	});
  3550 		});
  5572 })(tinymce);
  3551 })();
  5573 (function(tinymce) {
  3552 
       
  3553 /* file:jscripts/tiny_mce/classes/dom/StringWriter.js */
       
  3554 
       
  3555 (function() {
       
  3556 	tinymce.create('tinymce.dom.StringWriter', {
  5574 	tinymce.create('tinymce.dom.StringWriter', {
  3557 		str : null,
  5575 		str : null,
  3558 		tags : null,
  5576 		tags : null,
  3559 		count : 0,
  5577 		count : 0,
  3560 		settings : null,
  5578 		settings : null,
  3561 		indent : null,
  5579 		indent : null,
  3562 
  5580 
  3563 		StringWriter : function(s) {
  5581 		StringWriter : function(s) {
  3564 			this.settings = tinymce.extend({
  5582 			this.settings = tinymce.extend({
  3565 				indent_char : ' ',
  5583 				indent_char : ' ',
  3566 				indentation : 1
  5584 				indentation : 0
  3567 			}, s);
  5585 			}, s);
  3568 
  5586 
  3569 			this.reset();
  5587 			this.reset();
  3570 		},
  5588 		},
  3571 
  5589 
  3674 
  5692 
  3675 			this.writeRaw('>');
  5693 			this.writeRaw('>');
  3676 
  5694 
  3677 			return true;
  5695 			return true;
  3678 		}
  5696 		}
  3679 
  5697 	});
  3680 		});
  5698 })(tinymce);
  3681 })();
  5699 (function(tinymce) {
  3682 
       
  3683 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */
       
  3684 
       
  3685 (function() {
       
  3686 	// Shorten names
  5700 	// Shorten names
  3687 	var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;
  5701 	var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;
  3688 
       
  3689 	// Returns only attribites that have values not all attributes in IE
       
  3690 	function getIEAtts(n) {
       
  3691 		var o = [];
       
  3692 
       
  3693 		// Object will throw exception in IE
       
  3694 		if (n.nodeName == 'OBJECT')
       
  3695 			return n.attributes;
       
  3696 
       
  3697 		n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {
       
  3698 			o.push({specified : 1, nodeName : b});
       
  3699 		});
       
  3700 
       
  3701 		return o;
       
  3702 	};
       
  3703 
  5702 
  3704 	function wildcardToRE(s) {
  5703 	function wildcardToRE(s) {
  3705 		return s.replace(/([?+*])/g, '.$1');
  5704 		return s.replace(/([?+*])/g, '.$1');
  3706 	};
  5705 	};
  3707 
  5706 
  3711 
  5710 
  3712 			t.key = 0;
  5711 			t.key = 0;
  3713 			t.onPreProcess = new Dispatcher(t);
  5712 			t.onPreProcess = new Dispatcher(t);
  3714 			t.onPostProcess = new Dispatcher(t);
  5713 			t.onPostProcess = new Dispatcher(t);
  3715 
  5714 
  3716 			if (tinymce.relaxedDomain && tinymce.isGecko) {
  5715 			try {
  3717 				// Gecko has a bug where we can't create a new XML document if domain relaxing is used
  5716 				t.writer = new tinymce.dom.XMLWriter();
       
  5717 			} catch (ex) {
       
  5718 				// IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter
  3718 				t.writer = new tinymce.dom.StringWriter();
  5719 				t.writer = new tinymce.dom.StringWriter();
  3719 			} else {
       
  3720 				try {
       
  3721 					t.writer = new tinymce.dom.XMLWriter();
       
  3722 				} catch (ex) {
       
  3723 					// IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter
       
  3724 					t.writer = new tinymce.dom.StringWriter();
       
  3725 				}
       
  3726 			}
  5720 			}
  3727 
  5721 
  3728 			// Default settings
  5722 			// Default settings
  3729 			t.settings = s = extend({
  5723 			t.settings = s = extend({
  3730 				dom : tinymce.DOM,
  5724 				dom : tinymce.DOM,
  3731 				valid_nodes : 0,
  5725 				valid_nodes : 0,
  3732 				node_filter : 0,
  5726 				node_filter : 0,
  3733 				attr_filter : 0,
  5727 				attr_filter : 0,
  3734 				invalid_attrs : /^(mce_|_moz_)/,
  5728 				invalid_attrs : /^(mce_|_moz_|sizset|sizcache)/,
  3735 				closed : /(br|hr|input|meta|img|link|param)/,
  5729 				closed : /^(br|hr|input|meta|img|link|param|area)$/,
  3736 				entity_encoding : 'named',
  5730 				entity_encoding : 'named',
  3737 				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',
  5731 				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',
  3738 				bool_attrs : /(checked|disabled|readonly|selected|nowrap)/,
       
  3739 				valid_elements : '*[*]',
  5732 				valid_elements : '*[*]',
  3740 				extended_valid_elements : 0,
  5733 				extended_valid_elements : 0,
  3741 				valid_child_elements : 0,
  5734 				valid_child_elements : 0,
  3742 				invalid_elements : 0,
  5735 				invalid_elements : 0,
  3743 				fix_table_elements : 0,
  5736 				fix_table_elements : 1,
  3744 				fix_list_elements : true,
  5737 				fix_list_elements : true,
  3745 				fix_content_duplication : true,
  5738 				fix_content_duplication : true,
  3746 				convert_fonts_to_spans : false,
  5739 				convert_fonts_to_spans : false,
  3747 				font_size_classes : 0,
  5740 				font_size_classes : 0,
  3748 				font_size_style_values : 0,
  5741 				font_size_style_values : 0,
  3757 
  5750 
  3758 			t.dom = s.dom;
  5751 			t.dom = s.dom;
  3759 
  5752 
  3760 			if (s.remove_redundant_brs) {
  5753 			if (s.remove_redundant_brs) {
  3761 				t.onPostProcess.add(function(se, o) {
  5754 				t.onPostProcess.add(function(se, o) {
  3762 					// Remove BR elements at end of list elements since they get rendered in IE
  5755 					// Remove single BR at end of block elements since they get rendered
  3763 					o.content = o.content.replace(/<br \/>(\s*<\/li>)/g, '$1');
  5756 					o.content = o.content.replace(/(<br \/>\s*)+<\/(p|h[1-6]|div|li)>/gi, function(a, b, c) {
       
  5757 						// Check if it's a single element
       
  5758 						if (/^<br \/>\s*<\//.test(a))
       
  5759 							return '</' + c + '>';
       
  5760 
       
  5761 						return a;
       
  5762 					});
  3764 				});
  5763 				});
  3765 			}
  5764 			}
  3766 
  5765 
  3767 			// Remove XHTML element endings i.e. produce crap :) XHTML is better
  5766 			// Remove XHTML element endings i.e. produce crap :) XHTML is better
  3768 			if (s.element_format == 'html') {
  5767 			if (s.element_format == 'html') {
  3811 				});
  5810 				});
  3812 			}
  5811 			}
  3813 
  5812 
  3814 			if (s.fix_table_elements) {
  5813 			if (s.fix_table_elements) {
  3815 				t.onPreProcess.add(function(se, o) {
  5814 				t.onPreProcess.add(function(se, o) {
  3816 					each(t.dom.select('table', o.node), function(e) {
  5815 					// Since Opera will crash if you attach the node to a dynamic document we need to brrowser sniff a specific build
  3817 						var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), pa2, n, tm, pl = [], i, ns;
  5816 					// so Opera users with an older version will have to live with less compaible output not much we can do here
  3818 
  5817 					if (!tinymce.isOpera || opera.buildNumber() >= 1767) {
  3819 						if (pa) {
  5818 						each(t.dom.select('p table', o.node).reverse(), function(n) {
  3820 							pa2 = pa.cloneNode(false);
  5819 							var parent = t.dom.getParent(n.parentNode, 'table,p');
  3821 
  5820 
  3822 							pl.push(e);
  5821 							if (parent.nodeName != 'TABLE') {
  3823 							for (n = e; n = n.parentNode;) {
  5822 								try {
  3824 								pl.push(n);
  5823 									t.dom.split(parent, n);
  3825 
  5824 								} catch (ex) {
  3826 								if (n == pa)
  5825 									// IE can sometimes fire an unknown runtime error so we just ignore it
  3827 									break;
       
  3828 							}
       
  3829 
       
  3830 							tm = pa2;
       
  3831 							for (i = pl.length - 1; i >= 0; i--) {
       
  3832 								if (i == pl.length - 1) {
       
  3833 									while (ns = pl[i - 1].nextSibling)
       
  3834 										tm.appendChild(ns.parentNode.removeChild(ns));
       
  3835 								} else {
       
  3836 									n = pl[i].cloneNode(false);
       
  3837 
       
  3838 									if (i != 0) {
       
  3839 										while (ns = pl[i - 1].nextSibling)
       
  3840 											n.appendChild(ns.parentNode.removeChild(ns));
       
  3841 									}
       
  3842 
       
  3843 									tm = tm.appendChild(n);
       
  3844 								}
  5826 								}
  3845 							}
  5827 							}
  3846 
  5828 						});
  3847 							e = t.dom.insertAfter(e.parentNode.removeChild(e), pa);
  5829 					}
  3848 							t.dom.insertAfter(e, pa);
       
  3849 							t.dom.insertAfter(pa2, e);
       
  3850 						}
       
  3851 					});
       
  3852 				});
  5830 				});
  3853 			}
  5831 			}
  3854 		},
  5832 		},
  3855 
  5833 
  3856 		setEntities : function(s) {
  5834 		setEntities : function(s) {
  4162 
  6140 
  4163 			return null;
  6141 			return null;
  4164 		},
  6142 		},
  4165 
  6143 
  4166 		serialize : function(n, o) {
  6144 		serialize : function(n, o) {
  4167 			var h, t = this;
  6145 			var h, t = this, doc, oldDoc, impl, selected;
  4168 
  6146 
  4169 			t._setup();
  6147 			t._setup();
  4170 			o = o || {};
  6148 			o = o || {};
  4171 			o.format = o.format || 'html';
  6149 			o.format = o.format || 'html';
  4172 			t.processObj = o;
  6150 			t.processObj = o;
       
  6151 
       
  6152 			// IE looses the selected attribute on option elements so we need to store it
       
  6153 			// See: http://support.microsoft.com/kb/829907
       
  6154 			if (isIE) {
       
  6155 				selected = [];
       
  6156 				each(n.getElementsByTagName('option'), function(n) {
       
  6157 					var v = t.dom.getAttrib(n, 'selected');
       
  6158 
       
  6159 					selected.push(v ? v : null);
       
  6160 				});
       
  6161 			}
       
  6162 
  4173 			n = n.cloneNode(true);
  6163 			n = n.cloneNode(true);
       
  6164 
       
  6165 			// IE looses the selected attribute on option elements so we need to restore it
       
  6166 			if (isIE) {
       
  6167 				each(n.getElementsByTagName('option'), function(n, i) {
       
  6168 					t.dom.setAttrib(n, 'selected', selected[i]);
       
  6169 				});
       
  6170 			}
       
  6171 
       
  6172 			// Nodes needs to be attached to something in WebKit/Opera
       
  6173 			// Older builds of Opera crashes if you attach the node to an document created dynamically
       
  6174 			// and since we can't feature detect a crash we need to sniff the acutal build number
       
  6175 			// This fix will make DOM ranges and make Sizzle happy!
       
  6176 			impl = n.ownerDocument.implementation;
       
  6177 			if (impl.createHTMLDocument && (tinymce.isOpera && opera.buildNumber() >= 1767)) {
       
  6178 				// Create an empty HTML document
       
  6179 				doc = impl.createHTMLDocument("");
       
  6180 
       
  6181 				// Add the element or it's children if it's a body element to the new document
       
  6182 				each(n.nodeName == 'BODY' ? n.childNodes : [n], function(node) {
       
  6183 					doc.body.appendChild(doc.importNode(node, true));
       
  6184 				});
       
  6185 
       
  6186 				// Grab first child or body element for serialization
       
  6187 				if (n.nodeName != 'BODY')
       
  6188 					n = doc.body.firstChild;
       
  6189 				else
       
  6190 					n = doc.body;
       
  6191 
       
  6192 				// set the new document in DOMUtils so createElement etc works
       
  6193 				oldDoc = t.dom.doc;
       
  6194 				t.dom.doc = doc;
       
  6195 			}
       
  6196 
  4174 			t.key = '' + (parseInt(t.key) + 1);
  6197 			t.key = '' + (parseInt(t.key) + 1);
  4175 
  6198 
  4176 			// Pre process
  6199 			// Pre process
  4177 			if (!o.no_events) {
  6200 			if (!o.no_events) {
  4178 				o.node = n;
  6201 				o.node = n;
  4183 			t.writer.reset();
  6206 			t.writer.reset();
  4184 			t._serializeNode(n, o.getInner);
  6207 			t._serializeNode(n, o.getInner);
  4185 
  6208 
  4186 			// Post process
  6209 			// Post process
  4187 			o.content = t.writer.getContent();
  6210 			o.content = t.writer.getContent();
       
  6211 
       
  6212 			// Restore the old document if it was changed
       
  6213 			if (oldDoc)
       
  6214 				t.dom.doc = oldDoc;
  4188 
  6215 
  4189 			if (!o.no_events)
  6216 			if (!o.no_events)
  4190 				t.onPostProcess.dispatch(t, o);
  6217 				t.onPostProcess.dispatch(t, o);
  4191 
  6218 
  4192 			t._postProcess(o);
  6219 			t._postProcess(o);
  4204 				// Protect some elements
  6231 				// Protect some elements
  4205 				p = t._protect({
  6232 				p = t._protect({
  4206 					content : h,
  6233 					content : h,
  4207 					patterns : [
  6234 					patterns : [
  4208 						{pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},
  6235 						{pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},
       
  6236 						{pattern : /(<noscript[^>]*>)(.*?)(<\/noscript>)/g},
  4209 						{pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},
  6237 						{pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},
  4210 						{pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},
  6238 						{pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},
  4211 						{pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}
  6239 						{pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}
  4212 					]
  6240 					]
  4213 				});
  6241 				});
  4256 				h = h.replace(/<!--\[CDATA\[([\s\S]+)\]\]-->/g, '<![CDATA[$1]]>');
  6284 				h = h.replace(/<!--\[CDATA\[([\s\S]+)\]\]-->/g, '<![CDATA[$1]]>');
  4257 
  6285 
  4258 				// Restore the \u00a0 character if raw mode is enabled
  6286 				// Restore the \u00a0 character if raw mode is enabled
  4259 				if (s.entity_encoding == 'raw')
  6287 				if (s.entity_encoding == 'raw')
  4260 					h = h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g, '<p$1>\u00a0</p>');
  6288 					h = h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g, '<p$1>\u00a0</p>');
       
  6289 
       
  6290 				// Restore noscript elements
       
  6291 				h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {
       
  6292 					return '<noscript' + attribs + '>' + t.dom.decode(text.replace(/<!--|-->/g, '')) + '</noscript>';
       
  6293 				});
  4261 			}
  6294 			}
  4262 
  6295 
  4263 			o.content = h;
  6296 			o.content = h;
  4264 		},
  6297 		},
  4265 
  6298 
  4266 		_serializeNode : function(n, inn) {
  6299 		_serializeNode : function(n, inn) {
  4267 			var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;
  6300 			var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv, closed;
  4268 
  6301 
  4269 			if (!s.node_filter || s.node_filter(n)) {
  6302 			if (!s.node_filter || s.node_filter(n)) {
  4270 				switch (n.nodeType) {
  6303 				switch (n.nodeType) {
  4271 					case 1: // Element
  6304 					case 1: // Element
  4272 						if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))
  6305 						if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))
  4285 						// Remove mce prefix on IE needed for the abbr element
  6318 						// Remove mce prefix on IE needed for the abbr element
  4286 						if (nn.indexOf('mce:') === 0)
  6319 						if (nn.indexOf('mce:') === 0)
  4287 							nn = nn.substring(4);
  6320 							nn = nn.substring(4);
  4288 
  6321 
  4289 						// Check if valid
  6322 						// Check if valid
  4290 						if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
  6323 						if (!t.validElementsRE || !t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
  4291 							iv = true;
  6324 							iv = true;
  4292 							break;
  6325 							break;
  4293 						}
  6326 						}
  4294 
  6327 
  4295 						if (isIE) {
  6328 						if (isIE) {
  4322 							t.elementName = nn;
  6355 							t.elementName = nn;
  4323 						}
  6356 						}
  4324 
  6357 
  4325 						ru = t.findRule(nn);
  6358 						ru = t.findRule(nn);
  4326 						nn = ru.name || nn;
  6359 						nn = ru.name || nn;
       
  6360 						closed = s.closed.test(nn);
  4327 
  6361 
  4328 						// Skip empty nodes or empty node name in IE
  6362 						// Skip empty nodes or empty node name in IE
  4329 						if ((!hc && ru.noEmpty) || (isIE && !nn)) {
  6363 						if ((!hc && ru.noEmpty) || (isIE && !nn)) {
  4330 							iv = true;
  6364 							iv = true;
  4331 							break;
  6365 							break;
  4360 							}
  6394 							}
  4361 						}
  6395 						}
  4362 
  6396 
  4363 						// Add wild attributes
  6397 						// Add wild attributes
  4364 						if (ru.validAttribsRE) {
  6398 						if (ru.validAttribsRE) {
  4365 							at = isIE ? getIEAtts(n) : n.attributes;
  6399 							at = t.dom.getAttribs(n);
  4366 							for (i=at.length-1; i>-1; i--) {
  6400 							for (i=at.length-1; i>-1; i--) {
  4367 								no = at[i];
  6401 								no = at[i];
  4368 
  6402 
  4369 								if (no.specified) {
  6403 								if (no.specified) {
  4370 									a = no.nodeName.toLowerCase();
  6404 									a = no.nodeName.toLowerCase();
  4377 
  6411 
  4378 									if (v !== null)
  6412 									if (v !== null)
  4379 										w.writeAttribute(a, v);
  6413 										w.writeAttribute(a, v);
  4380 								}
  6414 								}
  4381 							}
  6415 							}
       
  6416 						}
       
  6417 
       
  6418 						// Write text from script
       
  6419 						if (nn === 'script' && tinymce.trim(n.innerHTML)) {
       
  6420 							w.writeText('// '); // Padd it with a comment so it will parse on older browsers
       
  6421 							w.writeCDATA(n.innerHTML.replace(/<!--|-->|<\[CDATA\[|\]\]>/g, '')); // Remove comments and cdata stuctures
       
  6422 							hc = false;
       
  6423 							break;
  4382 						}
  6424 						}
  4383 
  6425 
  4384 						// Padd empty nodes with a &nbsp;
  6426 						// Padd empty nodes with a &nbsp;
  4385 						if (ru.padd) {
  6427 						if (ru.padd) {
  4386 							// If it has only one bogus child, padd it anyway workaround for <td><br /></td> bug
  6428 							// If it has only one bogus child, padd it anyway workaround for <td><br /></td> bug
  4409 						return w.writeComment(n.nodeValue);
  6451 						return w.writeComment(n.nodeValue);
  4410 				}
  6452 				}
  4411 			} else if (n.nodeType == 1)
  6453 			} else if (n.nodeType == 1)
  4412 				hc = n.hasChildNodes();
  6454 				hc = n.hasChildNodes();
  4413 
  6455 
  4414 			if (hc) {
  6456 			if (hc && !closed) {
  4415 				cn = n.firstChild;
  6457 				cn = n.firstChild;
  4416 
  6458 
  4417 				while (cn) {
  6459 				while (cn) {
  4418 					t._serializeNode(cn);
  6460 					t._serializeNode(cn);
  4419 					t.elementName = nn;
  6461 					t.elementName = nn;
  4421 				}
  6463 				}
  4422 			}
  6464 			}
  4423 
  6465 
  4424 			// Write element end
  6466 			// Write element end
  4425 			if (!iv) {
  6467 			if (!iv) {
  4426 				if (hc || !s.closed.test(nn))
  6468 				if (!closed)
  4427 					w.writeFullEndElement();
  6469 					w.writeFullEndElement();
  4428 				else
  6470 				else
  4429 					w.writeEndElement();
  6471 					w.writeEndElement();
  4430 			}
  6472 			}
  4431 		},
  6473 		},
  4542 				return v;
  6584 				return v;
  4543 			}
  6585 			}
  4544 
  6586 
  4545 			v = this.dom.getAttrib(n, na);
  6587 			v = this.dom.getAttrib(n, na);
  4546 
  6588 
  4547 			// Bool attr
       
  4548 			if (this.settings.bool_attrs.test(na) && v) {
       
  4549 				v = ('' + v).toLowerCase();
       
  4550 
       
  4551 				if (v === 'false' || v === '0')
       
  4552 					return null;
       
  4553 
       
  4554 				v = na;
       
  4555 			}
       
  4556 
       
  4557 			switch (na) {
  6589 			switch (na) {
  4558 				case 'rowspan':
  6590 				case 'rowspan':
  4559 				case 'colspan':
  6591 				case 'colspan':
  4560 					// Whats the point? Remove usless attribute value
  6592 					// Whats the point? Remove usless attribute value
  4561 					if (v == '1')
  6593 					if (v == '1')
  4594 				return null;
  6626 				return null;
  4595 
  6627 
  4596 
  6628 
  4597 			return v;
  6629 			return v;
  4598 		}
  6630 		}
  4599 
  6631 	});
  4600 		});
  6632 })(tinymce);
  4601 })();
  6633 (function(tinymce) {
  4602 
       
  4603 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */
       
  4604 
       
  4605 (function() {
       
  4606 	var each = tinymce.each, Event = tinymce.dom.Event;
  6634 	var each = tinymce.each, Event = tinymce.dom.Event;
  4607 
  6635 
  4608 	tinymce.create('tinymce.dom.ScriptLoader', {
  6636 	tinymce.create('tinymce.dom.ScriptLoader', {
  4609 		ScriptLoader : function(s) {
  6637 		ScriptLoader : function(s) {
  4610 			this.settings = s || {};
  6638 			this.settings = s || {};
  4870 					// Check for head or body
  6898 					// Check for head or body
  4871 					(document.getElementsByTagName('head')[0] || document.body).appendChild(e);
  6899 					(document.getElementsByTagName('head')[0] || document.body).appendChild(e);
  4872 				}
  6900 				}
  4873 			}
  6901 			}
  4874 		}
  6902 		}
  4875 
  6903 	});
  4876 		});
       
  4877 
  6904 
  4878 	// Global script loader
  6905 	// Global script loader
  4879 	tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
  6906 	tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
  4880 })();
  6907 })(tinymce);
  4881 
  6908 (function(tinymce) {
  4882 /* file:jscripts/tiny_mce/classes/ui/Control.js */
       
  4883 
       
  4884 (function() {
       
  4885 	// Shorten class names
  6909 	// Shorten class names
  4886 	var DOM = tinymce.DOM, is = tinymce.is;
  6910 	var DOM = tinymce.DOM, is = tinymce.is;
  4887 
  6911 
  4888 	tinymce.create('tinymce.ui.Control', {
  6912 	tinymce.create('tinymce.ui.Control', {
  4889 		Control : function(id, s) {
  6913 		Control : function(id, s) {
  4978 		},
  7002 		},
  4979 
  7003 
  4980 		destroy : function() {
  7004 		destroy : function() {
  4981 			tinymce.dom.Event.clear(this.id);
  7005 			tinymce.dom.Event.clear(this.id);
  4982 		}
  7006 		}
  4983 
  7007 	});
  4984 		});
  7008 })(tinymce);tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
  4985 })();
       
  4986 /* file:jscripts/tiny_mce/classes/ui/Container.js */
       
  4987 
       
  4988 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
       
  4989 	Container : function(id, s) {
  7009 	Container : function(id, s) {
  4990 		this.parent(id, s);
  7010 		this.parent(id, s);
       
  7011 
  4991 		this.controls = [];
  7012 		this.controls = [];
       
  7013 
  4992 		this.lookup = {};
  7014 		this.lookup = {};
  4993 	},
  7015 	},
  4994 
  7016 
  4995 	add : function(c) {
  7017 	add : function(c) {
  4996 		this.lookup[c.id] = c;
  7018 		this.lookup[c.id] = c;
  5000 	},
  7022 	},
  5001 
  7023 
  5002 	get : function(n) {
  7024 	get : function(n) {
  5003 		return this.lookup[n];
  7025 		return this.lookup[n];
  5004 	}
  7026 	}
  5005 
  7027 });
  5006 	});
       
  5007 
       
  5008 
       
  5009 /* file:jscripts/tiny_mce/classes/ui/Separator.js */
       
  5010 
  7028 
  5011 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
  7029 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
  5012 	Separator : function(id, s) {
  7030 	Separator : function(id, s) {
  5013 		this.parent(id, s);
  7031 		this.parent(id, s);
  5014 		this.classPrefix = 'mceSeparator';
  7032 		this.classPrefix = 'mceSeparator';
  5015 	},
  7033 	},
  5016 
  7034 
  5017 	renderHTML : function() {
  7035 	renderHTML : function() {
  5018 		return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});
  7036 		return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});
  5019 	}
  7037 	}
  5020 
  7038 });
  5021 	});
  7039 (function(tinymce) {
  5022 
       
  5023 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */
       
  5024 
       
  5025 (function() {
       
  5026 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
  7040 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
  5027 
  7041 
  5028 	tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {
  7042 	tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {
  5029 		MenuItem : function(id, s) {
  7043 		MenuItem : function(id, s) {
  5030 			this.parent(id, s);
  7044 			this.parent(id, s);
  5047 
  7061 
  5048 			// Set pending state
  7062 			// Set pending state
  5049 			if (is(t.selected))
  7063 			if (is(t.selected))
  5050 				t.setSelected(t.selected);
  7064 				t.setSelected(t.selected);
  5051 		}
  7065 		}
  5052 
  7066 	});
  5053 		});
  7067 })(tinymce);
  5054 })();
  7068 (function(tinymce) {
  5055 
       
  5056 /* file:jscripts/tiny_mce/classes/ui/Menu.js */
       
  5057 
       
  5058 (function() {
       
  5059 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
  7069 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
  5060 
  7070 
  5061 	tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {
  7071 	tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {
  5062 		Menu : function(id, s) {
  7072 		Menu : function(id, s) {
  5063 			var t = this;
  7073 			var t = this;
  5149 
  7159 
  5150 			m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem);
  7160 			m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem);
  5151 
  7161 
  5152 			return m;
  7162 			return m;
  5153 		}
  7163 		}
  5154 
  7164 	});
  5155 		});
  7165 })(tinymce);(function(tinymce) {
  5156 })();
       
  5157 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */
       
  5158 
       
  5159 (function() {
       
  5160 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;
  7166 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;
  5161 
  7167 
  5162 	tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {
  7168 	tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {
  5163 		DropMenu : function(id, s) {
  7169 		DropMenu : function(id, s) {
  5164 			s = s || {};
  7170 			s = s || {};
  5267 			t.mouseClickFunc = Event.add(co, 'click', function(e) {
  7273 			t.mouseClickFunc = Event.add(co, 'click', function(e) {
  5268 				var m;
  7274 				var m;
  5269 
  7275 
  5270 				e = e.target;
  7276 				e = e.target;
  5271 
  7277 
  5272 				if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) {
  7278 				if (e && (e = DOM.getParent(e, 'tr')) && !DOM.hasClass(e, cp + 'ItemSub')) {
  5273 					m = t.items[e.id];
  7279 					m = t.items[e.id];
  5274 
  7280 
  5275 					if (m.isDisabled())
  7281 					if (m.isDisabled())
  5276 						return;
  7282 						return;
  5277 
  7283 
  5294 			if (t.hasMenus()) {
  7300 			if (t.hasMenus()) {
  5295 				t.mouseOverFunc = Event.add(co, 'mouseover', function(e) {
  7301 				t.mouseOverFunc = Event.add(co, 'mouseover', function(e) {
  5296 					var m, r, mi;
  7302 					var m, r, mi;
  5297 
  7303 
  5298 					e = e.target;
  7304 					e = e.target;
  5299 					if (e && (e = DOM.getParent(e, 'TR'))) {
  7305 					if (e && (e = DOM.getParent(e, 'tr'))) {
  5300 						m = t.items[e.id];
  7306 						m = t.items[e.id];
  5301 
  7307 
  5302 						if (t.lastMenu)
  7308 						if (t.lastMenu)
  5303 							t.lastMenu.collapse(1);
  7309 							t.lastMenu.collapse(1);
  5304 
  7310 
  5480 			if (n = ro.previousSibling)
  7486 			if (n = ro.previousSibling)
  5481 				DOM.removeClass(n, 'mceLast');
  7487 				DOM.removeClass(n, 'mceLast');
  5482 
  7488 
  5483 			DOM.addClass(ro, 'mceLast');
  7489 			DOM.addClass(ro, 'mceLast');
  5484 		}
  7490 		}
  5485 
  7491 	});
  5486 		});
  7492 })(tinymce);(function(tinymce) {
  5487 })();
       
  5488 /* file:jscripts/tiny_mce/classes/ui/Button.js */
       
  5489 
       
  5490 (function() {
       
  5491 	var DOM = tinymce.DOM;
  7493 	var DOM = tinymce.DOM;
  5492 
  7494 
  5493 	tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {
  7495 	tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {
  5494 		Button : function(id, s) {
  7496 		Button : function(id, s) {
  5495 			this.parent(id, s);
  7497 			this.parent(id, s);
  5516 			tinymce.dom.Event.add(t.id, 'click', function(e) {
  7518 			tinymce.dom.Event.add(t.id, 'click', function(e) {
  5517 				if (!t.isDisabled())
  7519 				if (!t.isDisabled())
  5518 					return s.onclick.call(s.scope, e);
  7520 					return s.onclick.call(s.scope, e);
  5519 			});
  7521 			});
  5520 		}
  7522 		}
  5521 
  7523 	});
  5522 		});
  7524 })(tinymce);
  5523 })();
  7525 (function(tinymce) {
  5524 
       
  5525 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */
       
  5526 
       
  5527 (function() {
       
  5528 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
  7526 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
  5529 
  7527 
  5530 	tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {
  7528 	tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {
  5531 		ListBox : function(id, s) {
  7529 		ListBox : function(id, s) {
  5532 			var t = this;
  7530 			var t = this;
  5533 
  7531 
  5534 			t.parent(id, s);
  7532 			t.parent(id, s);
       
  7533 
  5535 			t.items = [];
  7534 			t.items = [];
       
  7535 
  5536 			t.onChange = new Dispatcher(t);
  7536 			t.onChange = new Dispatcher(t);
       
  7537 
  5537 			t.onPostRender = new Dispatcher(t);
  7538 			t.onPostRender = new Dispatcher(t);
       
  7539 
  5538 			t.onAdd = new Dispatcher(t);
  7540 			t.onAdd = new Dispatcher(t);
       
  7541 
  5539 			t.onRenderMenu = new tinymce.util.Dispatcher(this);
  7542 			t.onRenderMenu = new tinymce.util.Dispatcher(this);
       
  7543 
  5540 			t.classPrefix = 'mceListBox';
  7544 			t.classPrefix = 'mceListBox';
  5541 		},
  7545 		},
  5542 
  7546 
  5543 		select : function(va) {
  7547 		select : function(va) {
  5544 			var t = this, fv, f;
  7548 			var t = this, fv, f;
  5588 					DOM.addClass(e, 'mceTitle');
  7592 					DOM.addClass(e, 'mceTitle');
  5589 					t.selectedValue = t.selectedIndex = null;
  7593 					t.selectedValue = t.selectedIndex = null;
  5590 				}
  7594 				}
  5591 
  7595 
  5592 				e = 0;
  7596 				e = 0;
  5593 			} else
  7597 			}
  5594 				t.selectedValue = t.selectedIndex = null;
       
  5595 		},
  7598 		},
  5596 
  7599 
  5597 		add : function(n, v, o) {
  7600 		add : function(n, v, o) {
  5598 			var t = this;
  7601 			var t = this;
  5599 
  7602 
  5668 
  7671 
  5669 			// Prevent double toogles by canceling the mouse click event to the button
  7672 			// Prevent double toogles by canceling the mouse click event to the button
  5670 			if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))
  7673 			if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))
  5671 				return;
  7674 				return;
  5672 
  7675 
  5673 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
  7676 			if (!e || !DOM.getParent(e.target, '.mceMenu')) {
  5674 				DOM.removeClass(t.id, t.classPrefix + 'Selected');
  7677 				DOM.removeClass(t.id, t.classPrefix + 'Selected');
  5675 				Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
  7678 				Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
  5676 
  7679 
  5677 				if (t.menu)
  7680 				if (t.menu)
  5678 					t.menu.hideMenu();
  7681 					t.menu.hideMenu();
  5771 
  7774 
  5772 		destroy : function() {
  7775 		destroy : function() {
  5773 			this.parent();
  7776 			this.parent();
  5774 
  7777 
  5775 			Event.clear(this.id + '_text');
  7778 			Event.clear(this.id + '_text');
       
  7779 			Event.clear(this.id + '_open');
  5776 		}
  7780 		}
  5777 
  7781 	});
  5778 		});
  7782 })(tinymce);(function(tinymce) {
  5779 })();
       
  5780 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */
       
  5781 
       
  5782 (function() {
       
  5783 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
  7783 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
  5784 
  7784 
  5785 	tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {
  7785 	tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {
  5786 		NativeListBox : function(id, s) {
  7786 		NativeListBox : function(id, s) {
  5787 			this.parent(id, s);
  7787 			this.parent(id, s);
  5904 				}
  7904 				}
  5905 			});
  7905 			});
  5906 
  7906 
  5907 			t.onPostRender.dispatch(t, DOM.get(t.id));
  7907 			t.onPostRender.dispatch(t, DOM.get(t.id));
  5908 		}
  7908 		}
  5909 
  7909 	});
  5910 		});
  7910 })(tinymce);(function(tinymce) {
  5911 })();
       
  5912 /* file:jscripts/tiny_mce/classes/ui/MenuButton.js */
       
  5913 
       
  5914 (function() {
       
  5915 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
  7911 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
  5916 
  7912 
  5917 	tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {
  7913 	tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {
  5918 		MenuButton : function(id, s) {
  7914 		MenuButton : function(id, s) {
  5919 			this.parent(id, s);
  7915 			this.parent(id, s);
       
  7916 
  5920 			this.onRenderMenu = new tinymce.util.Dispatcher(this);
  7917 			this.onRenderMenu = new tinymce.util.Dispatcher(this);
       
  7918 
  5921 			s.menu_container = s.menu_container || DOM.doc.body;
  7919 			s.menu_container = s.menu_container || DOM.doc.body;
  5922 		},
  7920 		},
  5923 
  7921 
  5924 		showMenu : function() {
  7922 		showMenu : function() {
  5925 			var t = this, p1, p2, e = DOM.get(t.id), m;
  7923 			var t = this, p1, p2, e = DOM.get(t.id), m;
  5972 
  7970 
  5973 			// Prevent double toogles by canceling the mouse click event to the button
  7971 			// Prevent double toogles by canceling the mouse click event to the button
  5974 			if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id || e.id === t.id + '_open';}))
  7972 			if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id || e.id === t.id + '_open';}))
  5975 				return;
  7973 				return;
  5976 
  7974 
  5977 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
  7975 			if (!e || !DOM.getParent(e.target, '.mceMenu')) {
  5978 				t.setState('Selected', 0);
  7976 				t.setState('Selected', 0);
  5979 				Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
  7977 				Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
  5980 				if (t.menu)
  7978 				if (t.menu)
  5981 					t.menu.hideMenu();
  7979 					t.menu.hideMenu();
  5982 			}
  7980 			}
  5994 
  7992 
  5995 					t.showMenu();
  7993 					t.showMenu();
  5996 				}
  7994 				}
  5997 			});
  7995 			});
  5998 		}
  7996 		}
  5999 
  7997 	});
  6000 		});
  7998 })(tinymce);
  6001 })();
  7999 (function(tinymce) {
  6002 
       
  6003 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */
       
  6004 
       
  6005 (function() {
       
  6006 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
  8000 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
  6007 
  8001 
  6008 	tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {
  8002 	tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {
  6009 		SplitButton : function(id, s) {
  8003 		SplitButton : function(id, s) {
  6010 			this.parent(id, s);
  8004 			this.parent(id, s);
  6063 			this.parent();
  8057 			this.parent();
  6064 
  8058 
  6065 			Event.clear(this.id + '_action');
  8059 			Event.clear(this.id + '_action');
  6066 			Event.clear(this.id + '_open');
  8060 			Event.clear(this.id + '_open');
  6067 		}
  8061 		}
  6068 
  8062 	});
  6069 		});
  8063 })(tinymce);
  6070 })();
  8064 (function(tinymce) {
  6071 
       
  6072 /* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */
       
  6073 
       
  6074 (function() {
       
  6075 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
  8065 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
  6076 
  8066 
  6077 	tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {
  8067 	tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {
  6078 		ColorSplitButton : function(id, s) {
  8068 		ColorSplitButton : function(id, s) {
  6079 			var t = this;
  8069 			var t = this;
  6085 				grid_width : 8,
  8075 				grid_width : 8,
  6086 				default_color : '#888888'
  8076 				default_color : '#888888'
  6087 			}, t.settings);
  8077 			}, t.settings);
  6088 
  8078 
  6089 			t.onShowMenu = new tinymce.util.Dispatcher(t);
  8079 			t.onShowMenu = new tinymce.util.Dispatcher(t);
       
  8080 
  6090 			t.onHideMenu = new tinymce.util.Dispatcher(t);
  8081 			t.onHideMenu = new tinymce.util.Dispatcher(t);
  6091 
  8082 
  6092 			t.value = s.default_color;
  8083 			t.value = s.default_color;
  6093 		},
  8084 		},
  6094 
  8085 
  6116 				zIndex : 200000
  8107 				zIndex : 200000
  6117 			});
  8108 			});
  6118 			e = 0;
  8109 			e = 0;
  6119 
  8110 
  6120 			Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
  8111 			Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
       
  8112 			t.onShowMenu.dispatch(t);
  6121 
  8113 
  6122 			if (t._focused) {
  8114 			if (t._focused) {
  6123 				t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {
  8115 				t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {
  6124 					if (e.keyCode == 27)
  8116 					if (e.keyCode == 27)
  6125 						t.hideMenu();
  8117 						t.hideMenu();
  6126 				});
  8118 				});
  6127 
  8119 
  6128 				DOM.select('a', t.id + '_menu')[0].focus(); // Select first link
  8120 				DOM.select('a', t.id + '_menu')[0].focus(); // Select first link
  6129 			}
  8121 			}
  6130 
  8122 
  6131 			t.onShowMenu.dispatch(t);
       
  6132 
       
  6133 			t.isMenuVisible = 1;
  8123 			t.isMenuVisible = 1;
  6134 		},
  8124 		},
  6135 
  8125 
  6136 		hideMenu : function(e) {
  8126 		hideMenu : function(e) {
  6137 			var t = this;
  8127 			var t = this;
  6138 
  8128 
  6139 			// Prevent double toogles by canceling the mouse click event to the button
  8129 			// Prevent double toogles by canceling the mouse click event to the button
  6140 			if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))
  8130 			if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))
  6141 				return;
  8131 				return;
  6142 
  8132 
  6143 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {
  8133 			if (!e || !DOM.getParent(e.target, '.mceSplitButtonMenu')) {
  6144 				DOM.removeClass(t.id, 'mceSplitButtonSelected');
  8134 				DOM.removeClass(t.id, 'mceSplitButtonSelected');
  6145 				Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
  8135 				Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
  6146 				Event.remove(t.id + '_menu', 'keydown', t._keyHandler);
  8136 				Event.remove(t.id + '_menu', 'keydown', t._keyHandler);
  6147 				DOM.hide(t.id + '_menu');
  8137 				DOM.hide(t.id + '_menu');
  6148 			}
  8138 			}
  6233 
  8223 
  6234 			Event.clear(this.id + '_menu');
  8224 			Event.clear(this.id + '_menu');
  6235 			Event.clear(this.id + '_more');
  8225 			Event.clear(this.id + '_more');
  6236 			DOM.remove(this.id + '_menu');
  8226 			DOM.remove(this.id + '_menu');
  6237 		}
  8227 		}
  6238 
  8228 	});
  6239 		});
  8229 })(tinymce);
  6240 })();
       
  6241 
       
  6242 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */
       
  6243 
       
  6244 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
  8230 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
  6245 	renderHTML : function() {
  8231 	renderHTML : function() {
  6246 		var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl;
  8232 		var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl;
  6247 
  8233 
  6248 		cl = t.controls;
  8234 		cl = t.controls;
  6300 
  8286 
  6301 		h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));
  8287 		h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));
  6302 
  8288 
  6303 		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>');
  8289 		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>');
  6304 	}
  8290 	}
  6305 
  8291 });
  6306 	});
  8292 (function(tinymce) {
  6307 
       
  6308 /* file:jscripts/tiny_mce/classes/AddOnManager.js */
       
  6309 
       
  6310 (function() {
       
  6311 	var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;
  8293 	var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;
  6312 
  8294 
  6313 	tinymce.create('tinymce.AddOnManager', {
  8295 	tinymce.create('tinymce.AddOnManager', {
  6314 		items : [],
  8296 		items : [],
  6315 		urls : {},
  8297 		urls : {},
  6316 		lookup : {},
  8298 		lookup : {},
       
  8299 
  6317 		onAdd : new Dispatcher(this),
  8300 		onAdd : new Dispatcher(this),
  6318 
  8301 
  6319 		get : function(n) {
  8302 		get : function(n) {
  6320 			return this.lookup[n];
  8303 			return this.lookup[n];
  6321 		},
  8304 		},
  6351 				u = tinymce.baseURL + '/' +  u;
  8334 				u = tinymce.baseURL + '/' +  u;
  6352 
  8335 
  6353 			t.urls[n] = u.substring(0, u.lastIndexOf('/'));
  8336 			t.urls[n] = u.substring(0, u.lastIndexOf('/'));
  6354 			tinymce.ScriptLoader.add(u, cb, s);
  8337 			tinymce.ScriptLoader.add(u, cb, s);
  6355 		}
  8338 		}
  6356 
  8339 	});
  6357 		});
       
  6358 
  8340 
  6359 	// Create plugin and theme managers
  8341 	// Create plugin and theme managers
  6360 	tinymce.PluginManager = new tinymce.AddOnManager();
  8342 	tinymce.PluginManager = new tinymce.AddOnManager();
  6361 	tinymce.ThemeManager = new tinymce.AddOnManager();
  8343 	tinymce.ThemeManager = new tinymce.AddOnManager();
  6362 }());
  8344 }(tinymce));
  6363 /* file:jscripts/tiny_mce/classes/EditorManager.js */
  8345 
  6364 
  8346 (function(tinymce) {
  6365 (function() {
       
  6366 	// Shorten names
  8347 	// Shorten names
  6367 	var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;
  8348 	var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;
  6368 
  8349 
  6369 	tinymce.create('static tinymce.EditorManager', {
  8350 	tinymce.create('static tinymce.EditorManager', {
  6370 		editors : {},
  8351 		editors : {},
       
  8352 
  6371 		i18n : {},
  8353 		i18n : {},
       
  8354 	
  6372 		activeEditor : null,
  8355 		activeEditor : null,
  6373 
  8356 
  6374 		preInit : function() {
  8357 		preInit : function() {
  6375 			var t = this, lo = window.location;
  8358 			var t = this, lo = window.location;
  6376 
  8359 
  6379 			if (!/[\/\\]$/.test(tinymce.documentBaseURL))
  8362 			if (!/[\/\\]$/.test(tinymce.documentBaseURL))
  6380 				tinymce.documentBaseURL += '/';
  8363 				tinymce.documentBaseURL += '/';
  6381 
  8364 
  6382 			tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
  8365 			tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
  6383 			tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
  8366 			tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
  6384 
       
  6385 			// User already specified a document.domain value
       
  6386 			if (document.domain && lo.hostname != document.domain)
       
  6387 				tinymce.relaxedDomain = document.domain;
       
  6388 
       
  6389 			// Setup document domain if tinymce is loaded from other domain
       
  6390 			if (!tinymce.relaxedDomain && tinymce.EditorManager.baseURI.host != lo.hostname && lo.hostname)
       
  6391 				document.domain = tinymce.relaxedDomain = lo.hostname.replace(/.*\.(.+\..+)$/, '$1');
       
  6392 
  8367 
  6393 			// Add before unload listener
  8368 			// Add before unload listener
  6394 			// This was required since IE was leaking memory if you added and removed beforeunload listeners
  8369 			// This was required since IE was leaking memory if you added and removed beforeunload listeners
  6395 			// with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event
  8370 			// with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event
  6396 			t.onBeforeUnload = new tinymce.util.Dispatcher(t);
  8371 			t.onBeforeUnload = new tinymce.util.Dispatcher(t);
  6438 					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
  8413 					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
  6439 
  8414 
  6440 				// Load plugins
  8415 				// Load plugins
  6441 				if (s.plugins) {
  8416 				if (s.plugins) {
  6442 					pl = explode(s.plugins);
  8417 					pl = explode(s.plugins);
  6443 
       
  6444 					// Load compat2x first
       
  6445 					if (tinymce.inArray(pl, 'compat2x') != -1)
       
  6446 						PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
       
  6447 
  8418 
  6448 					// Load rest if plugins
  8419 					// Load rest if plugins
  6449 					each(pl, function(v) {
  8420 					each(pl, function(v) {
  6450 						if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) {
  8421 						if (v && v.charAt(0) != '-' && !PluginManager.urls[v]) {
  6451 							// Skip safari plugin for other browsers
  8422 							// Skip safari plugin for other browsers
  6611 
  8582 
  6612 			delete t.editors[e.id];
  8583 			delete t.editors[e.id];
  6613 
  8584 
  6614 			// Select another editor since the active one was removed
  8585 			// Select another editor since the active one was removed
  6615 			if (t.activeEditor == e) {
  8586 			if (t.activeEditor == e) {
       
  8587 				t._setActive(null);
       
  8588 
  6616 				each(t.editors, function(e) {
  8589 				each(t.editors, function(e) {
  6617 					t._setActive(e);
  8590 					t._setActive(e);
  6618 					return false; // Break
  8591 					return false; // Break
  6619 				});
  8592 				});
  6620 			}
  8593 			}
  6735 		// Private methods
  8708 		// Private methods
  6736 
  8709 
  6737 		_setActive : function(e) {
  8710 		_setActive : function(e) {
  6738 			this.selectedInstance = this.activeEditor = e;
  8711 			this.selectedInstance = this.activeEditor = e;
  6739 		}
  8712 		}
  6740 
  8713 	});
  6741 		});
       
  6742 
  8714 
  6743 	tinymce.EditorManager.preInit();
  8715 	tinymce.EditorManager.preInit();
  6744 })();
  8716 })(tinymce);
  6745 
  8717 
  6746 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call
       
  6747 var tinyMCE = window.tinyMCE = tinymce.EditorManager;
  8718 var tinyMCE = window.tinyMCE = tinymce.EditorManager;
  6748 
  8719 (function(tinymce) {
  6749 /* file:jscripts/tiny_mce/classes/Editor.js */
       
  6750 
       
  6751 (function() {
       
  6752 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;
  8720 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;
  6753 	var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;
  8721 	var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;
  6754 	var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;
  8722 	var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;
  6755 	var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;
  8723 	var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;
  6756 
  8724 
  6757 	tinymce.create('tinymce.Editor', {
  8725 	tinymce.create('tinymce.Editor', {
  6758 		Editor : function(id, s) {
  8726 		Editor : function(id, s) {
  6759 			var t = this;
  8727 			var t = this;
  6760 
  8728 
  6761 			t.id = t.editorId = id;
  8729 			t.id = t.editorId = id;
       
  8730 
  6762 			t.execCommands = {};
  8731 			t.execCommands = {};
  6763 			t.queryStateCommands = {};
  8732 			t.queryStateCommands = {};
  6764 			t.queryValueCommands = {};
  8733 			t.queryValueCommands = {};
       
  8734 
       
  8735 			t.isNotDirty = false;
       
  8736 
  6765 			t.plugins = {};
  8737 			t.plugins = {};
  6766 
  8738 
  6767 			// Add events to the editor
  8739 			// Add events to the editor
  6768 			each([
  8740 			each([
  6769 				'onPreInit',
  8741 				'onPreInit',
       
  8742 
  6770 				'onBeforeRenderUI',
  8743 				'onBeforeRenderUI',
       
  8744 
  6771 				'onPostRender',
  8745 				'onPostRender',
       
  8746 
  6772 				'onInit',
  8747 				'onInit',
       
  8748 
  6773 				'onRemove',
  8749 				'onRemove',
       
  8750 
  6774 				'onActivate',
  8751 				'onActivate',
       
  8752 
  6775 				'onDeactivate',
  8753 				'onDeactivate',
       
  8754 
  6776 				'onClick',
  8755 				'onClick',
       
  8756 
  6777 				'onEvent',
  8757 				'onEvent',
       
  8758 
  6778 				'onMouseUp',
  8759 				'onMouseUp',
       
  8760 
  6779 				'onMouseDown',
  8761 				'onMouseDown',
       
  8762 
  6780 				'onDblClick',
  8763 				'onDblClick',
       
  8764 
  6781 				'onKeyDown',
  8765 				'onKeyDown',
       
  8766 
  6782 				'onKeyUp',
  8767 				'onKeyUp',
       
  8768 
  6783 				'onKeyPress',
  8769 				'onKeyPress',
       
  8770 
  6784 				'onContextMenu',
  8771 				'onContextMenu',
       
  8772 
  6785 				'onSubmit',
  8773 				'onSubmit',
       
  8774 
  6786 				'onReset',
  8775 				'onReset',
       
  8776 
  6787 				'onPaste',
  8777 				'onPaste',
       
  8778 
  6788 				'onPreProcess',
  8779 				'onPreProcess',
       
  8780 
  6789 				'onPostProcess',
  8781 				'onPostProcess',
       
  8782 
  6790 				'onBeforeSetContent',
  8783 				'onBeforeSetContent',
       
  8784 
  6791 				'onBeforeGetContent',
  8785 				'onBeforeGetContent',
       
  8786 
  6792 				'onSetContent',
  8787 				'onSetContent',
       
  8788 
  6793 				'onGetContent',
  8789 				'onGetContent',
       
  8790 
  6794 				'onLoadContent',
  8791 				'onLoadContent',
       
  8792 
  6795 				'onSaveContent',
  8793 				'onSaveContent',
       
  8794 
  6796 				'onNodeChange',
  8795 				'onNodeChange',
       
  8796 
  6797 				'onChange',
  8797 				'onChange',
       
  8798 
  6798 				'onBeforeExecCommand',
  8799 				'onBeforeExecCommand',
       
  8800 
  6799 				'onExecCommand',
  8801 				'onExecCommand',
       
  8802 
  6800 				'onUndo',
  8803 				'onUndo',
       
  8804 
  6801 				'onRedo',
  8805 				'onRedo',
       
  8806 
  6802 				'onVisualAid',
  8807 				'onVisualAid',
       
  8808 
  6803 				'onSetProgressState'
  8809 				'onSetProgressState'
  6804 			], function(e) {
  8810 			], function(e) {
  6805 				t[e] = new Dispatcher(t);
  8811 				t[e] = new Dispatcher(t);
  6806 			});
  8812 			});
  6807 
  8813 
  6808 			// Default editor config
       
  6809 			t.settings = s = extend({
  8814 			t.settings = s = extend({
  6810 				id : id,
  8815 				id : id,
  6811 				language : 'en',
  8816 				language : 'en',
  6812 				docs_language : 'en',
  8817 				docs_language : 'en',
  6813 				theme : 'simple',
  8818 				theme : 'simple',
  6838 				convert_fonts_to_spans : true,
  8843 				convert_fonts_to_spans : true,
  6839 				font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
  8844 				font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
  6840 				apply_source_formatting : 1,
  8845 				apply_source_formatting : 1,
  6841 				directionality : 'ltr',
  8846 				directionality : 'ltr',
  6842 				forced_root_block : 'p',
  8847 				forced_root_block : 'p',
  6843 				valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
  8848 				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,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
  6844 				hidden_input : 1,
  8849 				hidden_input : 1,
  6845 				padd_empty_editor : 1,
  8850 				padd_empty_editor : 1,
  6846 				render_ui : 1,
  8851 				render_ui : 1,
  6847 				init_theme : 1,
  8852 				init_theme : 1,
  6848 				force_p_newlines : 1,
  8853 				force_p_newlines : 1,
  6849 				indentation : '30px',
  8854 				indentation : '30px',
  6850 				keep_styles : 1
  8855 				keep_styles : 1,
       
  8856 				fix_table_elements : 1,
       
  8857 				removeformat_selector : 'span,b,strong,em,i,font,u,strike'
  6851 			}, s);
  8858 			}, s);
  6852 
  8859 
  6853 			// Setup URIs
       
  6854 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
  8860 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
  6855 				base_uri : tinyMCE.baseURI
  8861 				base_uri : tinyMCE.baseURI
  6856 			});
  8862 			});
       
  8863 
  6857 			t.baseURI = EditorManager.baseURI;
  8864 			t.baseURI = EditorManager.baseURI;
  6858 
  8865 
  6859 			// Call setup
  8866 			// Call setup
  6860 			t.execCallback('setup', t);
  8867 			t.execCallback('setup', t);
  6861 		},
  8868 		},
  6888 
  8895 
  6889 			// Add hidden input for non input elements inside form elements
  8896 			// Add hidden input for non input elements inside form elements
  6890 			if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
  8897 			if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
  6891 				DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
  8898 				DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
  6892 
  8899 
  6893 			t.windowManager = new tinymce.WindowManager(t);
  8900 			if (tinymce.WindowManager)
       
  8901 				t.windowManager = new tinymce.WindowManager(t);
  6894 
  8902 
  6895 			if (s.encoding == 'xml') {
  8903 			if (s.encoding == 'xml') {
  6896 				t.onGetContent.add(function(ed, o) {
  8904 				t.onGetContent.add(function(ed, o) {
  6897 					if (o.save)
  8905 					if (o.save)
  6898 						o.content = DOM.encode(o.content);
  8906 						o.content = DOM.encode(o.content);
  6906 						t.isNotDirty = 1;
  8914 						t.isNotDirty = 1;
  6907 					}
  8915 					}
  6908 				});
  8916 				});
  6909 			}
  8917 			}
  6910 
  8918 
  6911 			if (s.add_unload_trigger && !s.ask) {
  8919 			if (s.add_unload_trigger) {
  6912 				t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {
  8920 				t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {
  6913 					if (t.initialized && !t.destroyed && !t.isHidden())
  8921 					if (t.initialized && !t.destroyed && !t.isHidden())
  6914 						t.save({format : 'raw', no_events : true});
  8922 						t.save({format : 'raw', no_events : true});
  6915 				});
  8923 				});
  6916 			}
  8924 			}
  6935 						n.submit = function() {
  8943 						n.submit = function() {
  6936 							// Save all instances
  8944 							// Save all instances
  6937 							EditorManager.triggerSave();
  8945 							EditorManager.triggerSave();
  6938 							t.isNotDirty = 1;
  8946 							t.isNotDirty = 1;
  6939 
  8947 
  6940 							return this._mceOldSubmit(this);
  8948 							return t.formElement._mceOldSubmit(t.formElement);
  6941 						};
  8949 						};
  6942 					}
  8950 					}
  6943 
  8951 
  6944 					n = null;
  8952 					n = null;
  6945 				});
  8953 				});
  6948 			// Load scripts
  8956 			// Load scripts
  6949 			function loadScripts() {
  8957 			function loadScripts() {
  6950 				if (s.language)
  8958 				if (s.language)
  6951 					sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');
  8959 					sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');
  6952 
  8960 
  6953 				if (s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])
  8961 				if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])
  6954 					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
  8962 					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
  6955 
  8963 
  6956 				each(explode(s.plugins), function(p) {
  8964 				each(explode(s.plugins), function(p) {
  6957 					if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) {
  8965 					if (p && p.charAt(0) != '-' && !PluginManager.urls[p]) {
  6958 						// Skip safari plugin for other browsers
  8966 						// Skip safari plugin for other browsers
  6963 					}
  8971 					}
  6964 				});
  8972 				});
  6965 
  8973 
  6966 				// Init when que is loaded
  8974 				// Init when que is loaded
  6967 				sl.loadQueue(function() {
  8975 				sl.loadQueue(function() {
  6968 					if (s.ask) {
       
  6969 						function ask() {
       
  6970 							// Yield for awhile to avoid focus bug on FF 3 when cancel is pressed
       
  6971 							window.setTimeout(function() {
       
  6972 								Event.remove(t.id, 'focus', ask);
       
  6973 
       
  6974 								t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {
       
  6975 									if (s)
       
  6976 										t.init();
       
  6977 								});
       
  6978 							}, 0);
       
  6979 						};
       
  6980 
       
  6981 						Event.add(t.id, 'focus', ask);
       
  6982 						return;
       
  6983 					}
       
  6984 
       
  6985 					if (!t.removed)
  8976 					if (!t.removed)
  6986 						t.init();
  8977 						t.init();
  6987 				});
  8978 				});
  6988 			};
  8979 			};
  6989 
  8980 
  6990 			// Load compat2x first
  8981 			loadScripts();
  6991 			if (s.plugins.indexOf('compat2x') != -1) {
       
  6992 				PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
       
  6993 				sl.loadQueue(loadScripts);
       
  6994 			} else
       
  6995 				loadScripts();
       
  6996 		},
  8982 		},
  6997 
  8983 
  6998 		init : function() {
  8984 		init : function() {
  6999 			var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;
  8985 			var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;
  7000 
  8986 
  7001 			EditorManager.add(t);
  8987 			EditorManager.add(t);
  7002 
  8988 
  7003 			// Create theme
  8989 			if (s.theme) {
  7004 			s.theme = s.theme.replace(/-/, '');
  8990 				s.theme = s.theme.replace(/-/, '');
  7005 			o = ThemeManager.get(s.theme);
  8991 				o = ThemeManager.get(s.theme);
  7006 			t.theme = new o();
  8992 				t.theme = new o();
  7007 
  8993 
  7008 			if (t.theme.init && s.init_theme)
  8994 				if (t.theme.init && s.init_theme)
  7009 				t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
  8995 					t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
       
  8996 			}
  7010 
  8997 
  7011 			// Create all plugins
  8998 			// Create all plugins
  7012 			each(explode(s.plugins.replace(/\-/g, '')), function(p) {
  8999 			each(explode(s.plugins.replace(/\-/g, '')), function(p) {
  7013 				var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;
  9000 				var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;
  7014 
  9001 
  7031 			}
  9018 			}
  7032 
  9019 
  7033 			if (s.popup_css_add)
  9020 			if (s.popup_css_add)
  7034 				s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);
  9021 				s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);
  7035 
  9022 
  7036 			// Setup control factory
       
  7037 			t.controlManager = new tinymce.ControlManager(t);
  9023 			t.controlManager = new tinymce.ControlManager(t);
       
  9024 
  7038 			t.undoManager = new tinymce.UndoManager(t);
  9025 			t.undoManager = new tinymce.UndoManager(t);
  7039 
  9026 
  7040 			// Pass through
  9027 			// Pass through
  7041 			t.undoManager.onAdd.add(function(um, l) {
  9028 			t.undoManager.onAdd.add(function(um, l) {
  7042 				if (!l.initial)
  9029 				if (!l.initial)
  7102 				});
  9089 				});
  7103 
  9090 
  7104 				t.editorContainer = o.editorContainer;
  9091 				t.editorContainer = o.editorContainer;
  7105 			}
  9092 			}
  7106 
  9093 
  7107 			
  9094 
       
  9095 			// User specified a document.domain value
       
  9096 			if (document.domain && location.hostname != document.domain)
       
  9097 				tinymce.relaxedDomain = document.domain;
       
  9098 
  7108 			// Resize editor
  9099 			// Resize editor
  7109 			DOM.setStyles(o.sizeContainer || o.editorContainer, {
  9100 			DOM.setStyles(o.sizeContainer || o.editorContainer, {
  7110 				width : w,
  9101 				width : w,
  7111 				height : h
  9102 				height : h
  7112 			});
  9103 			});
  7113 
  9104 
  7114 			h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');
  9105 			h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');
  7115 			if (h < 100)
  9106 			if (h < 100)
  7116 				h = 100;
  9107 				h = 100;
  7117 
  9108 
  7118 			t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" />';
  9109 			t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml">';
       
  9110 
       
  9111 			// We only need to override paths if we have to
       
  9112 			// IE has a bug where it remove site absolute urls to relative ones if this is specified
       
  9113 			if (s.document_base_url != tinymce.documentBaseURL)
       
  9114 				t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />';
       
  9115 
  7119 			t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
  9116 			t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
  7120 
  9117 
  7121 			if (tinymce.relaxedDomain)
  9118 			if (tinymce.relaxedDomain)
  7122 				t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';
  9119 				t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';
  7123 
  9120 
  7157 
  9154 
  7158 			t.contentAreaContainer = o.iframeContainer;
  9155 			t.contentAreaContainer = o.iframeContainer;
  7159 			DOM.get(o.editorContainer).style.display = t.orgDisplay;
  9156 			DOM.get(o.editorContainer).style.display = t.orgDisplay;
  7160 			DOM.get(t.id).style.display = 'none';
  9157 			DOM.get(t.id).style.display = 'none';
  7161 
  9158 
  7162 			// Safari 2.x requires us to wait for the load event and load a real HTML doc
  9159 			if (!isIE || !tinymce.relaxedDomain)
  7163 			if (tinymce.isOldWebKit) {
  9160 				t.setupIframe();
  7164 				Event.add(n, 'load', t.setupIframe, t);
  9161 
  7165 				n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
  9162 			e = n = o = null; // Cleanup
  7166 			} else {
       
  7167 				if (!isIE || !tinymce.relaxedDomain)
       
  7168 					t.setupIframe();
       
  7169 
       
  7170 				e = n = o = null; // Cleanup
       
  7171 			}
       
  7172 		},
  9163 		},
  7173 
  9164 
  7174 		setupIframe : function() {
  9165 		setupIframe : function() {
  7175 			var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
  9166 			var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
  7176 
  9167 
  7202 					b.contentEditable = true;
  9193 					b.contentEditable = true;
  7203 
  9194 
  7204 				DOM.show(b);
  9195 				DOM.show(b);
  7205 			}
  9196 			}
  7206 
  9197 
  7207 			// Setup objects
  9198 			t.dom = new tinymce.dom.DOMUtils(t.getDoc(), {
  7208 			t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
       
  7209 				keep_values : true,
  9199 				keep_values : true,
  7210 				url_converter : t.convertURL,
  9200 				url_converter : t.convertURL,
  7211 				url_converter_scope : t,
  9201 				url_converter_scope : t,
  7212 				hex_colors : s.force_hex_style_colors,
  9202 				hex_colors : s.force_hex_style_colors,
  7213 				class_filter : s.class_filter,
  9203 				class_filter : s.class_filter,
  7214 				update_styles : 1,
  9204 				update_styles : 1,
  7215 				fix_ie_paragraphs : 1
  9205 				fix_ie_paragraphs : 1
  7216 			});
  9206 			});
  7217 
  9207 
  7218 			t.serializer = new tinymce.dom.Serializer({
  9208 			t.serializer = new tinymce.dom.Serializer(extend(s, {
  7219 				entity_encoding : s.entity_encoding,
       
  7220 				entities : s.entities,
       
  7221 				valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,
  9209 				valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,
  7222 				extended_valid_elements : s.extended_valid_elements,
       
  7223 				valid_child_elements : s.valid_child_elements,
       
  7224 				invalid_elements : s.invalid_elements,
       
  7225 				fix_table_elements : s.fix_table_elements,
       
  7226 				fix_list_elements : s.fix_list_elements,
       
  7227 				fix_content_duplication : s.fix_content_duplication,
       
  7228 				convert_fonts_to_spans : s.convert_fonts_to_spans,
       
  7229 				font_size_classes  : s.font_size_classes,
       
  7230 				font_size_style_values : s.font_size_style_values,
       
  7231 				apply_source_formatting : s.apply_source_formatting,
       
  7232 				remove_linebreaks : s.remove_linebreaks,
       
  7233 				element_format : s.element_format,
       
  7234 				dom : t.dom
  9210 				dom : t.dom
  7235 			});
  9211 			}));
  7236 
  9212 
  7237 			t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
  9213 			t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
       
  9214 
  7238 			t.forceBlocks = new tinymce.ForceBlocks(t, {
  9215 			t.forceBlocks = new tinymce.ForceBlocks(t, {
  7239 				forced_root_block : s.forced_root_block
  9216 				forced_root_block : s.forced_root_block
  7240 			});
  9217 			});
  7241 			t.editorCommands = new tinymce.EditorCommands(t);
  9218 			t.editorCommands = new tinymce.EditorCommands(t);
  7242 
  9219 
  7263 			if (s.directionality)
  9240 			if (s.directionality)
  7264 				t.getBody().dir = s.directionality;
  9241 				t.getBody().dir = s.directionality;
  7265 
  9242 
  7266 			if (s.nowrap)
  9243 			if (s.nowrap)
  7267 				t.getBody().style.whiteSpace = "nowrap";
  9244 				t.getBody().style.whiteSpace = "nowrap";
  7268 
       
  7269 			if (s.auto_resize)
       
  7270 				t.onNodeChange.add(t.resizeToContent, t);
       
  7271 
  9245 
  7272 			if (s.custom_elements) {
  9246 			if (s.custom_elements) {
  7273 				function handleCustom(ed, o) {
  9247 				function handleCustom(ed, o) {
  7274 					each(explode(s.custom_elements), function(v) {
  9248 					each(explode(s.custom_elements), function(v) {
  7275 						var n;
  9249 						var n;
  7286 				};
  9260 				};
  7287 
  9261 
  7288 				t.onBeforeSetContent.add(handleCustom);
  9262 				t.onBeforeSetContent.add(handleCustom);
  7289 				t.onPostProcess.add(function(ed, o) {
  9263 				t.onPostProcess.add(function(ed, o) {
  7290 					if (o.set)
  9264 					if (o.set)
  7291 						handleCustom(ed, o)
  9265 						handleCustom(ed, o);
  7292 				});
  9266 				});
  7293 			}
  9267 			}
  7294 
  9268 
  7295 			if (s.handle_node_change_callback) {
  9269 			if (s.handle_node_change_callback) {
  7296 				t.onNodeChange.add(function(ed, cm, n) {
  9270 				t.onNodeChange.add(function(ed, cm, n) {
  7403 					if (t.execCallback('handle_event_callback', e, ed, o) === false)
  9377 					if (t.execCallback('handle_event_callback', e, ed, o) === false)
  7404 						Event.cancel(e);
  9378 						Event.cancel(e);
  7405 				});
  9379 				});
  7406 			}
  9380 			}
  7407 
  9381 
       
  9382 			// Add visual aids when new contents is added
  7408 			t.onSetContent.add(function() {
  9383 			t.onSetContent.add(function() {
  7409 				// Safari needs some time, it will crash the browser when a link is created otherwise
  9384 				t.addVisual(t.getBody());
  7410 				// I think this crash issue is resolved in the latest 3.0.4
       
  7411 				//window.setTimeout(function() {
       
  7412 					t.addVisual(t.getBody());
       
  7413 				//}, 1);
       
  7414 			});
  9385 			});
  7415 
  9386 
  7416 			// Remove empty contents
  9387 			// Remove empty contents
  7417 			if (s.padd_empty_editor) {
  9388 			if (s.padd_empty_editor) {
  7418 				t.onPostProcess.add(function(ed, o) {
  9389 				t.onPostProcess.add(function(ed, o) {
  7419 					o.content = o.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');
  9390 					o.content = o.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');
  7420 				});
  9391 				});
  7421 			}
  9392 			}
  7422 
  9393 
  7423 			if (isGecko && !s.readonly) {
  9394 			if (isGecko) {
  7424 				try {
  9395 				// Fix gecko link bug, when a link is placed at the end of block elements there is
  7425 					// Design mode must be set here once again to fix a bug where
  9396 				// no way to move the caret behind the link. This fix adds a bogus br element after the link
  7426 					// Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again
  9397 				function fixLinks(ed, o) {
  7427 					d.designMode = 'Off';
  9398 					each(ed.dom.select('a'), function(n) {
  7428 					d.designMode = 'On';
  9399 						var pn = n.parentNode;
  7429 				} catch (ex) {
  9400 
  7430 					// Will fail on Gecko if the editor is placed in an hidden container element
  9401 						if (ed.dom.isBlock(pn) && pn.lastChild === n)
  7431 					// The design mode will be set ones the editor is focused
  9402 							ed.dom.add(pn, 'br', {'mce_bogus' : 1});
       
  9403 					});
       
  9404 				};
       
  9405 
       
  9406 				t.onExecCommand.add(function(ed, cmd) {
       
  9407 					if (cmd === 'CreateLink')
       
  9408 						fixLinks(ed);
       
  9409 				});
       
  9410 
       
  9411 				t.onSetContent.add(t.selection.onSetContent.add(fixLinks));
       
  9412 
       
  9413 				if (!s.readonly) {
       
  9414 					try {
       
  9415 						// Design mode must be set here once again to fix a bug where
       
  9416 						// Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again
       
  9417 						d.designMode = 'Off';
       
  9418 						d.designMode = 'On';
       
  9419 					} catch (ex) {
       
  9420 						// Will fail on Gecko if the editor is placed in an hidden container element
       
  9421 						// The design mode will be set ones the editor is focused
       
  9422 					}
  7432 				}
  9423 				}
  7433 			}
  9424 			}
  7434 
  9425 
  7435 			// A small timeout was needed since firefox will remove. Bug: #1838304
  9426 			// A small timeout was needed since firefox will remove. Bug: #1838304
  7436 			setTimeout(function () {
  9427 			setTimeout(function () {
  7468 			}, 1);
  9459 			}, 1);
  7469 	
  9460 	
  7470 			e = null;
  9461 			e = null;
  7471 		},
  9462 		},
  7472 
  9463 
  7473 		
  9464 
  7474 		focus : function(sf) {
  9465 		focus : function(sf) {
  7475 			var oed, t = this, ce = t.settings.content_editable;
  9466 			var oed, t = this, ce = t.settings.content_editable;
  7476 
  9467 
  7477 			if (!sf) {
  9468 			if (!sf) {
  7478 				// Is not content editable or the selection is outside the area in IE
  9469 				// Is not content editable or the selection is outside the area in IE
  7479 				// the IE statement is needed to avoid bluring if element selections inside layers since
  9470 				// the IE statement is needed to avoid bluring if element selections inside layers since
  7480 				// the layer is like it's own document in IE
  9471 				// the layer is like it's own document in IE
  7481 				if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc()))
  9472 				if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc()))
  7482 					t.getWin().focus();
  9473 					t.getWin().focus();
  7483 
  9474 
  7484 							}
  9475 			}
  7485 
  9476 
  7486 			if (EditorManager.activeEditor != t) {
  9477 			if (EditorManager.activeEditor != t) {
  7487 				if ((oed = EditorManager.activeEditor) != null)
  9478 				if ((oed = EditorManager.activeEditor) != null)
  7488 					oed.onDeactivate.dispatch(oed, t);
  9479 					oed.onDeactivate.dispatch(oed, t);
  7489 
  9480 
  7682 
  9673 
  7683 			if (s)
  9674 			if (s)
  7684 				return true;
  9675 				return true;
  7685 
  9676 
  7686 			// Theme commands
  9677 			// Theme commands
  7687 			if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {
  9678 			if (t.theme && t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {
       
  9679 				t.onExecCommand.dispatch(t, cmd, ui, val, a);
       
  9680 				return true;
       
  9681 			}
       
  9682 
       
  9683 			// Execute global commands
       
  9684 			if (tinymce.GlobalCommands.execCommand(t, cmd, ui, val)) {
  7688 				t.onExecCommand.dispatch(t, cmd, ui, val, a);
  9685 				t.onExecCommand.dispatch(t, cmd, ui, val, a);
  7689 				return true;
  9686 				return true;
  7690 			}
  9687 			}
  7691 
  9688 
  7692 			// Editor commands
  9689 			// Editor commands
  7787 			this.onSetProgressState.dispatch(this, b, ti, o);
  9784 			this.onSetProgressState.dispatch(this, b, ti, o);
  7788 
  9785 
  7789 			return b;
  9786 			return b;
  7790 		},
  9787 		},
  7791 
  9788 
  7792 		resizeToContent : function() {
       
  7793 			var t = this;
       
  7794 
       
  7795 			DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight);
       
  7796 		},
       
  7797 
       
  7798 		load : function(o) {
  9789 		load : function(o) {
  7799 			var t = this, e = t.getElement(), h;
  9790 			var t = this, e = t.getElement(), h;
  7800 
  9791 
  7801 			if (e) {
  9792 			if (e) {
  7802 				o = o || {};
  9793 				o = o || {};
  7803 				o.load = true;
  9794 				o.load = true;
  7804 
  9795 
       
  9796 				// Double encode existing entities in the value
  7805 				h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);
  9797 				h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);
  7806 				o.element = e;
  9798 				o.element = e;
  7807 
  9799 
  7808 				if (!o.no_events)
  9800 				if (!o.no_events)
  7809 					t.onLoadContent.dispatch(t, o);
  9801 					t.onLoadContent.dispatch(t, o);
  8054 			if (!s) {
 10046 			if (!s) {
  8055 				tinymce.removeUnload(t.destroy);
 10047 				tinymce.removeUnload(t.destroy);
  8056 				tinyMCE.onBeforeUnload.remove(t._beforeUnload);
 10048 				tinyMCE.onBeforeUnload.remove(t._beforeUnload);
  8057 
 10049 
  8058 				// Manual destroy
 10050 				// Manual destroy
  8059 				if (t.theme.destroy)
 10051 				if (t.theme && t.theme.destroy)
  8060 					t.theme.destroy();
 10052 					t.theme.destroy();
  8061 
 10053 
  8062 				// Destroy controls, selection and dom
 10054 				// Destroy controls, selection and dom
  8063 				t.controlManager.destroy();
 10055 				t.controlManager.destroy();
  8064 				t.selection.destroy();
 10056 				t.selection.destroy();
  8126 			each(lo, function(v, k) {
 10118 			each(lo, function(v, k) {
  8127 				switch (k) {
 10119 				switch (k) {
  8128 					case 'contextmenu':
 10120 					case 'contextmenu':
  8129 						if (tinymce.isOpera) {
 10121 						if (tinymce.isOpera) {
  8130 							// Fake contextmenu on Opera
 10122 							// Fake contextmenu on Opera
  8131 							Event.add(t.getBody(), 'mousedown', function(e) {
 10123 							t.dom.bind(t.getBody(), 'mousedown', function(e) {
  8132 								if (e.ctrlKey) {
 10124 								if (e.ctrlKey) {
  8133 									e.fakeType = 'contextmenu';
 10125 									e.fakeType = 'contextmenu';
  8134 									eventHandler(e);
 10126 									eventHandler(e);
  8135 								}
 10127 								}
  8136 							});
 10128 							});
  8137 						} else
 10129 						} else
  8138 							Event.add(t.getBody(), k, eventHandler);
 10130 							t.dom.bind(t.getBody(), k, eventHandler);
  8139 						break;
 10131 						break;
  8140 
 10132 
  8141 					case 'paste':
 10133 					case 'paste':
  8142 						Event.add(t.getBody(), k, function(e) {
 10134 						t.dom.bind(t.getBody(), k, function(e) {
  8143 							var tx, h, el, r;
 10135 							eventHandler(e);
  8144 
       
  8145 							// Get plain text data
       
  8146 							if (e.clipboardData)
       
  8147 								tx = e.clipboardData.getData('text/plain');
       
  8148 							else if (tinymce.isIE)
       
  8149 								tx = t.getWin().clipboardData.getData('Text');
       
  8150 
       
  8151 							// Get HTML data
       
  8152 							/*if (tinymce.isIE) {
       
  8153 								el = DOM.add(DOM.doc.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'});
       
  8154 								r = DOM.doc.body.createTextRange();
       
  8155 								r.moveToElementText(el);
       
  8156 								r.execCommand('Paste');
       
  8157 								h = el.innerHTML;
       
  8158 								DOM.remove(el);
       
  8159 							}*/
       
  8160 
       
  8161 							eventHandler(e, {text : tx, html : h});
       
  8162 						});
 10136 						});
  8163 						break;
 10137 						break;
  8164 
 10138 
  8165 					case 'submit':
 10139 					case 'submit':
  8166 					case 'reset':
 10140 					case 'reset':
  8167 						Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
 10141 						t.dom.bind(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
  8168 						break;
 10142 						break;
  8169 
 10143 
  8170 					default:
 10144 					default:
  8171 						Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
 10145 						t.dom.bind(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
  8172 				}
 10146 				}
  8173 			});
 10147 			});
  8174 
 10148 
  8175 			Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
 10149 			t.dom.bind(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
  8176 				t.focus(true);
 10150 				t.focus(true);
  8177 			});
 10151 			});
  8178 
 10152 
  8179 			
 10153 
  8180 			// Fixes bug where a specified document_base_uri could result in broken images
 10154 			// Fixes bug where a specified document_base_uri could result in broken images
  8181 			// This will also fix drag drop of images in Gecko
 10155 			// This will also fix drag drop of images in Gecko
  8182 			if (tinymce.isGecko) {
 10156 			if (tinymce.isGecko) {
  8183 				// Convert all images to absolute URLs
 10157 				// Convert all images to absolute URLs
  8184 /*				t.onSetContent.add(function(ed, o) {
 10158 /*				t.onSetContent.add(function(ed, o) {
  8188 						if (v = e.getAttribute('mce_src'))
 10162 						if (v = e.getAttribute('mce_src'))
  8189 							e.src = t.documentBaseURI.toAbsolute(v);
 10163 							e.src = t.documentBaseURI.toAbsolute(v);
  8190 					})
 10164 					})
  8191 				});*/
 10165 				});*/
  8192 
 10166 
  8193 				Event.add(t.getDoc(), 'DOMNodeInserted', function(e) {
 10167 				t.dom.bind(t.getDoc(), 'DOMNodeInserted', function(e) {
  8194 					var v;
 10168 					var v;
  8195 
 10169 
  8196 					e = e.target;
 10170 					e = e.target;
  8197 
 10171 
  8198 					if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src')))
 10172 					if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src')))
  8249 			// Add reset handler
 10223 			// Add reset handler
  8250 			t.onReset.add(function() {
 10224 			t.onReset.add(function() {
  8251 				t.setContent(t.startContent, {format : 'raw'});
 10225 				t.setContent(t.startContent, {format : 'raw'});
  8252 			});
 10226 			});
  8253 
 10227 
  8254 			if (t.getParam('tab_focus')) {
       
  8255 				function tabCancel(ed, e) {
       
  8256 					if (e.keyCode === 9)
       
  8257 						return Event.cancel(e);
       
  8258 				};
       
  8259 
       
  8260 				function tabHandler(ed, e) {
       
  8261 					var x, i, f, el, v;
       
  8262 
       
  8263 					function find(d) {
       
  8264 						f = DOM.getParent(ed.id, 'form');
       
  8265 						el = f.elements;
       
  8266 
       
  8267 						if (f) {
       
  8268 							each(el, function(e, i) {
       
  8269 								if (e.id == ed.id) {
       
  8270 									x = i;
       
  8271 									return false;
       
  8272 								}
       
  8273 							});
       
  8274 
       
  8275 							if (d > 0) {
       
  8276 								for (i = x + 1; i < el.length; i++) {
       
  8277 									if (el[i].type != 'hidden')
       
  8278 										return el[i];
       
  8279 								}
       
  8280 							} else {
       
  8281 								for (i = x - 1; i >= 0; i--) {
       
  8282 									if (el[i].type != 'hidden')
       
  8283 										return el[i];
       
  8284 								}
       
  8285 							}
       
  8286 						}
       
  8287 
       
  8288 						return null;
       
  8289 					};
       
  8290 
       
  8291 					if (e.keyCode === 9) {
       
  8292 						v = explode(ed.getParam('tab_focus'));
       
  8293 
       
  8294 						if (v.length == 1) {
       
  8295 							v[1] = v[0];
       
  8296 							v[0] = ':prev';
       
  8297 						}
       
  8298 
       
  8299 						// Find element to focus
       
  8300 						if (e.shiftKey) {
       
  8301 							if (v[0] == ':prev')
       
  8302 								el = find(-1);
       
  8303 							else
       
  8304 								el = DOM.get(v[0]);
       
  8305 						} else {
       
  8306 							if (v[1] == ':next')
       
  8307 								el = find(1);
       
  8308 							else
       
  8309 								el = DOM.get(v[1]);
       
  8310 						}
       
  8311 
       
  8312 						if (el) {
       
  8313 							if (ed = EditorManager.get(el.id || el.name))
       
  8314 								ed.focus();
       
  8315 							else
       
  8316 								window.setTimeout(function() {window.focus();el.focus();}, 10);
       
  8317 
       
  8318 							return Event.cancel(e);
       
  8319 						}
       
  8320 					}
       
  8321 				};
       
  8322 
       
  8323 				t.onKeyUp.add(tabCancel);
       
  8324 
       
  8325 				if (isGecko) {
       
  8326 					t.onKeyPress.add(tabHandler);
       
  8327 					t.onKeyDown.add(tabCancel);
       
  8328 				} else
       
  8329 					t.onKeyDown.add(tabHandler);
       
  8330 			}
       
  8331 
       
  8332 			// Add shortcuts
 10228 			// Add shortcuts
  8333 			if (s.custom_shortcuts) {
 10229 			if (s.custom_shortcuts) {
  8334 				if (s.custom_undo_redo_keyboard_shortcuts) {
 10230 				if (s.custom_undo_redo_keyboard_shortcuts) {
  8335 					t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');
 10231 					t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');
  8336 					t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');
 10232 					t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');
  8403 			}
 10299 			}
  8404 
 10300 
  8405 			if (tinymce.isIE) {
 10301 			if (tinymce.isIE) {
  8406 				// Fix so resize will only update the width and height attributes not the styles of an image
 10302 				// Fix so resize will only update the width and height attributes not the styles of an image
  8407 				// It will also block mceItemNoResize items
 10303 				// It will also block mceItemNoResize items
  8408 				Event.add(t.getDoc(), 'controlselect', function(e) {
 10304 				t.dom.bind(t.getDoc(), 'controlselect', function(e) {
  8409 					var re = t.resizeInfo, cb;
 10305 					var re = t.resizeInfo, cb;
  8410 
 10306 
  8411 					e = e.target;
 10307 					e = e.target;
  8412 
 10308 
  8413 					// Don't do this action for non image elements
 10309 					// Don't do this action for non image elements
  8414 					if (e.nodeName !== 'IMG')
 10310 					if (e.nodeName !== 'IMG')
  8415 						return;
 10311 						return;
  8416 
 10312 
  8417 					if (re)
 10313 					if (re)
  8418 						Event.remove(re.node, re.ev, re.cb);
 10314 						t.dom.unbind(re.node, re.ev, re.cb);
  8419 
 10315 
  8420 					if (!t.dom.hasClass(e, 'mceItemNoResize')) {
 10316 					if (!t.dom.hasClass(e, 'mceItemNoResize')) {
  8421 						ev = 'resizeend';
 10317 						ev = 'resizeend';
  8422 						cb = Event.add(e, ev, function(e) {
 10318 						cb = t.dom.bind(e, ev, function(e) {
  8423 							var v;
 10319 							var v;
  8424 
 10320 
  8425 							e = e.target;
 10321 							e = e.target;
  8426 
 10322 
  8427 							if (v = t.dom.getStyle(e, 'width')) {
 10323 							if (v = t.dom.getStyle(e, 'width')) {
  8434 								t.dom.setStyle(e, 'height', '');
 10330 								t.dom.setStyle(e, 'height', '');
  8435 							}
 10331 							}
  8436 						});
 10332 						});
  8437 					} else {
 10333 					} else {
  8438 						ev = 'resizestart';
 10334 						ev = 'resizestart';
  8439 						cb = Event.add(e, 'resizestart', Event.cancel, Event);
 10335 						cb = t.dom.bind(e, 'resizestart', Event.cancel, Event);
  8440 					}
 10336 					}
  8441 
 10337 
  8442 					re = t.resizeInfo = {
 10338 					re = t.resizeInfo = {
  8443 						node : e,
 10339 						node : e,
  8444 						ev : ev,
 10340 						ev : ev,
  8454 								t.selection.getRng().item(0).removeNode();
 10350 								t.selection.getRng().item(0).removeNode();
  8455 								return Event.cancel(e);
 10351 								return Event.cancel(e);
  8456 							}
 10352 							}
  8457 					}
 10353 					}
  8458 				});
 10354 				});
       
 10355 
       
 10356 				/*if (t.dom.boxModel) {
       
 10357 					t.getBody().style.height = '100%';
       
 10358 
       
 10359 					Event.add(t.getWin(), 'resize', function(e) {
       
 10360 						var docElm = t.getDoc().documentElement;
       
 10361 
       
 10362 						docElm.style.height = (docElm.offsetHeight - 10) + 'px';
       
 10363 					});
       
 10364 				}*/
  8459 			}
 10365 			}
  8460 
 10366 
  8461 			if (tinymce.isOpera) {
 10367 			if (tinymce.isOpera) {
  8462 				t.onClick.add(function(ed, e) {
 10368 				t.onClick.add(function(ed, e) {
  8463 					Event.prevent(e);
 10369 					Event.prevent(e);
  8471 					t.undoManager.add();
 10377 					t.undoManager.add();
  8472 				};
 10378 				};
  8473 
 10379 
  8474 				// Add undo level on editor blur
 10380 				// Add undo level on editor blur
  8475 				if (tinymce.isIE) {
 10381 				if (tinymce.isIE) {
  8476 					Event.add(t.getWin(), 'blur', function(e) {
 10382 					t.dom.bind(t.getWin(), 'blur', function(e) {
  8477 						var n;
 10383 						var n;
  8478 
 10384 
  8479 						// Check added for fullscreen bug
 10385 						// Check added for fullscreen bug
  8480 						if (t.selection) {
 10386 						if (t.selection) {
  8481 							n = t.selection.getNode();
 10387 							n = t.selection.getNode();
  8484 							if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc())
 10390 							if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc())
  8485 								addUndo();
 10391 								addUndo();
  8486 						}
 10392 						}
  8487 					});
 10393 					});
  8488 				} else {
 10394 				} else {
  8489 					Event.add(t.getDoc(), 'blur', function() {
 10395 					t.dom.bind(t.getDoc(), 'blur', function() {
  8490 						if (t.selection && !t.removed)
 10396 						if (t.selection && !t.removed)
  8491 							addUndo();
 10397 							addUndo();
  8492 					});
 10398 					});
  8493 				}
 10399 				}
  8494 
 10400 
  8707 			for (i=d.length - 1; i>=0; i--)
 10613 			for (i=d.length - 1; i>=0; i--)
  8708 				s += '</' + d[i].tag + '>';
 10614 				s += '</' + d[i].tag + '>';
  8709 
 10615 
  8710 			return s;
 10616 			return s;
  8711 		}
 10617 		}
  8712 
 10618 	});
  8713 		});
 10619 })(tinymce);
  8714 })();
 10620 (function(tinymce) {
  8715 
       
  8716 /* file:jscripts/tiny_mce/classes/EditorCommands.js */
       
  8717 
       
  8718 (function() {
       
  8719 	var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;
 10621 	var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;
  8720 
       
  8721 	function isBlock(n) {
       
  8722 		return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n.nodeName);
       
  8723 	};
       
  8724 
 10622 
  8725 	tinymce.create('tinymce.EditorCommands', {
 10623 	tinymce.create('tinymce.EditorCommands', {
  8726 		EditorCommands : function(ed) {
 10624 		EditorCommands : function(ed) {
  8727 			this.editor = ed;
 10625 			this.editor = ed;
  8728 		},
 10626 		},
  8729 
 10627 
  8730 		execCommand : function(cmd, ui, val) {
 10628 		execCommand : function(cmd, ui, val) {
  8731 			var t = this, ed = t.editor, f;
 10629 			var t = this, ed = t.editor, f;
  8732 
 10630 
  8733 			switch (cmd) {
 10631 			switch (cmd) {
  8734 				case 'Cut':
       
  8735 				case 'Copy':
       
  8736 				case 'Paste':
       
  8737 					try {
       
  8738 						ed.getDoc().execCommand(cmd, ui, val);
       
  8739 					} catch (ex) {
       
  8740 						if (isGecko) {
       
  8741 							ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {
       
  8742 								if (s)
       
  8743 									window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
       
  8744 							});
       
  8745 						} else
       
  8746 							ed.windowManager.alert(ed.getLang('clipboard_no_support'));
       
  8747 					}
       
  8748 
       
  8749 					return true;
       
  8750 
       
  8751 				// Ignore these
 10632 				// Ignore these
  8752 				case 'mceResetDesignMode':
 10633 				case 'mceResetDesignMode':
  8753 				case 'mceBeginUndoLevel':
 10634 				case 'mceBeginUndoLevel':
  8754 					return true;
 10635 					return true;
  8755 
 10636 
  8764 				case 'JustifyRight':
 10645 				case 'JustifyRight':
  8765 				case 'JustifyFull':
 10646 				case 'JustifyFull':
  8766 					t.mceJustify(cmd, cmd.substring(7).toLowerCase());
 10647 					t.mceJustify(cmd, cmd.substring(7).toLowerCase());
  8767 					return true;
 10648 					return true;
  8768 
 10649 
  8769 				case 'mceEndUndoLevel':
       
  8770 				case 'mceAddUndoLevel':
       
  8771 					ed.undoManager.add();
       
  8772 					return true;
       
  8773 
       
  8774 				default:
 10650 				default:
  8775 					f = this[cmd];
 10651 					f = this[cmd];
  8776 
 10652 
  8777 					if (f) {
 10653 					if (f) {
  8778 						f.call(this, ui, val);
 10654 						f.call(this, ui, val);
  8790 			iv = ed.settings.indentation;
 10666 			iv = ed.settings.indentation;
  8791 			iu = /[a-z%]+$/i.exec(iv);
 10667 			iu = /[a-z%]+$/i.exec(iv);
  8792 			iv = parseInt(iv);
 10668 			iv = parseInt(iv);
  8793 
 10669 
  8794 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
 10670 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
  8795 				each(this._getSelectedBlocks(), function(e) {
 10671 				each(s.getSelectedBlocks(), function(e) {
  8796 					d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);
 10672 					d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);
  8797 				});
 10673 				});
  8798 
 10674 
  8799 				return;
 10675 				return;
  8800 			}
 10676 			}
  8817 			iv = ed.settings.indentation;
 10693 			iv = ed.settings.indentation;
  8818 			iu = /[a-z%]+$/i.exec(iv);
 10694 			iu = /[a-z%]+$/i.exec(iv);
  8819 			iv = parseInt(iv);
 10695 			iv = parseInt(iv);
  8820 
 10696 
  8821 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
 10697 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
  8822 				each(this._getSelectedBlocks(), function(e) {
 10698 				each(s.getSelectedBlocks(), function(e) {
  8823 					v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);
 10699 					v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);
  8824 					d.setStyle(e, 'paddingLeft', v ? v + iu : '');
 10700 					d.setStyle(e, 'paddingLeft', v ? v + iu : '');
  8825 				});
 10701 				});
  8826 
 10702 
  8827 				return;
 10703 				return;
  8828 			}
 10704 			}
  8829 
 10705 
  8830 			ed.getDoc().execCommand('Outdent', false, null);
 10706 			ed.getDoc().execCommand('Outdent', false, null);
  8831 		},
 10707 		},
  8832 
 10708 
       
 10709 /*
  8833 		mceSetAttribute : function(u, v) {
 10710 		mceSetAttribute : function(u, v) {
  8834 			var ed = this.editor, d = ed.dom, e;
 10711 			var ed = this.editor, d = ed.dom, e;
  8835 
 10712 
  8836 			if (e = d.getParent(ed.selection.getNode(), d.isBlock))
 10713 			if (e = d.getParent(ed.selection.getNode(), d.isBlock))
  8837 				d.setAttrib(e, v.name, v.value);
 10714 				d.setAttrib(e, v.name, v.value);
  8838 		},
 10715 		},
  8839 
 10716 */
  8840 		mceSetContent : function(u, v) {
 10717 		mceSetContent : function(u, v) {
  8841 			this.editor.setContent(v);
 10718 			this.editor.setContent(v);
  8842 		},
 10719 		},
  8843 
 10720 
  8844 		mceToggleVisualAid : function() {
 10721 		mceToggleVisualAid : function() {
  8853 
 10730 
  8854 			s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'})));
 10731 			s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'})));
  8855 		},
 10732 		},
  8856 
 10733 
  8857 		mceInsertLink : function(u, v) {
 10734 		mceInsertLink : function(u, v) {
  8858 			var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A');
 10735 			var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'a');
  8859 
 10736 
  8860 			if (tinymce.is(v, 'string'))
 10737 			if (tinymce.is(v, 'string'))
  8861 				v = {href : v};
 10738 				v = {href : v};
  8862 
 10739 
  8863 			function set(e) {
 10740 			function set(e) {
  8866 				});
 10743 				});
  8867 			};
 10744 			};
  8868 
 10745 
  8869 			if (!e) {
 10746 			if (!e) {
  8870 				ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');
 10747 				ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');
  8871 				each(ed.dom.select('a'), function(e) {
 10748 				each(ed.dom.select('a[href=javascript:mctmp(0);]'), function(e) {
  8872 					if (e.href == 'javascript:mctmp(0);')
 10749 					set(e);
  8873 						set(e);
       
  8874 				});
 10750 				});
  8875 			} else {
 10751 			} else {
  8876 				if (v.href)
 10752 				if (v.href)
  8877 					set(e);
 10753 					set(e);
  8878 				else
 10754 				else
  8894 			var t = this, ed = t.editor, s = ed.selection, e;
 10770 			var t = this, ed = t.editor, s = ed.selection, e;
  8895 
 10771 
  8896 			if (!v) {
 10772 			if (!v) {
  8897 				if (s.isCollapsed())
 10773 				if (s.isCollapsed())
  8898 					s.select(s.getNode());
 10774 					s.select(s.getNode());
  8899 
       
  8900 				t.RemoveFormat();
       
  8901 			} else {
 10775 			} else {
  8902 				if (ed.settings.convert_fonts_to_spans)
 10776 				if (ed.settings.convert_fonts_to_spans)
  8903 					t._applyInlineStyle('span', {style : {fontFamily : v}});
 10777 					t._applyInlineStyle('span', {style : {fontFamily : v}});
  8904 				else
 10778 				else
  8905 					ed.getDoc().execCommand('FontName', false, v);
 10779 					ed.getDoc().execCommand('FontName', false, v);
  8971 		},
 10845 		},
  8972 
 10846 
  8973 		queryValueFontSize : function() {
 10847 		queryValueFontSize : function() {
  8974 			var ed = this.editor, v = 0, p;
 10848 			var ed = this.editor, v = 0, p;
  8975 
 10849 
  8976 			if (p = ed.dom.getParent(ed.selection.getNode(), 'SPAN'))
 10850 			if (p = ed.dom.getParent(ed.selection.getNode(), 'span'))
  8977 				v = p.style.fontSize;
 10851 				v = p.style.fontSize;
  8978 
 10852 
  8979 			if (!v && (isOpera || isWebKit)) {
 10853 			if (!v && (isOpera || isWebKit)) {
  8980 				if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))
 10854 				if (p = ed.dom.getParent(ed.selection.getNode(), 'font'))
  8981 					v = p.size;
 10855 					v = p.size;
  8982 
 10856 
  8983 				return v;
 10857 				return v;
  8984 			}
 10858 			}
  8985 
 10859 
  8987 		},
 10861 		},
  8988 
 10862 
  8989 		queryValueFontName : function() {
 10863 		queryValueFontName : function() {
  8990 			var ed = this.editor, v = 0, p;
 10864 			var ed = this.editor, v = 0, p;
  8991 
 10865 
  8992 			if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))
 10866 			if (p = ed.dom.getParent(ed.selection.getNode(), 'font'))
  8993 				v = p.face;
 10867 				v = p.face;
  8994 
 10868 
  8995 			if (p = ed.dom.getParent(ed.selection.getNode(), 'SPAN'))
 10869 			if (p = ed.dom.getParent(ed.selection.getNode(), 'span'))
  8996 				v = p.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase();
 10870 				v = p.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase();
  8997 
 10871 
  8998 			if (!v)
 10872 			if (!v)
  8999 				v = this._queryVal('FontName');
 10873 				v = this._queryVal('FontName');
  9000 
 10874 
  9055 			// Handle the alignment outselfs, less quirks in all browsers
 10929 			// Handle the alignment outselfs, less quirks in all browsers
  9056 			if (ed.settings.inline_styles && ed.settings.forced_root_block) {
 10930 			if (ed.settings.inline_styles && ed.settings.forced_root_block) {
  9057 				if (rm)
 10931 				if (rm)
  9058 					v = '';
 10932 					v = '';
  9059 
 10933 
  9060 				each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {
 10934 				each(se.getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {
  9061 					dom.setAttrib(e, 'align', '');
 10935 					dom.setAttrib(e, 'align', '');
  9062 					dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);
 10936 					dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);
  9063 				});
 10937 				});
  9064 
 10938 
  9065 				return;
 10939 				return;
  9126 					if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0)
 11000 					if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0)
  9127 						return re && re.test(sc.nodeName) ? null : sc;
 11001 						return re && re.test(sc.nodeName) ? null : sc;
  9128 				}
 11002 				}
  9129 			} else {
 11003 			} else {
  9130 				function getParent(n) {
 11004 				function getParent(n) {
  9131 					return dom.getParent(n, function(n) {return n.nodeType == 1;});
 11005 					return dom.getParent(n, '*');
  9132 				};
 11006 				};
  9133 
 11007 
  9134 				sc = r.startContainer;
 11008 				sc = r.startContainer;
  9135 				ec = r.endContainer;
 11009 				ec = r.endContainer;
  9136 				so = r.startOffset;
 11010 				so = r.startOffset;
  9184 			}
 11058 			}
  9185 
 11059 
  9186 			return null;
 11060 			return null;
  9187 		},
 11061 		},
  9188 
 11062 
  9189 		InsertHorizontalRule : function() {
       
  9190 			// Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");
       
  9191 			if (isGecko || isIE)
       
  9192 				this.editor.selection.setContent('<hr />');
       
  9193 			else
       
  9194 				this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');
       
  9195 		},
       
  9196 
       
  9197 		RemoveFormat : function() {
       
  9198 			var t = this, ed = t.editor, s = ed.selection, b;
       
  9199 
       
  9200 			// Safari breaks tables
       
  9201 			if (isWebKit)
       
  9202 				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'});
       
  9203 			else
       
  9204 				ed.getDoc().execCommand('RemoveFormat', false, null);
       
  9205 
       
  9206 			t.mceSetStyleInfo(0, {command : 'removeformat'});
       
  9207 			ed.addVisual();
       
  9208 		},
       
  9209 
       
  9210 		mceSetStyleInfo : function(u, v) {
 11063 		mceSetStyleInfo : function(u, v) {
  9211 			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;
 11064 			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;
  9212 
 11065 
  9213 			function set(n, e) {
 11066 			function set(n, e) {
  9214 				if (n.nodeType == 1) {
 11067 				if (n.nodeType == 1) {
  9234 			if ((e = t.getSelectedElement()) && !ed.settings.force_span_wrappers)
 11087 			if ((e = t.getSelectedElement()) && !ed.settings.force_span_wrappers)
  9235 				set(e, 1);
 11088 				set(e, 1);
  9236 			else {
 11089 			else {
  9237 				// Generate wrappers and set styles on them
 11090 				// Generate wrappers and set styles on them
  9238 				d.execCommand('FontName', false, '__');
 11091 				d.execCommand('FontName', false, '__');
  9239 				each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {
 11092 				each(dom.select('span,font'), function(n) {
  9240 					var sp, e;
 11093 					var sp, e;
  9241 
 11094 
  9242 					if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {
 11095 					if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {
  9243 						sp = dom.create(nn, {mce_new : '1'});
 11096 						sp = dom.create(nn, {mce_new : '1'});
  9244 
 11097 
  9258 				var p = n.parentNode;
 11111 				var p = n.parentNode;
  9259 
 11112 
  9260 				// Check if it's an old span in a new wrapper
 11113 				// Check if it's an old span in a new wrapper
  9261 				if (!dom.getAttrib(n, 'mce_new')) {
 11114 				if (!dom.getAttrib(n, 'mce_new')) {
  9262 					// Find new wrapper
 11115 					// Find new wrapper
  9263 					p = dom.getParent(n, function(n) {
 11116 					p = dom.getParent(n, '*[mce_new]');
  9264 						return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');
       
  9265 					});
       
  9266 
 11117 
  9267 					if (p)
 11118 					if (p)
  9268 						dom.remove(n, 1);
 11119 						dom.remove(n, 1);
  9269 				}
 11120 				}
  9270 			});
 11121 			});
  9363 				set(false);
 11214 				set(false);
  9364 			} else
 11215 			} else
  9365 				d.execCommand('BackColor', false, val);
 11216 				d.execCommand('BackColor', false, val);
  9366 		},
 11217 		},
  9367 
 11218 
  9368 		Undo : function() {
       
  9369 			var ed = this.editor;
       
  9370 
       
  9371 			if (ed.settings.custom_undo_redo) {
       
  9372 				ed.undoManager.undo();
       
  9373 				ed.nodeChanged();
       
  9374 			} else
       
  9375 				ed.getDoc().execCommand('Undo', false, null);
       
  9376 		},
       
  9377 
       
  9378 		Redo : function() {
       
  9379 			var ed = this.editor;
       
  9380 
       
  9381 			if (ed.settings.custom_undo_redo) {
       
  9382 				ed.undoManager.redo();
       
  9383 				ed.nodeChanged();
       
  9384 			} else
       
  9385 				ed.getDoc().execCommand('Redo', false, null);
       
  9386 		},
       
  9387 
       
  9388 		FormatBlock : function(ui, val) {
 11219 		FormatBlock : function(ui, val) {
  9389 			var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b;
 11220 			var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b;
  9390 
 11221 
  9391 			function isBlock(n) {
 11222 			function isBlock(n) {
  9392 				return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName);
 11223 				return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName);
  9524 
 11355 
  9525 		queryStatemceBlockQuote : function() {
 11356 		queryStatemceBlockQuote : function() {
  9526 			return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});
 11357 			return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});
  9527 		},
 11358 		},
  9528 
 11359 
  9529 		mceBlockQuote : function() {
       
  9530 			var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;
       
  9531 
       
  9532 			function getBQ(e) {
       
  9533 				return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
       
  9534 			};
       
  9535 
       
  9536 			// Get start/end block
       
  9537 			sb = dom.getParent(s.getStart(), isBlock);
       
  9538 			eb = dom.getParent(s.getEnd(), isBlock);
       
  9539 
       
  9540 			// Remove blockquote(s)
       
  9541 			if (bq = getBQ(sb)) {
       
  9542 				if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
       
  9543 					bm = s.getBookmark();
       
  9544 
       
  9545 				// Move all elements after the end block into new bq
       
  9546 				if (getBQ(eb)) {
       
  9547 					bq2 = bq.cloneNode(false);
       
  9548 
       
  9549 					while (n = eb.nextSibling)
       
  9550 						bq2.appendChild(n.parentNode.removeChild(n));
       
  9551 				}
       
  9552 
       
  9553 				// Add new bq after
       
  9554 				if (bq2)
       
  9555 					dom.insertAfter(bq2, bq);
       
  9556 
       
  9557 				// Move all selected blocks after the current bq
       
  9558 				nl = t._getSelectedBlocks(sb, eb);
       
  9559 				for (i = nl.length - 1; i >= 0; i--) {
       
  9560 					dom.insertAfter(nl[i], bq);
       
  9561 				}
       
  9562 
       
  9563 				// Empty bq, then remove it
       
  9564 				if (/^\s*$/.test(bq.innerHTML))
       
  9565 					dom.remove(bq, 1); // Keep children so boomark restoration works correctly
       
  9566 
       
  9567 				// Empty bq, then remote it
       
  9568 				if (bq2 && /^\s*$/.test(bq2.innerHTML))
       
  9569 					dom.remove(bq2, 1); // Keep children so boomark restoration works correctly
       
  9570 
       
  9571 				if (!bm) {
       
  9572 					// Move caret inside empty block element
       
  9573 					if (!isIE) {
       
  9574 						r = ed.getDoc().createRange();
       
  9575 						r.setStart(sb, 0);
       
  9576 						r.setEnd(sb, 0);
       
  9577 						s.setRng(r);
       
  9578 					} else {
       
  9579 						s.select(sb);
       
  9580 						s.collapse(0);
       
  9581 
       
  9582 						// IE misses the empty block some times element so we must move back the caret
       
  9583 						if (dom.getParent(s.getStart(), isBlock) != sb) {
       
  9584 							r = s.getRng();
       
  9585 							r.move('character', -1);
       
  9586 							r.select();
       
  9587 						}
       
  9588 					}
       
  9589 				} else
       
  9590 					t.editor.selection.moveToBookmark(bm);
       
  9591 
       
  9592 				return;
       
  9593 			}
       
  9594 
       
  9595 			// Since IE can start with a totally empty document we need to add the first bq and paragraph
       
  9596 			if (isIE && !sb && !eb) {
       
  9597 				t.editor.getDoc().execCommand('Indent');
       
  9598 				n = getBQ(s.getNode());
       
  9599 				n.style.margin = n.dir = ''; // IE adds margin and dir to bq
       
  9600 				return;
       
  9601 			}
       
  9602 
       
  9603 			if (!sb || !eb)
       
  9604 				return;
       
  9605 
       
  9606 			// If empty paragraph node then do not use bookmark
       
  9607 			if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
       
  9608 				bm = s.getBookmark();
       
  9609 
       
  9610 			// Move selected block elements into a bq
       
  9611 			each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {
       
  9612 				// Found existing BQ add to this one
       
  9613 				if (e.nodeName == 'BLOCKQUOTE' && !bq) {
       
  9614 					bq = e;
       
  9615 					return;
       
  9616 				}
       
  9617 
       
  9618 				// No BQ found, create one
       
  9619 				if (!bq) {
       
  9620 					bq = dom.create('blockquote');
       
  9621 					e.parentNode.insertBefore(bq, e);
       
  9622 				}
       
  9623 
       
  9624 				// Add children from existing BQ
       
  9625 				if (e.nodeName == 'BLOCKQUOTE' && bq) {
       
  9626 					n = e.firstChild;
       
  9627 
       
  9628 					while (n) {
       
  9629 						bq.appendChild(n.cloneNode(true));
       
  9630 						n = n.nextSibling;
       
  9631 					}
       
  9632 
       
  9633 					dom.remove(e);
       
  9634 					return;
       
  9635 				}
       
  9636 
       
  9637 				// Add non BQ element to BQ
       
  9638 				bq.appendChild(dom.remove(e));
       
  9639 			});
       
  9640 
       
  9641 			if (!bm) {
       
  9642 				// Move caret inside empty block element
       
  9643 				if (!isIE) {
       
  9644 					r = ed.getDoc().createRange();
       
  9645 					r.setStart(sb, 0);
       
  9646 					r.setEnd(sb, 0);
       
  9647 					s.setRng(r);
       
  9648 				} else {
       
  9649 					s.select(sb);
       
  9650 					s.collapse(1);
       
  9651 				}
       
  9652 			} else
       
  9653 				s.moveToBookmark(bm);
       
  9654 		},
       
  9655 
       
  9656 		_applyInlineStyle : function(na, at, op) {
 11360 		_applyInlineStyle : function(na, at, op) {
  9657 			var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh;
 11361 			var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh, found;
  9658 
 11362 
  9659 			na = na.toUpperCase();
 11363 			na = na.toUpperCase();
  9660 
 11364 
  9661 			if (op && op.check_classes && at['class'])
 11365 			if (op && op.check_classes && at['class'])
  9662 				op.check_classes.push(at['class']);
 11366 				op.check_classes.push(at['class']);
  9663 
 11367 
  9664 			function replaceFonts() {
 11368 			function removeEmpty() {
  9665 				var bm;
       
  9666 
       
  9667 				each(dom.select(tinymce.isWebKit && !tinymce.isAir ? 'span' : 'font'), function(n) {
       
  9668 					if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') {
       
  9669 						if (!bm)
       
  9670 							bm = ed.selection.getBookmark();
       
  9671 
       
  9672 						at._mce_new = '1';
       
  9673 						dom.replace(dom.create(na, at), n, 1);
       
  9674 					}
       
  9675 				});
       
  9676 
       
  9677 				// Remove redundant elements
       
  9678 				each(dom.select(na), function(n) {
       
  9679 					if (n.getAttribute('_mce_new')) {
       
  9680 						function removeStyle(n) {
       
  9681 							if (n.nodeType == 1) {
       
  9682 								each(at.style, function(v, k) {
       
  9683 									dom.setStyle(n, k, '');
       
  9684 								});
       
  9685 
       
  9686 								// Remove spans with the same class or marked classes
       
  9687 								if (at['class'] && n.className && op) {
       
  9688 									each(op.check_classes, function(c) {
       
  9689 										if (dom.hasClass(n, c))
       
  9690 											dom.removeClass(n, c);
       
  9691 									});
       
  9692 								}
       
  9693 							}
       
  9694 						};
       
  9695 
       
  9696 						// Remove specified style information from child elements
       
  9697 						each(dom.select(na, n), removeStyle);
       
  9698 
       
  9699 						// Remove the specified style information on parent if current node is only child (IE)
       
  9700 						if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1)
       
  9701 							removeStyle(n.parentNode);
       
  9702 
       
  9703 						// Remove the child elements style info if a parent already has it
       
  9704 						dom.getParent(n.parentNode, function(pn) {
       
  9705 							if (pn.nodeType == 1) {
       
  9706 								if (at.style) {
       
  9707 									each(at.style, function(v, k) {
       
  9708 										var sv;
       
  9709 
       
  9710 										if (!lo[k] && (sv = dom.getStyle(pn, k))) {
       
  9711 											if (sv === v)
       
  9712 												dom.setStyle(n, k, '');
       
  9713 
       
  9714 											lo[k] = 1;
       
  9715 										}
       
  9716 									});
       
  9717 								}
       
  9718 
       
  9719 								// Remove spans with the same class or marked classes
       
  9720 								if (at['class'] && pn.className && op) {
       
  9721 									each(op.check_classes, function(c) {
       
  9722 										if (dom.hasClass(pn, c))
       
  9723 											dom.removeClass(n, c);
       
  9724 									});
       
  9725 								}
       
  9726 							}
       
  9727 
       
  9728 							return false;
       
  9729 						});
       
  9730 
       
  9731 						n.removeAttribute('_mce_new');
       
  9732 					}
       
  9733 				});
       
  9734 
       
  9735 				// Remove empty span elements
       
  9736 				each(dom.select(na).reverse(), function(n) {
 11369 				each(dom.select(na).reverse(), function(n) {
  9737 					var c = 0;
 11370 					var c = 0;
  9738 
 11371 
  9739 					// Check if there is any attributes
 11372 					// Check if there is any attributes
  9740 					each(dom.getAttribs(n), function(an) {
 11373 					each(dom.getAttribs(n), function(an) {
  9746 
 11379 
  9747 					// No attributes then remove the element and keep the children
 11380 					// No attributes then remove the element and keep the children
  9748 					if (c == 0)
 11381 					if (c == 0)
  9749 						dom.remove(n, 1);
 11382 						dom.remove(n, 1);
  9750 				});
 11383 				});
  9751 
 11384 			};
       
 11385 
       
 11386 			function replaceFonts() {
       
 11387 				var bm;
       
 11388 
       
 11389 				each(dom.select('span,font'), function(n) {
       
 11390 					if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') {
       
 11391 						if (!bm)
       
 11392 							bm = ed.selection.getBookmark();
       
 11393 
       
 11394 						at._mce_new = '1';
       
 11395 						dom.replace(dom.create(na, at), n, 1);
       
 11396 					}
       
 11397 				});
       
 11398 
       
 11399 				// Remove redundant elements
       
 11400 				each(dom.select(na + '[_mce_new]'), function(n) {
       
 11401 					function removeStyle(n) {
       
 11402 						if (n.nodeType == 1) {
       
 11403 							each(at.style, function(v, k) {
       
 11404 								dom.setStyle(n, k, '');
       
 11405 							});
       
 11406 
       
 11407 							// Remove spans with the same class or marked classes
       
 11408 							if (at['class'] && n.className && op) {
       
 11409 								each(op.check_classes, function(c) {
       
 11410 									if (dom.hasClass(n, c))
       
 11411 										dom.removeClass(n, c);
       
 11412 								});
       
 11413 							}
       
 11414 						}
       
 11415 					};
       
 11416 
       
 11417 					// Remove specified style information from child elements
       
 11418 					each(dom.select(na, n), removeStyle);
       
 11419 
       
 11420 					// Remove the specified style information on parent if current node is only child (IE)
       
 11421 					if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1)
       
 11422 						removeStyle(n.parentNode);
       
 11423 
       
 11424 					// Remove the child elements style info if a parent already has it
       
 11425 					dom.getParent(n.parentNode, function(pn) {
       
 11426 						if (pn.nodeType == 1) {
       
 11427 							if (at.style) {
       
 11428 								each(at.style, function(v, k) {
       
 11429 									var sv;
       
 11430 
       
 11431 									if (!lo[k] && (sv = dom.getStyle(pn, k))) {
       
 11432 										if (sv === v)
       
 11433 											dom.setStyle(n, k, '');
       
 11434 
       
 11435 										lo[k] = 1;
       
 11436 									}
       
 11437 								});
       
 11438 							}
       
 11439 
       
 11440 							// Remove spans with the same class or marked classes
       
 11441 							if (at['class'] && pn.className && op) {
       
 11442 								each(op.check_classes, function(c) {
       
 11443 									if (dom.hasClass(pn, c))
       
 11444 										dom.removeClass(n, c);
       
 11445 								});
       
 11446 							}
       
 11447 						}
       
 11448 
       
 11449 						return false;
       
 11450 					});
       
 11451 
       
 11452 					n.removeAttribute('_mce_new');
       
 11453 				});
       
 11454 
       
 11455 				removeEmpty();
  9752 				ed.selection.moveToBookmark(bm);
 11456 				ed.selection.moveToBookmark(bm);
  9753 
 11457 
  9754 				return !!bm;
 11458 				return !!bm;
  9755 			};
 11459 			};
  9756 
 11460 
  9765 				ed.onKeyDown.remove(kh);
 11469 				ed.onKeyDown.remove(kh);
  9766 				ed.onSetContent.remove(t._applyInlineStyle.chandler);
 11470 				ed.onSetContent.remove(t._applyInlineStyle.chandler);
  9767 			}
 11471 			}
  9768 
 11472 
  9769 			if (ed.selection.isCollapsed()) {
 11473 			if (ed.selection.isCollapsed()) {
       
 11474 				// IE will format the current word so this code can't be executed on that browser
       
 11475 				if (!isIE) {
       
 11476 					each(dom.getParents(ed.selection.getNode(), 'span'), function(n) {
       
 11477 						each(at.style, function(v, k) {
       
 11478 							var kv;
       
 11479 
       
 11480 							if (kv = dom.getStyle(n, k)) {
       
 11481 								if (kv == v) {
       
 11482 									dom.setStyle(n, k, '');
       
 11483 									found = 2;
       
 11484 									return false;
       
 11485 								}
       
 11486 
       
 11487 								found = 1;
       
 11488 								return false;
       
 11489 							}
       
 11490 						});
       
 11491 
       
 11492 						if (found)
       
 11493 							return false;
       
 11494 					});
       
 11495 
       
 11496 					if (found == 2) {
       
 11497 						bm = ed.selection.getBookmark();
       
 11498 
       
 11499 						removeEmpty();
       
 11500 
       
 11501 						ed.selection.moveToBookmark(bm);
       
 11502 
       
 11503 						// Node change needs to be detached since the onselect event
       
 11504 						// for the select box will run the onclick handler after onselect call. Todo: Add a nicer fix!
       
 11505 						window.setTimeout(function() {
       
 11506 							ed.nodeChanged();
       
 11507 						}, 1);
       
 11508 
       
 11509 						return;
       
 11510 					}
       
 11511 				}
       
 11512 
  9770 				// Start collecting styles
 11513 				// Start collecting styles
  9771 				t._pendingStyles = tinymce.extend(t._pendingStyles || {}, at.style);
 11514 				t._pendingStyles = tinymce.extend(t._pendingStyles || {}, at.style);
  9772 
 11515 
  9773 				t._applyInlineStyle.chandler = ed.onSetContent.add(function() {
 11516 				t._applyInlineStyle.chandler = ed.onSetContent.add(function() {
  9774 					delete t._pendingStyles;
 11517 					delete t._pendingStyles;
  9793 				ed.onKeyDown.add(kh);
 11536 				ed.onKeyDown.add(kh);
  9794 				ed.onKeyPress.add(kh);
 11537 				ed.onKeyPress.add(kh);
  9795 				ed.onKeyUp.add(kh);
 11538 				ed.onKeyUp.add(kh);
  9796 			} else
 11539 			} else
  9797 				t._pendingStyles = 0;
 11540 				t._pendingStyles = 0;
  9798 		},
       
  9799 
       
  9800 /*
       
  9801 		_mceBlockQuote : function() {
       
  9802 			var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;
       
  9803 
       
  9804 			function findBQ(e) {
       
  9805 				return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
       
  9806 			};
       
  9807 
       
  9808 			// Remove blockquote(s)
       
  9809 			if (findBQ(s.getStart())) {
       
  9810 				each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {
       
  9811 					// Found BQ lets remove it
       
  9812 					if (e.nodeName == 'BLOCKQUOTE')
       
  9813 						dom.remove(e, 1);
       
  9814 				});
       
  9815 
       
  9816 				t.editor.selection.moveToBookmark(b);
       
  9817 				return;
       
  9818 			}
       
  9819 
       
  9820 			each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {
       
  9821 				var n;
       
  9822 
       
  9823 				// Found existing BQ add to this one
       
  9824 				if (e.nodeName == 'BLOCKQUOTE' && !bq) {
       
  9825 					bq = e;
       
  9826 					return;
       
  9827 				}
       
  9828 
       
  9829 				// No BQ found, create one
       
  9830 				if (!bq) {
       
  9831 					bq = dom.create('blockquote');
       
  9832 					e.parentNode.insertBefore(bq, e);
       
  9833 				}
       
  9834 
       
  9835 				// Add children from existing BQ
       
  9836 				if (e.nodeName == 'BLOCKQUOTE' && bq) {
       
  9837 					n = e.firstChild;
       
  9838 
       
  9839 					while (n) {
       
  9840 						bq.appendChild(n.cloneNode(true));
       
  9841 						n = n.nextSibling;
       
  9842 					}
       
  9843 
       
  9844 					dom.remove(e);
       
  9845 
       
  9846 					return;
       
  9847 				}
       
  9848 
       
  9849 				// Add non BQ element to BQ
       
  9850 				bq.appendChild(dom.remove(e));
       
  9851 			});
       
  9852 
       
  9853 			t.editor.selection.moveToBookmark(b);
       
  9854 		},
       
  9855 */
       
  9856 		_getSelectedBlocks : function(st, en) {
       
  9857 			var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];
       
  9858 
       
  9859 			sb = dom.getParent(st || s.getStart(), isBlock);
       
  9860 			eb = dom.getParent(en || s.getEnd(), isBlock);
       
  9861 
       
  9862 			if (sb)
       
  9863 				bl.push(sb);
       
  9864 
       
  9865 			if (sb && eb && sb != eb) {
       
  9866 				n = sb;
       
  9867 
       
  9868 				while ((n = n.nextSibling) && n != eb) {
       
  9869 					if (isBlock(n))
       
  9870 						bl.push(n);
       
  9871 				}
       
  9872 			}
       
  9873 
       
  9874 			if (eb && sb != eb)
       
  9875 				bl.push(eb);
       
  9876 
       
  9877 			return bl;
       
  9878 		}
 11541 		}
  9879 	});
 11542 	});
  9880 })();
 11543 })(tinymce);(function(tinymce) {
  9881 
 11544 	tinymce.create('tinymce.UndoManager', {
  9882 
 11545 		index : 0,
  9883 /* file:jscripts/tiny_mce/classes/UndoManager.js */
 11546 		data : null,
  9884 
 11547 		typing : 0,
  9885 tinymce.create('tinymce.UndoManager', {
 11548 
  9886 	index : 0,
 11549 		UndoManager : function(ed) {
  9887 	data : null,
 11550 			var t = this, Dispatcher = tinymce.util.Dispatcher;
  9888 	typing : 0,
 11551 
  9889 
 11552 			t.editor = ed;
  9890 	UndoManager : function(ed) {
 11553 			t.data = [];
  9891 		var t = this, Dispatcher = tinymce.util.Dispatcher;
 11554 			t.onAdd = new Dispatcher(this);
  9892 
 11555 			t.onUndo = new Dispatcher(this);
  9893 		t.editor = ed;
 11556 			t.onRedo = new Dispatcher(this);
  9894 		t.data = [];
 11557 		},
  9895 		t.onAdd = new Dispatcher(this);
 11558 
  9896 		t.onUndo = new Dispatcher(this);
 11559 		add : function(l) {
  9897 		t.onRedo = new Dispatcher(this);
 11560 			var t = this, i, ed = t.editor, b, s = ed.settings, la;
  9898 	},
 11561 
  9899 
 11562 			l = l || {};
  9900 	add : function(l) {
 11563 			l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
  9901 		var t = this, i, ed = t.editor, b, s = ed.settings, la;
 11564 
  9902 
 11565 			// Add undo level if needed
  9903 		l = l || {};
 11566 			l.content = l.content.replace(/^\s*|\s*$/g, '');
  9904 		l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
 11567 			la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];
  9905 
 11568 			if (!l.initial && la && l.content == la.content)
  9906 		// Add undo level if needed
 11569 				return null;
  9907 		l.content = l.content.replace(/^\s*|\s*$/g, '');
 11570 
  9908 		la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];
 11571 			// Time to compress
  9909 		if (!l.initial && la && l.content == la.content)
 11572 			if (s.custom_undo_redo_levels) {
  9910 			return null;
 11573 				if (t.data.length > s.custom_undo_redo_levels) {
  9911 
 11574 					for (i = 0; i < t.data.length - 1; i++)
  9912 		// Time to compress
 11575 						t.data[i] = t.data[i + 1];
  9913 		if (s.custom_undo_redo_levels) {
 11576 
  9914 			if (t.data.length > s.custom_undo_redo_levels) {
 11577 					t.data.length--;
  9915 				for (i = 0; i < t.data.length - 1; i++)
 11578 					t.index = t.data.length;
  9916 					t.data[i] = t.data[i + 1];
 11579 				}
  9917 
 11580 			}
  9918 				t.data.length--;
 11581 
  9919 				t.index = t.data.length;
 11582 			if (s.custom_undo_redo_restore_selection && !l.initial)
  9920 			}
 11583 				l.bookmark = b = l.bookmark || ed.selection.getBookmark();
       
 11584 
       
 11585 			if (t.index < t.data.length)
       
 11586 				t.index++;
       
 11587 
       
 11588 			// Only initial marked undo levels should be allowed as first item
       
 11589 			// This to workaround a bug with Firefox and the blur event
       
 11590 			if (t.data.length === 0 && !l.initial)
       
 11591 				return null;
       
 11592 
       
 11593 			// Add level
       
 11594 			t.data.length = t.index + 1;
       
 11595 			t.data[t.index++] = l;
       
 11596 
       
 11597 			if (l.initial)
       
 11598 				t.index = 0;
       
 11599 
       
 11600 			// Set initial bookmark use first real undo level
       
 11601 			if (t.data.length == 2 && t.data[0].initial)
       
 11602 				t.data[0].bookmark = b;
       
 11603 
       
 11604 			t.onAdd.dispatch(t, l);
       
 11605 			ed.isNotDirty = 0;
       
 11606 
       
 11607 			//console.dir(t.data);
       
 11608 
       
 11609 			return l;
       
 11610 		},
       
 11611 
       
 11612 		undo : function() {
       
 11613 			var t = this, ed = t.editor, l = l, i;
       
 11614 
       
 11615 			if (t.typing) {
       
 11616 				t.add();
       
 11617 				t.typing = 0;
       
 11618 			}
       
 11619 
       
 11620 			if (t.index > 0) {
       
 11621 				// If undo on last index then take snapshot
       
 11622 				if (t.index == t.data.length && t.index > 1) {
       
 11623 					i = t.index;
       
 11624 					t.typing = 0;
       
 11625 
       
 11626 					if (!t.add())
       
 11627 						t.index = i;
       
 11628 
       
 11629 					--t.index;
       
 11630 				}
       
 11631 
       
 11632 				l = t.data[--t.index];
       
 11633 				ed.setContent(l.content, {format : 'raw'});
       
 11634 				ed.selection.moveToBookmark(l.bookmark);
       
 11635 
       
 11636 				t.onUndo.dispatch(t, l);
       
 11637 			}
       
 11638 
       
 11639 			return l;
       
 11640 		},
       
 11641 
       
 11642 		redo : function() {
       
 11643 			var t = this, ed = t.editor, l = null;
       
 11644 
       
 11645 			if (t.index < t.data.length - 1) {
       
 11646 				l = t.data[++t.index];
       
 11647 				ed.setContent(l.content, {format : 'raw'});
       
 11648 				ed.selection.moveToBookmark(l.bookmark);
       
 11649 
       
 11650 				t.onRedo.dispatch(t, l);
       
 11651 			}
       
 11652 
       
 11653 			return l;
       
 11654 		},
       
 11655 
       
 11656 		clear : function() {
       
 11657 			var t = this;
       
 11658 
       
 11659 			t.data = [];
       
 11660 			t.index = 0;
       
 11661 			t.typing = 0;
       
 11662 			t.add({initial : true});
       
 11663 		},
       
 11664 
       
 11665 		hasUndo : function() {
       
 11666 			return this.index != 0 || this.typing;
       
 11667 		},
       
 11668 
       
 11669 		hasRedo : function() {
       
 11670 			return this.index < this.data.length - 1;
  9921 		}
 11671 		}
  9922 
       
  9923 		if (s.custom_undo_redo_restore_selection && !l.initial)
       
  9924 			l.bookmark = b = l.bookmark || ed.selection.getBookmark();
       
  9925 
       
  9926 		if (t.index < t.data.length)
       
  9927 			t.index++;
       
  9928 
       
  9929 		// Only initial marked undo levels should be allowed as first item
       
  9930 		// This to workaround a bug with Firefox and the blur event
       
  9931 		if (t.data.length === 0 && !l.initial)
       
  9932 			return null;
       
  9933 
       
  9934 		// Add level
       
  9935 		t.data.length = t.index + 1;
       
  9936 		t.data[t.index++] = l;
       
  9937 
       
  9938 		if (l.initial)
       
  9939 			t.index = 0;
       
  9940 
       
  9941 		// Set initial bookmark use first real undo level
       
  9942 		if (t.data.length == 2 && t.data[0].initial)
       
  9943 			t.data[0].bookmark = b;
       
  9944 
       
  9945 		t.onAdd.dispatch(t, l);
       
  9946 		ed.isNotDirty = 0;
       
  9947 
       
  9948 		//console.dir(t.data);
       
  9949 
       
  9950 		return l;
       
  9951 	},
       
  9952 
       
  9953 	undo : function() {
       
  9954 		var t = this, ed = t.editor, l = l, i;
       
  9955 
       
  9956 		if (t.typing) {
       
  9957 			t.add();
       
  9958 			t.typing = 0;
       
  9959 		}
       
  9960 
       
  9961 		if (t.index > 0) {
       
  9962 			// If undo on last index then take snapshot
       
  9963 			if (t.index == t.data.length && t.index > 1) {
       
  9964 				i = t.index;
       
  9965 				t.typing = 0;
       
  9966 
       
  9967 				if (!t.add())
       
  9968 					t.index = i;
       
  9969 
       
  9970 				--t.index;
       
  9971 			}
       
  9972 
       
  9973 			l = t.data[--t.index];
       
  9974 			ed.setContent(l.content, {format : 'raw'});
       
  9975 			ed.selection.moveToBookmark(l.bookmark);
       
  9976 
       
  9977 			t.onUndo.dispatch(t, l);
       
  9978 		}
       
  9979 
       
  9980 		return l;
       
  9981 	},
       
  9982 
       
  9983 	redo : function() {
       
  9984 		var t = this, ed = t.editor, l = null;
       
  9985 
       
  9986 		if (t.index < t.data.length - 1) {
       
  9987 			l = t.data[++t.index];
       
  9988 			ed.setContent(l.content, {format : 'raw'});
       
  9989 			ed.selection.moveToBookmark(l.bookmark);
       
  9990 
       
  9991 			t.onRedo.dispatch(t, l);
       
  9992 		}
       
  9993 
       
  9994 		return l;
       
  9995 	},
       
  9996 
       
  9997 	clear : function() {
       
  9998 		var t = this;
       
  9999 
       
 10000 		t.data = [];
       
 10001 		t.index = 0;
       
 10002 		t.typing = 0;
       
 10003 		t.add({initial : true});
       
 10004 	},
       
 10005 
       
 10006 	hasUndo : function() {
       
 10007 		return this.index != 0 || this.typing;
       
 10008 	},
       
 10009 
       
 10010 	hasRedo : function() {
       
 10011 		return this.index < this.data.length - 1;
       
 10012 	}
       
 10013 
       
 10014 	});
 11672 	});
 10015 /* file:jscripts/tiny_mce/classes/ForceBlocks.js */
 11673 })(tinymce);
 10016 
 11674 (function(tinymce) {
 10017 (function() {
       
 10018 	// Shorten names
 11675 	// Shorten names
 10019 	var Event, isIE, isGecko, isOpera, each, extend;
 11676 	var Event, isIE, isGecko, isOpera, each, extend;
 10020 
 11677 
 10021 	Event = tinymce.dom.Event;
 11678 	Event = tinymce.dom.Event;
 10022 	isIE = tinymce.isIE;
 11679 	isIE = tinymce.isIE;
 10023 	isGecko = tinymce.isGecko;
 11680 	isGecko = tinymce.isGecko;
 10024 	isOpera = tinymce.isOpera;
 11681 	isOpera = tinymce.isOpera;
 10025 	each = tinymce.each;
 11682 	each = tinymce.each;
 10026 	extend = tinymce.extend;
 11683 	extend = tinymce.extend;
 10027 
 11684 
       
 11685 	// Checks if the selection/caret is at the end of the specified block element
       
 11686 	function isAtEnd(rng, par) {
       
 11687 		var rng2 = par.ownerDocument.createRange();
       
 11688 
       
 11689 		rng2.setStart(rng.endContainer, rng.endOffset);
       
 11690 		rng2.setEndAfter(par);
       
 11691 
       
 11692 		// Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element
       
 11693 		return rng2.cloneContents().textContent.length == 0;
       
 11694 	};
       
 11695 
       
 11696 	function isEmpty(n) {
       
 11697 		n = n.innerHTML;
       
 11698 
       
 11699 		n = n.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi, '-'); // Keep these convert them to - chars
       
 11700 		n = n.replace(/<[^>]+>/g, ''); // Remove all tags
       
 11701 
       
 11702 		return n.replace(/[ \t\r\n]+/g, '') == '';
       
 11703 	};
       
 11704 
 10028 	tinymce.create('tinymce.ForceBlocks', {
 11705 	tinymce.create('tinymce.ForceBlocks', {
 10029 		ForceBlocks : function(ed) {
 11706 		ForceBlocks : function(ed) {
 10030 			var t = this, s = ed.settings, elm;
 11707 			var t = this, s = ed.settings, elm;
 10031 
 11708 
 10032 			t.editor = ed;
 11709 			t.editor = ed;
 10037 			ed.onPreInit.add(t.setup, t);
 11714 			ed.onPreInit.add(t.setup, t);
 10038 
 11715 
 10039 			t.reOpera = new RegExp('(\\u00a0|&#160;|&nbsp;)<\/' + elm + '>', 'gi');
 11716 			t.reOpera = new RegExp('(\\u00a0|&#160;|&nbsp;)<\/' + elm + '>', 'gi');
 10040 			t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');
 11717 			t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');
 10041 			t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');
 11718 			t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');
 10042 			t.reNbsp2BR2 = new RegExp('<p( )([^>]+)>(&nbsp;|&#160;)<\\\/p>|<p>(&nbsp;|&#160;)<\\\/p>'.replace(/p/g, elm), 'gi');
 11719 			t.reNbsp2BR2 = new RegExp('<%p()([^>]+)>(&nbsp;|&#160;)<\\\/%p>|<%p>(&nbsp;|&#160;)<\\\/%p>'.replace(/%p/g, elm), 'gi');
 10043 			t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');
 11720 			t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');
 10044 			t.reTrailBr = new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');
       
 10045 
 11721 
 10046 			function padd(ed, o) {
 11722 			function padd(ed, o) {
 10047 				if (isOpera)
 11723 				if (isOpera)
 10048 					o.content = o.content.replace(t.reOpera, '</' + elm + '>');
 11724 					o.content = o.content.replace(t.reOpera, '</' + elm + '>');
 10049 
 11725 
 10051 
 11727 
 10052 				if (!isIE && !isOpera && o.set) {
 11728 				if (!isIE && !isOpera && o.set) {
 10053 					// Use &nbsp; instead of BR in padded paragraphs
 11729 					// Use &nbsp; instead of BR in padded paragraphs
 10054 					o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');
 11730 					o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');
 10055 					o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');
 11731 					o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');
 10056 				} else {
 11732 				} else
 10057 					o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');
 11733 					o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');
 10058 					o.content = o.content.replace(t.reTrailBr, '</' + elm + '>');
       
 10059 				}
       
 10060 			};
 11734 			};
 10061 
 11735 
 10062 			ed.onBeforeSetContent.add(padd);
 11736 			ed.onBeforeSetContent.add(padd);
 10063 			ed.onPostProcess.add(padd);
 11737 			ed.onPostProcess.add(padd);
 10064 
 11738 
 10140 				rn.parentNode.replaceChild(ne, rn);
 11814 				rn.parentNode.replaceChild(ne, rn);
 10141 
 11815 
 10142 				return ne;
 11816 				return ne;
 10143 			};
 11817 			};
 10144 
 11818 
 10145 			// Replaces IE:s auto generated paragraphs with the specified element name
 11819 			// Padd empty inline elements within block elements
 10146 			if (isIE && s.element != 'P') {
 11820 			// For example: <p><strong><em></em></strong></p> becomes <p><strong><em>&nbsp;</em></strong></p>
 10147 				ed.onKeyPress.add(function(ed, e) {
 11821 			ed.onPreProcess.add(function(ed, o) {
 10148 					t.lastElm = ed.selection.getNode().nodeName;
 11822 				each(ed.dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) {
 10149 				});
 11823 					if (isEmpty(p)) {
 10150 
 11824 						each(ed.dom.select('span,em,strong,b,i', o.node), function(n) {
 10151 				ed.onKeyUp.add(function(ed, e) {
 11825 							if (!n.hasChildNodes()) {
 10152 					var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();
 11826 								n.appendChild(ed.getDoc().createTextNode('\u00a0'));
 10153 
 11827 								return false; // Break the loop one padding is enough
 10154 					if (b.childNodes.length === 1 && n.nodeName == 'P') {
 11828 							}
 10155 						n = ren(n, s.element);
 11829 						});
 10156 						sel.select(n);
       
 10157 						sel.collapse();
       
 10158 						ed.nodeChanged();
       
 10159 					} else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {
       
 10160 						bl = ed.dom.getParent(n, 'P');
       
 10161 
       
 10162 						if (bl) {
       
 10163 							ren(bl, s.element);
       
 10164 							ed.nodeChanged();
       
 10165 						}
       
 10166 					}
 11830 					}
 10167 				});
 11831 				});
       
 11832 			});
       
 11833 
       
 11834 			// IE specific fixes
       
 11835 			if (isIE) {
       
 11836 				// Replaces IE:s auto generated paragraphs with the specified element name
       
 11837 				if (s.element != 'P') {
       
 11838 					ed.onKeyPress.add(function(ed, e) {
       
 11839 						t.lastElm = ed.selection.getNode().nodeName;
       
 11840 					});
       
 11841 
       
 11842 					ed.onKeyUp.add(function(ed, e) {
       
 11843 						var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();
       
 11844 
       
 11845 						if (b.childNodes.length === 1 && n.nodeName == 'P') {
       
 11846 							n = ren(n, s.element);
       
 11847 							sel.select(n);
       
 11848 							sel.collapse();
       
 11849 							ed.nodeChanged();
       
 11850 						} else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {
       
 11851 							bl = ed.dom.getParent(n, 'p');
       
 11852 
       
 11853 							if (bl) {
       
 11854 								ren(bl, s.element);
       
 11855 								ed.nodeChanged();
       
 11856 							}
       
 11857 						}
       
 11858 					});
       
 11859 				}
 10168 			}
 11860 			}
 10169 		},
 11861 		},
 10170 
 11862 
 10171 		find : function(n, t, s) {
 11863 		find : function(n, t, s) {
 10172 			var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1;
 11864 			var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1;
 10197 			// Wrap non blocks into blocks
 11889 			// Wrap non blocks into blocks
 10198 			for (i = nl.length - 1; i >= 0; i--) {
 11890 			for (i = nl.length - 1; i >= 0; i--) {
 10199 				nx = nl[i];
 11891 				nx = nl[i];
 10200 
 11892 
 10201 				// Is text or non block element
 11893 				// Is text or non block element
 10202 				if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) {
 11894 				if (nx.nodeType === 3 || (!t.dom.isBlock(nx) && nx.nodeType !== 8 && !/^(script|mce:script|style|mce:style)$/i.test(nx.nodeName))) {
 10203 					if (!bl) {
 11895 					if (!bl) {
 10204 						// Create new block but ignore whitespace
 11896 						// Create new block but ignore whitespace
 10205 						if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {
 11897 						if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {
 10206 							// Store selection
 11898 							// Store selection
 10207 							if (si == -2 && r) {
 11899 							if (si == -2 && r) {
 10237 									si = sp - bp;
 11929 									si = sp - bp;
 10238 									ei = le;
 11930 									ei = le;
 10239 								}
 11931 								}
 10240 							}
 11932 							}
 10241 
 11933 
       
 11934 							// Uses replaceChild instead of cloneNode since it removes selected attribute from option elements on IE
       
 11935 							// See: http://support.microsoft.com/kb/829907
 10242 							bl = ed.dom.create(ed.settings.forced_root_block);
 11936 							bl = ed.dom.create(ed.settings.forced_root_block);
 10243 							bl.appendChild(nx.cloneNode(1));
       
 10244 							nx.parentNode.replaceChild(bl, nx);
 11937 							nx.parentNode.replaceChild(bl, nx);
       
 11938 							bl.appendChild(nx);
 10245 						}
 11939 						}
 10246 					} else {
 11940 					} else {
 10247 						if (bl.hasChildNodes())
 11941 						if (bl.hasChildNodes())
 10248 							bl.insertBefore(nx, bl.firstChild);
 11942 							bl.insertBefore(nx, bl.firstChild);
 10249 						else
 11943 						else
 10310 
 12004 
 10311 		insertPara : function(e) {
 12005 		insertPara : function(e) {
 10312 			var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
 12006 			var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
 10313 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car;
 12007 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car;
 10314 
 12008 
 10315 			function isEmpty(n) {
       
 10316 				n = n.innerHTML;
       
 10317 				n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
       
 10318 				n = n.replace(/<[^>]+>/g, ''); // Remove all tags
       
 10319 
       
 10320 				return n.replace(/[ \t\r\n]+/g, '') == '';
       
 10321 			};
       
 10322 
       
 10323 			// If root blocks are forced then use Operas default behavior since it's really good
 12009 			// If root blocks are forced then use Operas default behavior since it's really good
 10324 // Removed due to bug: #1853816
 12010 // Removed due to bug: #1853816
 10325 //			if (se.forced_root_block && isOpera)
 12011 //			if (se.forced_root_block && isOpera)
 10326 //				return true;
 12012 //				return true;
 10327 
 12013 
 10346 			en = dir ? s.focusNode : s.anchorNode;
 12032 			en = dir ? s.focusNode : s.anchorNode;
 10347 			eo = dir ? s.focusOffset : s.anchorOffset;
 12033 			eo = dir ? s.focusOffset : s.anchorOffset;
 10348 
 12034 
 10349 			// If selection is in empty table cell
 12035 			// If selection is in empty table cell
 10350 			if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) {
 12036 			if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) {
 10351 				dom.remove(sn.firstChild); // Remove BR
 12037 				if (sn.firstChild.nodeName == 'BR')
       
 12038 					dom.remove(sn.firstChild); // Remove BR
 10352 
 12039 
 10353 				// Create two new block elements
 12040 				// Create two new block elements
 10354 				ed.dom.add(sn, se.element, null, '<br />');
 12041 				if (sn.childNodes.length == 0) {
 10355 				aft = ed.dom.add(sn, se.element, null, '<br />');
 12042 					ed.dom.add(sn, se.element, null, '<br />');
       
 12043 					aft = ed.dom.add(sn, se.element, null, '<br />');
       
 12044 				} else {
       
 12045 					n = sn.innerHTML;
       
 12046 					sn.innerHTML = '';
       
 12047 					ed.dom.add(sn, se.element, null, n);
       
 12048 					aft = ed.dom.add(sn, se.element, null, '<br />');
       
 12049 				}
 10356 
 12050 
 10357 				// Move caret into the last one
 12051 				// Move caret into the last one
 10358 				r = d.createRange();
 12052 				r = d.createRange();
 10359 				r.selectNodeContents(aft);
 12053 				r.selectNodeContents(aft);
 10360 				r.collapse(1);
 12054 				r.collapse(1);
 10383 			sb = t.getParentBlock(sn);
 12077 			sb = t.getParentBlock(sn);
 10384 			eb = t.getParentBlock(en);
 12078 			eb = t.getParentBlock(en);
 10385 			bn = sb ? sb.nodeName : se.element; // Get block name to create
 12079 			bn = sb ? sb.nodeName : se.element; // Get block name to create
 10386 
 12080 
 10387 			// Return inside list use default browser behavior
 12081 			// Return inside list use default browser behavior
 10388 			if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))
 12082 			if (t.dom.getParent(sb, 'ol,ul,pre'))
 10389 				return true;
 12083 				return true;
 10390 
 12084 
 10391 			// If caption or absolute layers then always generate new blocks within
 12085 			// If caption or absolute layers then always generate new blocks within
 10392 			if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {
 12086 			if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {
 10393 				bn = se.element;
 12087 				bn = se.element;
 10394 				sb = null;
 12088 				sb = null;
 10395 			}
 12089 			}
 10396 
 12090 
 10397 			// If caption or absolute layers then always generate new blocks within
 12091 			// If caption or absolute layers then always generate new blocks within
 10398 			if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {
 12092 			if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {
 10399 				bn = se.element;
 12093 				bn = se.element;
 10400 				eb = null;
 12094 				eb = null;
 10401 			}
 12095 			}
 10402 
 12096 
 10403 			// Use P instead
 12097 			// Use P instead
 10404 			if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {
 12098 			if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) {
 10405 				bn = se.element;
 12099 				bn = se.element;
 10406 				sb = eb = null;
 12100 				sb = eb = null;
 10407 			}
 12101 			}
 10408 
 12102 
 10409 			// Setup new before and after blocks
 12103 			// Setup new before and after blocks
 10412 
 12106 
 10413 			// Remove id from after clone
 12107 			// Remove id from after clone
 10414 			aft.removeAttribute('id');
 12108 			aft.removeAttribute('id');
 10415 
 12109 
 10416 			// Is header and cursor is at the end, then force paragraph under
 12110 			// Is header and cursor is at the end, then force paragraph under
 10417 			if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)
 12111 			if (/^(H[1-6])$/.test(bn) && isAtEnd(r, sb))
 10418 				aft = ed.dom.create(se.element);
 12112 				aft = ed.dom.create(se.element);
 10419 
 12113 
 10420 			// Find start chop node
 12114 			// Find start chop node
 10421 			n = sc = sn;
 12115 			n = sc = sn;
 10422 			do {
 12116 			do {
 10557 
 12251 
 10558 			return false;
 12252 			return false;
 10559 		},
 12253 		},
 10560 
 12254 
 10561 		backspaceDelete : function(e, bs) {
 12255 		backspaceDelete : function(e, bs) {
 10562 			var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;
 12256 			var t = this, ed = t.editor, b = ed.getBody(), dom = ed.dom, n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;
       
 12257 
       
 12258 			/*
       
 12259 			var par, rng, nextBlock;
       
 12260 
       
 12261 			// Delete key will not merge paragraphs on Gecko so we need to do this manually
       
 12262 			// Hitting the delete key at the following caret position doesn't merge the elements <p>A|</p><p>B</p>
       
 12263 			// This logic will merge them into this: <p>A|B</p>
       
 12264 			if (e.keyCode == 46) {
       
 12265 				if (r.collapsed) {
       
 12266 					par = dom.getParent(sc, 'p,h1,h2,h3,h4,h5,h6,div');
       
 12267 
       
 12268 					if (par) {
       
 12269 						rng = dom.createRng();
       
 12270 
       
 12271 						rng.setStart(sc, r.startOffset);
       
 12272 						rng.setEndAfter(par);
       
 12273 
       
 12274 						// Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element
       
 12275 						if (dom.getOuterHTML(rng.cloneContents()).replace(/<[^>]+>/g, '').length == 0) {
       
 12276 							nextBlock = dom.getNext(par, 'p,h1,h2,h3,h4,h5,h6,div');
       
 12277 
       
 12278 							// Copy all children from next sibling block and remove it
       
 12279 							if (nextBlock) {
       
 12280 								each(nextBlock.childNodes, function(node) {
       
 12281 									par.appendChild(node.cloneNode(true));
       
 12282 								});
       
 12283 
       
 12284 								dom.remove(nextBlock);
       
 12285 							}
       
 12286 
       
 12287 							// Block the default even since the Gecko team might eventually fix this
       
 12288 							// We will remove this logic once they do we can't feature detect this one
       
 12289 							e.preventDefault();
       
 12290 							return;
       
 12291 						}
       
 12292 					}
       
 12293 				}
       
 12294 			}
       
 12295 			*/
 10563 
 12296 
 10564 			// The caret sometimes gets stuck in Gecko if you delete empty paragraphs
 12297 			// The caret sometimes gets stuck in Gecko if you delete empty paragraphs
 10565 			// This workaround removes the element by hand and moves the caret to the previous element
 12298 			// This workaround removes the element by hand and moves the caret to the previous element
 10566 			if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) {
 12299 			if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) {
 10567 				if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) {
 12300 				if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) {
 10621 			window.setTimeout(function() {
 12354 			window.setTimeout(function() {
 10622 				Event._remove(b, 'DOMNodeInserted', handler);
 12355 				Event._remove(b, 'DOMNodeInserted', handler);
 10623 			}, 1);
 12356 			}, 1);
 10624 		}
 12357 		}
 10625 	});
 12358 	});
 10626 })();
 12359 })(tinymce);
 10627 
 12360 (function(tinymce) {
 10628 /* file:jscripts/tiny_mce/classes/ControlManager.js */
       
 10629 
       
 10630 (function() {
       
 10631 	// Shorten names
 12361 	// Shorten names
 10632 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;
 12362 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;
 10633 
 12363 
 10634 	tinymce.create('tinymce.ControlManager', {
 12364 	tinymce.create('tinymce.ControlManager', {
 10635 		ControlManager : function(ed, s) {
 12365 		ControlManager : function(ed, s) {
 10739 			});
 12469 			});
 10740 
 12470 
 10741 			// Fix for bug #1897785, #1898007
 12471 			// Fix for bug #1897785, #1898007
 10742 			if (tinymce.isIE) {
 12472 			if (tinymce.isIE) {
 10743 				c.onShowMenu.add(function() {
 12473 				c.onShowMenu.add(function() {
       
 12474 					// IE 8 needs focus in order to store away a range with the current collapsed caret location
       
 12475 					ed.focus();
       
 12476 
 10744 					bm = ed.selection.getBookmark(1);
 12477 					bm = ed.selection.getBookmark(1);
 10745 				});
 12478 				});
 10746 
 12479 
 10747 				c.onHideMenu.add(function() {
 12480 				c.onHideMenu.add(function() {
 10748 					if (bm)
 12481 					if (bm) {
 10749 						ed.selection.moveToBookmark(bm);
 12482 						ed.selection.moveToBookmark(bm);
       
 12483 						bm = 0;
       
 12484 					}
 10750 				});
 12485 				});
 10751 			}
 12486 			}
 10752 
 12487 
 10753 			return t.add(c);
 12488 			return t.add(c);
 10754 		},
 12489 		},
 10789 			// Fix focus problem in Safari
 12524 			// Fix focus problem in Safari
 10790 			if (tinymce.isWebKit) {
 12525 			if (tinymce.isWebKit) {
 10791 				c.onPostRender.add(function(c, n) {
 12526 				c.onPostRender.add(function(c, n) {
 10792 					// Store bookmark on mousedown
 12527 					// Store bookmark on mousedown
 10793 					Event.add(n, 'mousedown', function() {
 12528 					Event.add(n, 'mousedown', function() {
 10794 						ed.bookmark = ed.selection.getBookmark('simple');
 12529 						ed.bookmark = ed.selection.getBookmark(1);
 10795 					});
 12530 					});
 10796 
 12531 
 10797 					// Restore on focus, since it might be lost
 12532 					// Restore on focus, since it might be lost
 10798 					Event.add(n, 'focus', function() {
 12533 					Event.add(n, 'focus', function() {
 10799 						ed.selection.moveToBookmark(ed.bookmark);
 12534 						ed.selection.moveToBookmark(ed.bookmark);
 10898 			s.title = ed.translate(s.title);
 12633 			s.title = ed.translate(s.title);
 10899 			s.scope = s.scope || ed;
 12634 			s.scope = s.scope || ed;
 10900 
 12635 
 10901 			if (!s.onclick) {
 12636 			if (!s.onclick) {
 10902 				s.onclick = function(v) {
 12637 				s.onclick = function(v) {
       
 12638 					if (tinymce.isIE)
       
 12639 						bm = ed.selection.getBookmark(1);
       
 12640 
 10903 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
 12641 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
 10904 				};
 12642 				};
 10905 			}
 12643 			}
 10906 
 12644 
 10907 			if (!s.onselect) {
 12645 			if (!s.onselect) {
 10929 			});
 12667 			});
 10930 
 12668 
 10931 			// Fix for bug #1897785, #1898007
 12669 			// Fix for bug #1897785, #1898007
 10932 			if (tinymce.isIE) {
 12670 			if (tinymce.isIE) {
 10933 				c.onShowMenu.add(function() {
 12671 				c.onShowMenu.add(function() {
       
 12672 					// IE 8 needs focus in order to store away a range with the current collapsed caret location
       
 12673 					ed.focus();
 10934 					bm = ed.selection.getBookmark(1);
 12674 					bm = ed.selection.getBookmark(1);
 10935 				});
 12675 				});
 10936 
 12676 
 10937 				c.onHideMenu.add(function() {
 12677 				c.onHideMenu.add(function() {
 10938 					if (bm) {
 12678 					if (bm) {
 10965 		},
 12705 		},
 10966 
 12706 
 10967 		setControlType : function(n, c) {
 12707 		setControlType : function(n, c) {
 10968 			return this._cls[n.toLowerCase()] = c;
 12708 			return this._cls[n.toLowerCase()] = c;
 10969 		},
 12709 		},
 10970 
 12710 	
 10971 		destroy : function() {
 12711 		destroy : function() {
 10972 			each(this.controls, function(c) {
 12712 			each(this.controls, function(c) {
 10973 				c.destroy();
 12713 				c.destroy();
 10974 			});
 12714 			});
 10975 
 12715 
 10976 			this.controls = null;
 12716 			this.controls = null;
 10977 		}
 12717 		}
 10978 
 12718 	});
 10979 		});
 12719 })(tinymce);
 10980 })();
 12720 (function(tinymce) {
 10981 
       
 10982 /* file:jscripts/tiny_mce/classes/WindowManager.js */
       
 10983 
       
 10984 (function() {
       
 10985 	var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;
 12721 	var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;
 10986 
 12722 
 10987 	tinymce.create('tinymce.WindowManager', {
 12723 	tinymce.create('tinymce.WindowManager', {
 10988 		WindowManager : function(ed) {
 12724 		WindowManager : function(ed) {
 10989 			var t = this;
 12725 			var t = this;
 11040 			t.features = s;
 12776 			t.features = s;
 11041 			t.params = p;
 12777 			t.params = p;
 11042 			t.onOpen.dispatch(t, s, p);
 12778 			t.onOpen.dispatch(t, s, p);
 11043 
 12779 
 11044 			u = s.url || s.file;
 12780 			u = s.url || s.file;
 11045 			if (tinymce.relaxedDomain)
       
 11046 				u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;
       
 11047 
       
 11048 			u = tinymce._addVer(u);
 12781 			u = tinymce._addVer(u);
 11049 
 12782 
 11050 			try {
 12783 			try {
 11051 				if (isIE && mo) {
 12784 				if (isIE && mo) {
 11052 					w = 1;
 12785 					w = 1;
 11091 		// Internal functions
 12824 		// Internal functions
 11092 
 12825 
 11093 		_decode : function(s) {
 12826 		_decode : function(s) {
 11094 			return tinymce.DOM.decode(s).replace(/\\n/g, '\n');
 12827 			return tinymce.DOM.decode(s).replace(/\\n/g, '\n');
 11095 		}
 12828 		}
 11096 
 12829 	});
       
 12830 }(tinymce));(function(tinymce) {
       
 12831 	tinymce.CommandManager = function() {
       
 12832 		var execCommands = {}, queryStateCommands = {}, queryValueCommands = {};
       
 12833 
       
 12834 		function add(collection, cmd, func, scope) {
       
 12835 			if (typeof(cmd) == 'string')
       
 12836 				cmd = [cmd];
       
 12837 
       
 12838 			tinymce.each(cmd, function(cmd) {
       
 12839 				collection[cmd.toLowerCase()] = {func : func, scope : scope};
       
 12840 			});
       
 12841 		};
       
 12842 
       
 12843 		tinymce.extend(this, {
       
 12844 			add : function(cmd, func, scope) {
       
 12845 				add(execCommands, cmd, func, scope);
       
 12846 			},
       
 12847 
       
 12848 			addQueryStateHandler : function(cmd, func, scope) {
       
 12849 				add(queryStateCommands, cmd, func, scope);
       
 12850 			},
       
 12851 
       
 12852 			addQueryValueHandler : function(cmd, func, scope) {
       
 12853 				add(queryValueCommands, cmd, func, scope);
       
 12854 			},
       
 12855 
       
 12856 			execCommand : function(scope, cmd, ui, value, args) {
       
 12857 				if (cmd = execCommands[cmd.toLowerCase()]) {
       
 12858 					if (cmd.func.call(scope || cmd.scope, ui, value, args) !== false)
       
 12859 						return true;
       
 12860 				}
       
 12861 			},
       
 12862 
       
 12863 			queryCommandValue : function() {
       
 12864 				if (cmd = queryValueCommands[cmd.toLowerCase()])
       
 12865 					return cmd.func.call(scope || cmd.scope, ui, value, args);
       
 12866 			},
       
 12867 
       
 12868 			queryCommandState : function() {
       
 12869 				if (cmd = queryStateCommands[cmd.toLowerCase()])
       
 12870 					return cmd.func.call(scope || cmd.scope, ui, value, args);
       
 12871 			}
 11097 		});
 12872 		});
 11098 }());
 12873 	};
       
 12874 
       
 12875 	tinymce.GlobalCommands = new tinymce.CommandManager();
       
 12876 })(tinymce);(function(tinymce) {
       
 12877 	function processRange(dom, start, end, callback) {
       
 12878 		var ancestor, n, startPoint, endPoint, sib;
       
 12879 
       
 12880 		function findEndPoint(n, c) {
       
 12881 			do {
       
 12882 				if (n.parentNode == c)
       
 12883 					return n;
       
 12884 
       
 12885 				n = n.parentNode;
       
 12886 			} while(n);
       
 12887 		};
       
 12888 
       
 12889 		function process(n) {
       
 12890 			callback(n);
       
 12891 			tinymce.walk(n, callback, 'childNodes');
       
 12892 		};
       
 12893 
       
 12894 		// Find common ancestor and end points
       
 12895 		ancestor = dom.findCommonAncestor(start, end);
       
 12896 		startPoint = findEndPoint(start, ancestor) || start;
       
 12897 		endPoint = findEndPoint(end, ancestor) || end;
       
 12898 
       
 12899 		// Process left leaf
       
 12900 		for (n = start; n && n != startPoint; n = n.parentNode) {
       
 12901 			for (sib = n.nextSibling; sib; sib = sib.nextSibling)
       
 12902 				process(sib);
       
 12903 		}
       
 12904 
       
 12905 		// Process middle from start to end point
       
 12906 		if (startPoint != endPoint) {
       
 12907 			for (n = startPoint.nextSibling; n && n != endPoint; n = n.nextSibling)
       
 12908 				process(n);
       
 12909 		} else
       
 12910 			process(startPoint);
       
 12911 
       
 12912 		// Process right leaf
       
 12913 		for (n = end; n && n != endPoint; n = n.parentNode) {
       
 12914 			for (sib = n.previousSibling; sib; sib = sib.previousSibling)
       
 12915 				process(sib);
       
 12916 		}
       
 12917 	};
       
 12918 
       
 12919 	tinymce.GlobalCommands.add('RemoveFormat', function() {
       
 12920 		var ed = this, dom = ed.dom, s = ed.selection, r = s.getRng(1), nodes = [], bm, start, end, sc, so, ec, eo, n;
       
 12921 
       
 12922 		function findFormatRoot(n) {
       
 12923 			var sp;
       
 12924 
       
 12925 			dom.getParent(n, function(n) {
       
 12926 				if (dom.is(n, ed.getParam('removeformat_selector')))
       
 12927 					sp = n;
       
 12928 
       
 12929 				return dom.isBlock(n);
       
 12930 			}, ed.getBody());
       
 12931 
       
 12932 			return sp;
       
 12933 		};
       
 12934 
       
 12935 		function collect(n) {
       
 12936 			if (dom.is(n, ed.getParam('removeformat_selector')))
       
 12937 				nodes.push(n);
       
 12938 		};
       
 12939 
       
 12940 		function walk(n) {
       
 12941 			collect(n);
       
 12942 			tinymce.walk(n, collect, 'childNodes');
       
 12943 		};
       
 12944 
       
 12945 		bm = s.getBookmark();
       
 12946 		sc = r.startContainer;
       
 12947 		ec = r.endContainer;
       
 12948 		so = r.startOffset;
       
 12949 		eo = r.endOffset;
       
 12950 		sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc;
       
 12951 		ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec;
       
 12952 
       
 12953 		// Same container
       
 12954 		if (sc == ec) { // TEXT_NODE
       
 12955 			start = findFormatRoot(sc);
       
 12956 
       
 12957 			// Handle single text node
       
 12958 			if (sc.nodeType == 3) {
       
 12959 				if (start && start.nodeType == 1) { // ELEMENT
       
 12960 					n = sc.splitText(so);
       
 12961 					n.splitText(eo - so);
       
 12962 					dom.split(start, n);
       
 12963 
       
 12964 					s.moveToBookmark(bm);
       
 12965 				}
       
 12966 
       
 12967 				return;
       
 12968 			}
       
 12969 
       
 12970 			// Handle single element
       
 12971 			walk(dom.split(start, sc) || sc);
       
 12972 		} else {
       
 12973 			// Find start/end format root
       
 12974 			start = findFormatRoot(sc);
       
 12975 			end = findFormatRoot(ec);
       
 12976 
       
 12977 			// Split start text node
       
 12978 			if (start) {
       
 12979 				if (sc.nodeType == 3) { // TEXT
       
 12980 					// Since IE doesn't support white space nodes in the DOM we need to
       
 12981 					// add this invisible character so that the splitText function can split the contents
       
 12982 					if (so == sc.nodeValue.length)
       
 12983 						sc.nodeValue += '\uFEFF'; // Yet another pesky IE fix
       
 12984 
       
 12985 					sc = sc.splitText(so);
       
 12986 				}
       
 12987 			}
       
 12988 
       
 12989 			// Split end text node
       
 12990 			if (end) {
       
 12991 				if (ec.nodeType == 3) // TEXT
       
 12992 					ec.splitText(eo);
       
 12993 			}
       
 12994 
       
 12995 			// If the start and end format root is the same then we need to wrap
       
 12996 			// the end node in a span since the split calls might change the reference
       
 12997 			// Example: <p><b><em>x[yz<span>---</span>12]3</em></b></p>
       
 12998 			if (start && start == end)
       
 12999 				dom.replace(dom.create('span', {id : '__end'}, ec.cloneNode(true)), ec);
       
 13000 
       
 13001 			// Split all start containers down to the format root
       
 13002 			if (start)
       
 13003 				start = dom.split(start, sc);
       
 13004 			else
       
 13005 				start = sc;
       
 13006 
       
 13007 			// If there is a span wrapper use that one instead
       
 13008 			if (n = dom.get('__end')) {
       
 13009 				ec = n;
       
 13010 				end = findFormatRoot(ec);
       
 13011 			}
       
 13012 
       
 13013 			// Split all end containers down to the format root
       
 13014 			if (end)
       
 13015 				end = dom.split(end, ec);
       
 13016 			else
       
 13017 				end = ec;
       
 13018 
       
 13019 			// Collect nodes in between
       
 13020 			processRange(dom, start, end, collect);
       
 13021 
       
 13022 			// Remove invisible character for IE workaround if we find it
       
 13023 			if (sc.nodeValue == '\uFEFF')
       
 13024 				sc.nodeValue = '';
       
 13025 
       
 13026 			// Process start/end container elements
       
 13027 			walk(ec);
       
 13028 			walk(sc);
       
 13029 		}
       
 13030 
       
 13031 		// Remove all collected nodes
       
 13032 		tinymce.each(nodes, function(n) {
       
 13033 			dom.remove(n, 1);
       
 13034 		});
       
 13035 
       
 13036 		// Remove leftover wrapper
       
 13037 		dom.remove('__end', 1);
       
 13038 
       
 13039 		s.moveToBookmark(bm);
       
 13040 	});
       
 13041 })(tinymce);
       
 13042 (function(tinymce) {
       
 13043 	tinymce.GlobalCommands.add('mceBlockQuote', function() {
       
 13044 		var ed = this, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;
       
 13045 
       
 13046 		function getBQ(e) {
       
 13047 			return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
       
 13048 		};
       
 13049 
       
 13050 		// Get start/end block
       
 13051 		sb = dom.getParent(s.getStart(), dom.isBlock);
       
 13052 		eb = dom.getParent(s.getEnd(), dom.isBlock);
       
 13053 
       
 13054 		// Remove blockquote(s)
       
 13055 		if (bq = getBQ(sb)) {
       
 13056 			if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
       
 13057 				bm = s.getBookmark();
       
 13058 
       
 13059 			// Move all elements after the end block into new bq
       
 13060 			if (getBQ(eb)) {
       
 13061 				bq2 = bq.cloneNode(false);
       
 13062 
       
 13063 				while (n = eb.nextSibling)
       
 13064 					bq2.appendChild(n.parentNode.removeChild(n));
       
 13065 			}
       
 13066 
       
 13067 			// Add new bq after
       
 13068 			if (bq2)
       
 13069 				dom.insertAfter(bq2, bq);
       
 13070 
       
 13071 			// Move all selected blocks after the current bq
       
 13072 			nl = s.getSelectedBlocks(sb, eb);
       
 13073 			for (i = nl.length - 1; i >= 0; i--) {
       
 13074 				dom.insertAfter(nl[i], bq);
       
 13075 			}
       
 13076 
       
 13077 			// Empty bq, then remove it
       
 13078 			if (/^\s*$/.test(bq.innerHTML))
       
 13079 				dom.remove(bq, 1); // Keep children so boomark restoration works correctly
       
 13080 
       
 13081 			// Empty bq, then remote it
       
 13082 			if (bq2 && /^\s*$/.test(bq2.innerHTML))
       
 13083 				dom.remove(bq2, 1); // Keep children so boomark restoration works correctly
       
 13084 
       
 13085 			if (!bm) {
       
 13086 				// Move caret inside empty block element
       
 13087 				if (!tinymce.isIE) {
       
 13088 					r = ed.getDoc().createRange();
       
 13089 					r.setStart(sb, 0);
       
 13090 					r.setEnd(sb, 0);
       
 13091 					s.setRng(r);
       
 13092 				} else {
       
 13093 					s.select(sb);
       
 13094 					s.collapse(0);
       
 13095 
       
 13096 					// IE misses the empty block some times element so we must move back the caret
       
 13097 					if (dom.getParent(s.getStart(), dom.isBlock) != sb) {
       
 13098 						r = s.getRng();
       
 13099 						r.move('character', -1);
       
 13100 						r.select();
       
 13101 					}
       
 13102 				}
       
 13103 			} else
       
 13104 				ed.selection.moveToBookmark(bm);
       
 13105 
       
 13106 			return;
       
 13107 		}
       
 13108 
       
 13109 		// Since IE can start with a totally empty document we need to add the first bq and paragraph
       
 13110 		if (tinymce.isIE && !sb && !eb) {
       
 13111 			ed.getDoc().execCommand('Indent');
       
 13112 			n = getBQ(s.getNode());
       
 13113 			n.style.margin = n.dir = ''; // IE adds margin and dir to bq
       
 13114 			return;
       
 13115 		}
       
 13116 
       
 13117 		if (!sb || !eb)
       
 13118 			return;
       
 13119 
       
 13120 		// If empty paragraph node then do not use bookmark
       
 13121 		if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
       
 13122 			bm = s.getBookmark();
       
 13123 
       
 13124 		// Move selected block elements into a bq
       
 13125 		tinymce.each(s.getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {
       
 13126 			// Found existing BQ add to this one
       
 13127 			if (e.nodeName == 'BLOCKQUOTE' && !bq) {
       
 13128 				bq = e;
       
 13129 				return;
       
 13130 			}
       
 13131 
       
 13132 			// No BQ found, create one
       
 13133 			if (!bq) {
       
 13134 				bq = dom.create('blockquote');
       
 13135 				e.parentNode.insertBefore(bq, e);
       
 13136 			}
       
 13137 
       
 13138 			// Add children from existing BQ
       
 13139 			if (e.nodeName == 'BLOCKQUOTE' && bq) {
       
 13140 				n = e.firstChild;
       
 13141 
       
 13142 				while (n) {
       
 13143 					bq.appendChild(n.cloneNode(true));
       
 13144 					n = n.nextSibling;
       
 13145 				}
       
 13146 
       
 13147 				dom.remove(e);
       
 13148 				return;
       
 13149 			}
       
 13150 
       
 13151 			// Add non BQ element to BQ
       
 13152 			bq.appendChild(dom.remove(e));
       
 13153 		});
       
 13154 
       
 13155 		if (!bm) {
       
 13156 			// Move caret inside empty block element
       
 13157 			if (!tinymce.isIE) {
       
 13158 				r = ed.getDoc().createRange();
       
 13159 				r.setStart(sb, 0);
       
 13160 				r.setEnd(sb, 0);
       
 13161 				s.setRng(r);
       
 13162 			} else {
       
 13163 				s.select(sb);
       
 13164 				s.collapse(1);
       
 13165 			}
       
 13166 		} else
       
 13167 			s.moveToBookmark(bm);
       
 13168 	});
       
 13169 })(tinymce);
       
 13170 (function(tinymce) {
       
 13171 	tinymce.each(['Cut', 'Copy', 'Paste'], function(cmd) {
       
 13172 		tinymce.GlobalCommands.add(cmd, function() {
       
 13173 			var ed = this, doc = ed.getDoc();
       
 13174 
       
 13175 			try {
       
 13176 				doc.execCommand(cmd, false, null);
       
 13177 
       
 13178 				// On WebKit the command will just be ignored if it's not enabled
       
 13179 				if (!doc.queryCommandEnabled(cmd))
       
 13180 					throw 'Error';
       
 13181 			} catch (ex) {
       
 13182 				if (tinymce.isGecko) {
       
 13183 					ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {
       
 13184 						if (s)
       
 13185 							open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', '_blank');
       
 13186 					});
       
 13187 				} else
       
 13188 					ed.windowManager.alert(ed.getLang('clipboard_no_support'));
       
 13189 			}
       
 13190 		});
       
 13191 	});
       
 13192 })(tinymce);
       
 13193 (function(tinymce) {
       
 13194 	tinymce.GlobalCommands.add('InsertHorizontalRule', function() {
       
 13195 		if (tinymce.isOpera)
       
 13196 			return this.getDoc().execCommand('InsertHorizontalRule', false, '');
       
 13197 
       
 13198 		this.selection.setContent('<hr />');
       
 13199 	});
       
 13200 })(tinymce);
       
 13201 (function() {
       
 13202 	var cmds = tinymce.GlobalCommands;
       
 13203 
       
 13204 	cmds.add(['mceEndUndoLevel', 'mceAddUndoLevel'], function() {
       
 13205 		this.undoManager.add();
       
 13206 	});
       
 13207 
       
 13208 	cmds.add('Undo', function() {
       
 13209 		var ed = this;
       
 13210 
       
 13211 		if (ed.settings.custom_undo_redo) {
       
 13212 			ed.undoManager.undo();
       
 13213 			ed.nodeChanged();
       
 13214 			return true;
       
 13215 		}
       
 13216 
       
 13217 		return false; // Run browser command
       
 13218 	});
       
 13219 
       
 13220 	cmds.add('Redo', function() {
       
 13221 		var ed = this;
       
 13222 
       
 13223 		if (ed.settings.custom_undo_redo) {
       
 13224 			ed.undoManager.redo();
       
 13225 			ed.nodeChanged();
       
 13226 			return true;
       
 13227 		}
       
 13228 
       
 13229 		return false; // Run browser command
       
 13230 	});
       
 13231 })();