includes/clientside/tinymce/tiny_mce_src.js
changeset 335 67bd3121a12e
parent 117 7cfdbb2fd17a
child 395 fa4c5ecb7c9a
equal deleted inserted replaced
334:c72b545f1304 335:67bd3121a12e
     1 
     1 
     2 /* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */
     2 /* file:jscripts/tiny_mce/classes/tinymce.js */
     3 
     3 
     4 function TinyMCE_Engine() {
     4 var tinymce = {
     5 	var ua;
     5 	majorVersion : '3',
     6 
     6 	minorVersion : '0b3',
     7 	this.majorVersion = "2";
     7 	releaseDate : '2007-12-14',
     8 	this.minorVersion = "1.0";
     8 
     9 	this.releaseDate = "2007-02-13";
     9 	_init : function() {
    10 
    10 		var t = this, ua = navigator.userAgent, i, nl, n, base;
    11 	this.instances = new Array();
    11 
    12 	this.switchClassCache = new Array();
    12 		// Browser checks
    13 	this.windowArgs = new Array();
    13 		t.isOpera = window.opera && opera.buildNumber;
    14 	this.loadedFiles = new Array();
    14 		t.isWebKit = /WebKit/.test(ua);
    15 	this.pendingFiles = new Array();
    15 		t.isOldWebKit = t.isWebKit && !window.getSelection().getRangeAt;
    16 	this.loadingIndex = 0;
    16 		t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(navigator.appName);
    17 	this.configs = new Array();
    17 		t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
    18 	this.currentConfig = 0;
    18 		t.isGecko = !t.isWebKit && /Gecko/.test(ua);
    19 	this.eventHandlers = new Array();
    19 //		t.isGecko3 = t.isGecko && /(Firefox|Minefield)\/[3-9]/.test(ua);
    20 	this.log = new Array();
    20 		t.isMac = ua.indexOf('Mac') != -1;
    21 	this.undoLevels = [];
    21 
    22 	this.undoIndex = 0;
    22 		// TinyMCE .NET webcontrol might be setting the values for TinyMCE
    23 	this.typingUndoIndex = -1;
    23 		if (window.tinyMCEPreInit) {
    24 
    24 			t.suffix = tinyMCEPreInit.suffix;
    25 	// Browser check
    25 			t.baseURL = tinyMCEPreInit.base;
    26 	ua = navigator.userAgent;
       
    27 	this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
       
    28 	this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1);
       
    29 	this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);
       
    30 	this.isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1);
       
    31 	this.isGecko = ua.indexOf('Gecko') != -1;
       
    32 	this.isSafari = ua.indexOf('Safari') != -1;
       
    33 	this.isOpera = ua.indexOf('Opera') != -1;
       
    34 	this.isMac = ua.indexOf('Mac') != -1;
       
    35 	this.isNS7 = ua.indexOf('Netscape/7') != -1;
       
    36 	this.isNS71 = ua.indexOf('Netscape/7.1') != -1;
       
    37 	this.dialogCounter = 0;
       
    38 	this.plugins = new Array();
       
    39 	this.themes = new Array();
       
    40 	this.menus = new Array();
       
    41 	this.loadedPlugins = new Array();
       
    42 	this.buttonMap = new Array();
       
    43 	this.isLoaded = false;
       
    44 
       
    45 	// Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those
       
    46 	if (this.isOpera) {
       
    47 		this.isMSIE = true;
       
    48 		this.isGecko = false;
       
    49 		this.isSafari =  false;
       
    50 	}
       
    51 
       
    52 	this.isIE = this.isMSIE;
       
    53 	this.isRealIE = this.isMSIE && !this.isOpera;
       
    54 
       
    55 	// TinyMCE editor id instance counter
       
    56 	this.idCounter = 0;
       
    57 };
       
    58 
       
    59 TinyMCE_Engine.prototype = {
       
    60 	init : function(settings) {
       
    61 		var theme, nl, baseHREF = "", i;
       
    62 
       
    63 		// IE 5.0x is no longer supported since 5.5, 6.0 and 7.0 now exists. We can't support old browsers forever, sorry.
       
    64 		if (this.isMSIE5_0)
       
    65 			return;
    26 			return;
    66 
    27 		}
    67 		this.settings = settings;
    28 
    68 
    29 		// Get suffix and base
    69 		// Check if valid browser has execcommand support
    30 		t.suffix = '';
    70 		if (typeof(document.execCommand) == 'undefined')
    31 
       
    32 		// If base element found, add that infront of baseURL
       
    33 		nl = document.getElementsByTagName('base');
       
    34 		for (i=0; i<nl.length; i++) {
       
    35 			if (nl[i].href)
       
    36 				base = nl[i].href;
       
    37 		}
       
    38 
       
    39 		function getBase(n) {
       
    40 			if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) {
       
    41 				if (/_(src|dev)\.js/g.test(n.src))
       
    42 					t.suffix = '_src';
       
    43 
       
    44 				t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
       
    45 
       
    46 				// If path to script is relative and a base href was found add that one infront
       
    47 				if (base && t.baseURL.indexOf('://') == -1)
       
    48 					t.baseURL = base + t.baseURL;
       
    49 
       
    50 				return t.baseURL;
       
    51 			}
       
    52 
       
    53 			return null;
       
    54 		};
       
    55 
       
    56 		// Check document
       
    57 		nl = document.getElementsByTagName('script');
       
    58 		for (i=0; i<nl.length; i++) {
       
    59 			if (getBase(nl[i]))
       
    60 				return;
       
    61 		}
       
    62 
       
    63 		// Check head
       
    64 		n = document.getElementsByTagName('head')[0];
       
    65 		if (n) {
       
    66 			nl = n.getElementsByTagName('script');
       
    67 			for (i=0; i<nl.length; i++) {
       
    68 				if (getBase(nl[i]))
       
    69 					return;
       
    70 			}
       
    71 		}
       
    72 
       
    73 		return;
       
    74 	},
       
    75 
       
    76 	is : function(o, t) {
       
    77 		var n = typeof(o);
       
    78 
       
    79 		if (!t)
       
    80 			return n != 'undefined';
       
    81 
       
    82 		if (t == 'array' && (o instanceof Array))
       
    83 			return true;
       
    84 
       
    85 		return n == t;
       
    86 	},
       
    87 
       
    88 	// #if !jquery
       
    89 
       
    90 	each : function(o, cb, s) {
       
    91 		var n, l;
       
    92 
       
    93 		if (!o)
       
    94 			return 0;
       
    95 
       
    96 		s = s || o;
       
    97 
       
    98 		if (typeof(o.length) != 'undefined') {
       
    99 			// Indexed arrays, needed for Safari
       
   100 			for (n=0, l = o.length; n<l; n++) {
       
   101 				if (cb.call(s, o[n], n, o) === false)
       
   102 					return 0;
       
   103 			}
       
   104 		} else {
       
   105 			// Hashtables
       
   106 			for (n in o) {
       
   107 				if (o.hasOwnProperty(n)) {
       
   108 					if (cb.call(s, o[n], n, o) === false)
       
   109 						return 0;
       
   110 				}
       
   111 			}
       
   112 		}
       
   113 
       
   114 		return 1;
       
   115 	},
       
   116 
       
   117 	map : function(a, f) {
       
   118 		var o = [];
       
   119 
       
   120 		tinymce.each(a, function(v) {
       
   121 			o.push(f(v));
       
   122 		});
       
   123 
       
   124 		return o;
       
   125 	},
       
   126 
       
   127 	grep : function(a, f) {
       
   128 		var o = [];
       
   129 
       
   130 		tinymce.each(a, function(v) {
       
   131 			if (!f || f(v))
       
   132 				o.push(v);
       
   133 		});
       
   134 
       
   135 		return o;
       
   136 	},
       
   137 
       
   138 	inArray : function(a, v) {
       
   139 		var i, l;
       
   140 
       
   141 		if (a) {
       
   142 			for (i = 0, l = a.length; i < l; i++) {
       
   143 				if (a[i] === v)
       
   144 					return i;
       
   145 			}
       
   146 		}
       
   147 
       
   148 		return -1;
       
   149 	},
       
   150 
       
   151 	extend : function(o, e) {
       
   152 		var i, a = arguments;
       
   153 
       
   154 		for (i=1; i<a.length; i++) {
       
   155 			e = a[i];
       
   156 
       
   157 			tinymce.each(e, function(v, n) {
       
   158 				if (typeof(v) !== 'undefined')
       
   159 					o[n] = v;
       
   160 			});
       
   161 		}
       
   162 
       
   163 		return o;
       
   164 	},
       
   165 
       
   166 	trim : function(s) {
       
   167 		return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');
       
   168 	},
       
   169 
       
   170 	// #endif
       
   171 
       
   172 	create : function(s, p) {
       
   173 		var t = this, sp, ns, cn, scn, c, de = 0;
       
   174 
       
   175 		// Parse : <prefix> <class>:<super class>
       
   176 		s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
       
   177 		cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name
       
   178 
       
   179 		// Create namespace for new class
       
   180 		ns = t.createNS(s[3].replace(/\.\w+$/, ''));
       
   181 
       
   182 		// Class already exists
       
   183 		if (ns[cn])
    71 			return;
   184 			return;
    72 
   185 
    73 		// Get script base path
   186 		// Make pure static class
    74 		if (!tinyMCE.baseURL) {
   187 		if (s[2] == 'static') {
    75 			var elements = document.getElementsByTagName('script');
   188 			ns[cn] = p;
    76 
   189 
    77 			// If base element found, add that infront of baseURL
   190 			if (this.onCreate)
    78 			nl = document.getElementsByTagName('base');
   191 				this.onCreate(s[2], s[3], ns[cn]);
    79 			for (i=0; i<nl.length; i++) {
   192 
    80 				if (nl[i].href)
   193 			return;
    81 					baseHREF = nl[i].href;
       
    82 			}
       
    83 
       
    84 			for (var i=0; i<elements.length; i++) {
       
    85 				if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_dev.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) {
       
    86 					var src = elements[i].src;
       
    87 
       
    88 					tinyMCE.srcMode = (src.indexOf('_src') != -1 || src.indexOf('_dev') != -1) ? '_src' : '';
       
    89 					tinyMCE.gzipMode = src.indexOf('_gzip') != -1;
       
    90 					src = src.substring(0, src.lastIndexOf('/'));
       
    91 
       
    92 					if (settings.exec_mode == "src" || settings.exec_mode == "normal")
       
    93 						tinyMCE.srcMode = settings.exec_mode == "src" ? '_src' : '';
       
    94 
       
    95 					// Force it absolute if page has a base href
       
    96 					if (baseHREF != "" && src.indexOf('://') == -1)
       
    97 						tinyMCE.baseURL = baseHREF + src;
       
    98 					else
       
    99 						tinyMCE.baseURL = src;
       
   100 
       
   101 					break;
       
   102 				}
       
   103 			}
       
   104 		}
   194 		}
   105 
   195 
   106 		// Get document base path
   196 		// Create default constructor
   107 		this.documentBasePath = document.location.href;
   197 		if (!p[cn]) {
   108 		if (this.documentBasePath.indexOf('?') != -1)
   198 			p[cn] = function() {};
   109 			this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?'));
   199 			de = 1;
   110 		this.documentURL = this.documentBasePath;
       
   111 		this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.lastIndexOf('/'));
       
   112 
       
   113 		// If not HTTP absolute
       
   114 		if (tinyMCE.baseURL.indexOf('://') == -1 && tinyMCE.baseURL.charAt(0) != '/') {
       
   115 			// If site absolute
       
   116 			tinyMCE.baseURL = this.documentBasePath + "/" + tinyMCE.baseURL;
       
   117 		}
   200 		}
   118 
   201 
   119 		// Set default values on settings
   202 		// Add constructor and methods
   120 		this._def("mode", "none");
   203 		ns[cn] = p[cn];
   121 		this._def("theme", "advanced");
   204 		t.extend(ns[cn].prototype, p);
   122 		this._def("plugins", "", true);
   205 
   123 		this._def("language", "en");
   206 		// Extend
   124 		this._def("docs_language", this.settings['language']);
   207 		if (s[5]) {
   125 		this._def("elements", "");
   208 			sp = t.resolve(s[5]).prototype;
   126 		this._def("textarea_trigger", "mce_editable");
   209 			scn = s[5].match(/\.(\w+)$/i)[1]; // Class name
   127 		this._def("editor_selector", "");
   210 
   128 		this._def("editor_deselector", "mceNoEditor");
   211 			// Extend constructor
   129 		this._def("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[id|style|dir|class|align],-h2[id|style|dir|class|align],-h3[id|style|dir|class|align],-h4[id|style|dir|class|align],-h5[id|style|dir|class|align],-h6[id|style|dir|class|align],hr[class|style],-font[face|size|style|id|class|dir|color],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],cite[title|id|class|style|dir|lang],abbr[title|id|class|style|dir|lang],acronym[title|id|class|style|dir|lang],del[title|id|class|style|dir|lang|datetime|cite],ins[title|id|class|style|dir|lang|datetime|cite]");
   212 			c = ns[cn];
   130 		this._def("extended_valid_elements", "");
   213 			if (de) {
   131 		this._def("invalid_elements", "");
   214 				// Add passthrough constructor
   132 		this._def("encoding", "");
   215 				ns[cn] = function() {
   133 		this._def("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE_Engine.prototype.convertURL"));
   216 					return sp[scn].apply(this, arguments);
   134 		this._def("save_callback", "");
   217 				};
   135 		this._def("debug", false);
   218 			} else {
   136 		this._def("force_br_newlines", false);
   219 				// Add inherit constructor
   137 		this._def("force_p_newlines", true);
   220 				ns[cn] = function() {
   138 		this._def("add_form_submit_trigger", true);
   221 					this.parent = sp[scn];
   139 		this._def("relative_urls", true);
   222 					return c.apply(this, arguments);
   140 		this._def("remove_script_host", true);
   223 				};
   141 		this._def("focus_alert", true);
   224 			}
   142 		this._def("document_base_url", this.documentURL);
   225 			ns[cn].prototype[cn] = ns[cn];
   143 		this._def("visual", true);
   226 
   144 		this._def("visual_table_class", "mceVisualAid");
   227 			// Add super methods
   145 		this._def("setupcontent_callback", "");
   228 			t.each(sp, function(f, n) {
   146 		this._def("fix_content_duplication", true);
   229 				if (n != scn)
   147 		this._def("custom_undo_redo", true);
   230 					ns[cn].prototype[n] = sp[n];
   148 		this._def("custom_undo_redo_levels", -1);
   231 			});
   149 		this._def("custom_undo_redo_keyboard_shortcuts", true);
   232 
   150 		this._def("custom_undo_redo_restore_selection", true);
   233 			// Add overridden methods
   151 		this._def("custom_undo_redo_global", false);
   234 			t.each(p, function(f, n) {
   152 		this._def("verify_html", true);
   235 				// Extend methods if needed
   153 		this._def("apply_source_formatting", false);
   236 				if (sp[n]) {
   154 		this._def("directionality", "ltr");
   237 					ns[cn].prototype[n] = function() {
   155 		this._def("cleanup_on_startup", false);
   238 						this.parent = sp[n];
   156 		this._def("inline_styles", false);
   239 						return f.apply(this, arguments);
   157 		this._def("convert_newlines_to_brs", false);
   240 					};
   158 		this._def("auto_reset_designmode", true);
   241 				} else {
   159 		this._def("entities", "39,#39,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,34,quot,38,amp,60,lt,62,gt,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", true);
   242 					if (n != cn)
   160 		this._def("entity_encoding", "named");
   243 						ns[cn].prototype[n] = f;
   161 		this._def("cleanup_callback", "");
   244 				}
   162 		this._def("add_unload_trigger", true);
   245 			});
   163 		this._def("ask", false);
       
   164 		this._def("nowrap", false);
       
   165 		this._def("auto_resize", false);
       
   166 		this._def("auto_focus", false);
       
   167 		this._def("cleanup", true);
       
   168 		this._def("remove_linebreaks", true);
       
   169 		this._def("button_tile_map", false);
       
   170 		this._def("submit_patch", true);
       
   171 		this._def("browsers", "msie,safari,gecko,opera", true);
       
   172 		this._def("dialog_type", "window");
       
   173 		this._def("accessibility_warnings", true);
       
   174 		this._def("accessibility_focus", true);
       
   175 		this._def("merge_styles_invalid_parents", "");
       
   176 		this._def("force_hex_style_colors", true);
       
   177 		this._def("trim_span_elements", true);
       
   178 		this._def("convert_fonts_to_spans", false);
       
   179 		this._def("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">');
       
   180 		this._def("font_size_classes", '');
       
   181 		this._def("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large', true);
       
   182 		this._def("event_elements", 'a,img', true);
       
   183 		this._def("convert_urls", true);
       
   184 		this._def("table_inline_editing", false);
       
   185 		this._def("object_resizing", true);
       
   186 		this._def("custom_shortcuts", true);
       
   187 		this._def("convert_on_click", false);
       
   188 		this._def("content_css", '');
       
   189 		this._def("fix_list_elements", true);
       
   190 		this._def("fix_table_elements", false);
       
   191 		this._def("strict_loading_mode", ( ( IE ) ? true : true ) ); // document.contentType == 'application/xhtml+xml');
       
   192 		this._def("hidden_tab_class", '');
       
   193 		this._def("display_tab_class", '');
       
   194 		this._def("gecko_spellcheck", false);
       
   195 		this._def("hide_selects_on_submit", true);
       
   196 
       
   197 		// Force strict loading mode to false on non Gecko browsers
       
   198 		//if (this.isMSIE && !this.isOpera)
       
   199 		//	this.settings.strict_loading_mode = false;
       
   200 
       
   201 		// Browser check IE
       
   202 		if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)
       
   203 			return;
       
   204 
       
   205 		// Browser check Gecko
       
   206 		if (this.isGecko && this.settings['browsers'].indexOf('gecko') == -1)
       
   207 			return;
       
   208 
       
   209 		// Browser check Safari
       
   210 		if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)
       
   211 			return;
       
   212 
       
   213 		// Browser check Opera
       
   214 		if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)
       
   215 			return;
       
   216 
       
   217 		// If not super absolute make it so
       
   218 		baseHREF = tinyMCE.settings['document_base_url'];
       
   219 		var h = document.location.href;
       
   220 		var p = h.indexOf('://');
       
   221 		if (p > 0 && document.location.protocol != "file:") {
       
   222 			p = h.indexOf('/', p + 3);
       
   223 			h = h.substring(0, p);
       
   224 
       
   225 			if (baseHREF.indexOf('://') == -1)
       
   226 				baseHREF = h + baseHREF;
       
   227 
       
   228 			tinyMCE.settings['document_base_url'] = baseHREF;
       
   229 			tinyMCE.settings['document_base_prefix'] = h;
       
   230 		}
   246 		}
   231 
   247 
   232 		// Trim away query part
   248 		// Add static methods
   233 		if (baseHREF.indexOf('?') != -1)
   249 		t.each(p['static'], function(f, n) {
   234 			baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));
   250 			ns[cn][n] = f;
   235 
   251 		});
   236 		this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
   252 
   237 
   253 		if (this.onCreate)
   238 		theme = this.settings['theme'];
   254 			this.onCreate(s[2], s[3], ns[cn].prototype);
   239 		this.inlineStrict = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment';
       
   240 		this.inlineTransitional = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment';
       
   241 		this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';
       
   242 		this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i");
       
   243 		this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);
       
   244 		this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL
       
   245 		this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';
       
   246 		this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance');
       
   247 
       
   248 		// Theme url
       
   249 		this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;
       
   250 
       
   251 		if (!tinyMCE.isIE || tinyMCE.isOpera)
       
   252 			this.settings['force_br_newlines'] = false;
       
   253 
       
   254 		if (tinyMCE.getParam("popups_css", false)) {
       
   255 			var cssPath = tinyMCE.getParam("popups_css", "");
       
   256 
       
   257 			// Is relative
       
   258 			if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
       
   259 				this.settings['popups_css'] = this.documentBasePath + "/" + cssPath;
       
   260 			else
       
   261 				this.settings['popups_css'] = cssPath;
       
   262 		} else
       
   263 			this.settings['popups_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
       
   264 
       
   265 		if (tinyMCE.getParam("editor_css", false)) {
       
   266 			var cssPath = tinyMCE.getParam("editor_css", "");
       
   267 
       
   268 			// Is relative
       
   269 			if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
       
   270 				this.settings['editor_css'] = this.documentBasePath + "/" + cssPath;
       
   271 			else
       
   272 				this.settings['editor_css'] = cssPath;
       
   273 		} else {
       
   274 			if (this.settings.editor_css != '')
       
   275 				this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
       
   276 		}
       
   277 
       
   278 		if (tinyMCE.settings['debug']) {
       
   279 			var msg = "Debug: \n";
       
   280 
       
   281 			msg += "baseURL: " + this.baseURL + "\n";
       
   282 			msg += "documentBasePath: " + this.documentBasePath + "\n";
       
   283 			msg += "content_css: " + this.settings['content_css'] + "\n";
       
   284 			msg += "popups_css: " + this.settings['popups_css'] + "\n";
       
   285 			msg += "editor_css: " + this.settings['editor_css'] + "\n";
       
   286 
       
   287 			alert(msg);
       
   288 		}
       
   289 
       
   290 		// Only do this once
       
   291 		if (this.configs.length == 0) {
       
   292 			if (typeof(TinyMCECompressed) == "undefined") {
       
   293 				tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad);
       
   294 
       
   295 				if (tinyMCE.isRealIE) {
       
   296 					if (document.body)
       
   297 						tinyMCE.addEvent(document.body, "readystatechange", TinyMCE_Engine.prototype.onLoad);
       
   298 					else
       
   299 						tinyMCE.addEvent(document, "readystatechange", TinyMCE_Engine.prototype.onLoad);
       
   300 				}
       
   301 
       
   302 				tinyMCE.addEvent(window, "load", TinyMCE_Engine.prototype.onLoad);
       
   303 				tinyMCE._addUnloadEvents();
       
   304 			}
       
   305 		}
       
   306 
       
   307 		this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings['theme'] + '/editor_template' + tinyMCE.srcMode + '.js');
       
   308 		this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] +  '.js');
       
   309 		this.loadCSS(this.settings['editor_css']);
       
   310 
       
   311 		// Add plugins
       
   312 		var p = tinyMCE.getParam('plugins', '', true, ',');
       
   313 		if (p.length > 0) {
       
   314 			for (var i=0; i<p.length; i++) {
       
   315 				if (p[i].charAt(0) != '-')
       
   316 					this.loadScript(tinyMCE.baseURL + '/plugins/' + p[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');
       
   317 			}
       
   318 		}
       
   319 
       
   320 		// Setup entities
       
   321 		if (tinyMCE.getParam('entity_encoding') == 'named') {
       
   322 			settings['cleanup_entities'] = new Array();
       
   323 			var entities = tinyMCE.getParam('entities', '', true, ',');
       
   324 			for (var i=0; i<entities.length; i+=2)
       
   325 				settings['cleanup_entities']['c' + entities[i]] = entities[i+1];
       
   326 		}
       
   327 
       
   328 		// Save away this config
       
   329 		settings['index'] = this.configs.length;
       
   330 		this.configs[this.configs.length] = settings;
       
   331 
       
   332 		// Start loading first one in chain
       
   333 		this.loadNextScript();
       
   334 
       
   335 		// Force flicker free CSS backgrounds in IE
       
   336 		if (this.isIE && !this.isOpera) {
       
   337 			try {
       
   338 				document.execCommand('BackgroundImageCache', false, true);
       
   339 			} catch (e) {
       
   340 			}
       
   341 		}
       
   342 
       
   343 		// Setup XML encoding regexps
       
   344 		this.xmlEncodeAposRe = new RegExp('[<>&"\']', 'g');
       
   345 		this.xmlEncodeRe = new RegExp('[<>&"]', 'g');
       
   346 //		this.xmlEncodeEnts = {'&':'&amp;','"':'&quot;',"'":'&#39;','<':'&lt;','>':'&gt;'};
       
   347 	},
   255 	},
   348 
   256 
   349 	_addUnloadEvents : function() {
   257 	walk : function(o, f, n, s) {
   350 		if (tinyMCE.isIE) {
   258 		s = s || this;
   351 			if (tinyMCE.settings['add_unload_trigger']) {
   259 
   352 				tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler);
   260 		if (o) {
   353 				tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler);
   261 			if (n)
   354 			}
   262 				o = o[n];
   355 		} else {
   263 
   356 			if (tinyMCE.settings['add_unload_trigger'])
   264 			tinymce.each(o, function(o, i) {
   357 				tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);});
   265 				if (f.call(s, o, i, n) === false)
       
   266 					return false;
       
   267 
       
   268 				tinymce.walk(o, f, n, s);
       
   269 			});
   358 		}
   270 		}
   359 	},
   271 	},
   360 
   272 
   361 	_def : function(key, def_val, t) {
   273 	createNS : function(n, o) {
   362 		var v = tinyMCE.getParam(key, def_val);
   274 		var i, v;
   363 
   275 
   364 		v = t ? v.replace(/\s+/g, "") : v;
   276 		o = o || window;
   365 
   277 
   366 		this.settings[key] = v;
   278 		n = n.split('.');
       
   279 		for (i=0; i<n.length; i++) {
       
   280 			v = n[i];
       
   281 
       
   282 			if (!o[v])
       
   283 				o[v] = {};
       
   284 
       
   285 			o = o[v];
       
   286 		}
       
   287 
       
   288 		return o;
   367 	},
   289 	},
   368 
   290 
   369 	hasPlugin : function(n) {
   291 	resolve : function(n, o) {
   370 		return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null;
   292 		var i, l;
       
   293 
       
   294 		o = o || window;
       
   295 
       
   296 		n = n.split('.');
       
   297 		for (i=0, l = n.length; i<l; i++) {
       
   298 			o = o[n[i]];
       
   299 
       
   300 			if (!o)
       
   301 				break;
       
   302 		}
       
   303 
       
   304 		return o;
   371 	},
   305 	},
   372 
   306 
   373 	addPlugin : function(n, p) {
   307 	addUnload : function(f, s) {
   374 		var op = this.plugins[n];
   308 		var t = this, w = window, unload;
   375 
   309 
   376 		// Use the previous plugin object base URL used when loading external plugins
   310 		f = {func : f, scope : s || this};
   377 		p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n;
   311 
   378 		this.plugins[n] = p;
   312 		if (!t.unloads) {
   379 
   313 			unload = function() {
   380 		this.loadNextScript();
   314 				var li = t.unloads, o, n;
       
   315 
       
   316 				// Call unload handlers
       
   317 				for (n in li) {
       
   318 					o = li[n];
       
   319 
       
   320 					if (o && o.func)
       
   321 						o.func.call(o.scope);
       
   322 				}
       
   323 
       
   324 				// Detach unload function
       
   325 				if (w.detachEvent)
       
   326 					w.detachEvent('onunload', unload);
       
   327 				else if (w.removeEventListener)
       
   328 					w.removeEventListener('unload', unload, false);
       
   329 
       
   330 				// Destroy references
       
   331 				o = li = w = unload = null;
       
   332 
       
   333 				// Run garbarge collector on IE
       
   334 				if (window.CollectGarbage)
       
   335 					window.CollectGarbage();
       
   336 			};
       
   337 
       
   338 			// Attach unload handler
       
   339 			if (w.attachEvent)
       
   340 				w.attachEvent('onunload', unload);
       
   341 			else if (w.addEventListener)
       
   342 				w.addEventListener('unload', unload, false);
       
   343 
       
   344 			// Setup initial unload handler array
       
   345 			t.unloads = [f];
       
   346 		} else
       
   347 			t.unloads.push(f);
       
   348 
       
   349 		return f;
   381 	},
   350 	},
   382 
   351 
   383 	setPluginBaseURL : function(n, u) {
   352 	removeUnload : function(f) {
   384 		var op = this.plugins[n];
   353 		var u = this.unloads, r = null;
   385 
   354 
   386 		if (op)
   355 		tinymce.each(u, function(o, i) {
   387 			op.baseURL = u;
   356 			if (o && o.func == f) {
   388 		else
   357 				u.splice(i, 1);
   389 			this.plugins[n] = {baseURL : u};
   358 				r = f;
       
   359 				return false;
       
   360 			}
       
   361 		});
       
   362 
       
   363 		return r;
       
   364 	}
       
   365 
       
   366 	};
       
   367 
       
   368 // Required for GZip AJAX loading
       
   369 window.tinymce = tinymce;
       
   370 
       
   371 // Initialize the API
       
   372 tinymce._init();
       
   373 
       
   374 /* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */
       
   375 
       
   376 
       
   377 /* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */
       
   378 
       
   379 
       
   380 /* file:jscripts/tiny_mce/classes/util/Dispatcher.js */
       
   381 
       
   382 tinymce.create('tinymce.util.Dispatcher', {
       
   383 	scope : null,
       
   384 	listeners : null,
       
   385 
       
   386 	Dispatcher : function(s) {
       
   387 		this.scope = s || this;
       
   388 		this.listeners = [];
   390 	},
   389 	},
   391 
   390 
   392 	loadPlugin : function(n, u) {
   391 	add : function(cb, s) {
   393 		u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u;
   392 		this.listeners.push({cb : cb, scope : s || this.scope});
   394 		u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u;
   393 
   395 		this.plugins[n] = {baseURL : u};
   394 		return cb;
   396 		this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js");
       
   397 	},
   395 	},
   398 
   396 
   399 	hasTheme : function(n) {
   397 	addToTop : function(cb, s) {
   400 		return typeof(this.themes[n]) != "undefined" && this.themes[n] != null;
   398 		this.listeners.unshift({cb : cb, scope : s || this.scope});
       
   399 
       
   400 		return cb;
   401 	},
   401 	},
   402 
   402 
   403 	addTheme : function(n, t) {
   403 	remove : function(cb) {
   404 		this.themes[n] = t;
   404 		var l = this.listeners, o = null;
   405 
   405 
   406 		this.loadNextScript();
   406 		tinymce.each(l, function(c, i) {
       
   407 			if (cb == c.cb) {
       
   408 				o = cb;
       
   409 				l.splice(i, 1);
       
   410 				return false;
       
   411 			}
       
   412 		});
       
   413 
       
   414 		return o;
   407 	},
   415 	},
   408 
   416 
   409 	addMenu : function(n, m) {
   417 	dispatch : function() {
   410 		this.menus[n] = m;
   418 		var s, a = arguments;
   411 	},
   419 
   412 
   420 		tinymce.each(this.listeners, function(c) {
   413 	hasMenu : function(n) {
   421 			return s = c.cb.apply(c.scope, a);
   414 		return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null;
   422 		});
   415 	},
   423 
   416 
   424 		return s;
   417 	loadScript : function(url) {
   425 	}
   418 		var i;
   426 
   419 
   427 	});
   420 		for (i=0; i<this.loadedFiles.length; i++) {
   428 
   421 			if (this.loadedFiles[i] == url)
   429 /* file:jscripts/tiny_mce/classes/util/URI.js */
       
   430 
       
   431 (function() {
       
   432 	var each = tinymce.each;
       
   433 
       
   434 	tinymce.create('tinymce.util.URI', {
       
   435 		URI : function(u, s) {
       
   436 			var t = this, o, a, b;
       
   437 
       
   438 			// Default settings
       
   439 			s = t.settings = s || {};
       
   440 
       
   441 			// Strange app protocol or local anchor
       
   442 			if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {
       
   443 				t.source = u;
   422 				return;
   444 				return;
   423 		}
   445 			}
   424 
   446 
   425 		if (tinyMCE.settings.strict_loading_mode)
   447 			// Absolute path with no host, fake host and protocol
   426 			this.pendingFiles[this.pendingFiles.length] = url;
   448 			if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
   427 		else
   449 				u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
   428     {
   450 
   429       document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>');
   451 			// Relative path
   430     }
   452 			if (u.indexOf('://') === -1 && u.indexOf('//') !== 0)
   431 
   453 				u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
   432 		this.loadedFiles[this.loadedFiles.length] = url;
   454 
   433 	},
   455 			// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
   434 
   456 			u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
   435 	loadNextScript : function() {
   457 			each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
   436 		var d = document, se;
   458 				t[v] = u[i];
   437 
   459 			});
   438 		if (!tinyMCE.settings.strict_loading_mode)
   460 
   439 			return;
   461 			if (b = s.base_uri) {
   440 
   462 				if (!t.protocol)
   441 		if (this.loadingIndex < this.pendingFiles.length) {
   463 					t.protocol = b.protocol;
   442       try {
   464 
   443         /*
   465 				if (!t.userInfo)
   444         se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script');
   466 					t.userInfo = b.userInfo;
   445         se.setAttribute('language', 'javascript');
   467 
   446         se.setAttribute('type', 'text/javascript');
   468 				if (!t.port && t.host == 'mce_host')
   447         se.setAttribute('src', this.pendingFiles[this.loadingIndex++]);
   469 					t.port = b.port;
   448         */
   470 
   449         
   471 				if (!t.host || t.host == 'mce_host')
   450         se = d.createElement('script');
   472 					t.host = b.host;
   451         se.language = 'javascript';
   473 
   452         se.type = 'text/javascript';
   474 				t.source = '';
   453         se.src = this.pendingFiles[this.loadingIndex++];
   475 			}
   454   
   476 
   455         d.getElementsByTagName("head")[0].appendChild(se);
   477 			//t.path = t.path || '/';
   456       } catch(e) {
   478 		},
   457         var error = e.toString();
   479 
   458         alert(error);
   480 		setPath : function(p) {
   459       }
   481 			var t = this;
   460 		} else
   482 
   461 			this.loadingIndex = -1; // Done with loading
   483 			p = /^(.*?)\/?(\w+)?$/.exec(p);
   462 	},
   484 
   463 
   485 			// Update path parts
   464 	loadCSS : function(url) {
   486 			t.path = p[0];
   465 		var ar = url.replace(/\s+/, '').split(',');
   487 			t.directory = p[1];
   466 		var lflen = 0, csslen = 0;
   488 			t.file = p[2];
   467 		var skip = false;
   489 
   468 		var x = 0, i = 0, nl, le;
   490 			// Rebuild source
   469 
   491 			t.source = '';
   470 		for (x = 0,csslen = ar.length; x<csslen; x++) {
   492 			t.getURI();
   471 			if (ar[x] != null && ar[x] != 'null' && ar[x].length > 0) {
   493 		},
   472 				/* Make sure it doesn't exist. */
   494 
   473 				for (i=0, lflen=this.loadedFiles.length; i<lflen; i++) {
   495 		toRelative : function(u) {
   474 					if (this.loadedFiles[i] == ar[x]) {
   496 			var t = this, o;
   475 						skip = true;
   497 
       
   498 			u = new tinymce.util.URI(u, {base_uri : t});
       
   499 
       
   500 			// Not on same domain/port or protocol
       
   501 			if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)
       
   502 				return u.getURI();
       
   503 
       
   504 			o = t.toRelPath(t.path, u.path);
       
   505 
       
   506 			// Add query
       
   507 			if (u.query)
       
   508 				o += '?' + u.query;
       
   509 
       
   510 			// Add anchor
       
   511 			if (u.anchor)
       
   512 				o += '#' + u.anchor;
       
   513 
       
   514 			return o;
       
   515 		},
       
   516 	
       
   517 		toAbsolute : function(u, nh) {
       
   518 			var u = new tinymce.util.URI(u, {base_uri : this});
       
   519 
       
   520 			return u.getURI(this.host == u.host ? nh : 0);
       
   521 		},
       
   522 
       
   523 		toRelPath : function(base, path) {
       
   524 			var items, bp = 0, out = '', i;
       
   525 
       
   526 			// Split the paths
       
   527 			base = base.substring(0, base.lastIndexOf('/'));
       
   528 			base = base.split('/');
       
   529 			items = path.split('/');
       
   530 
       
   531 			if (base.length >= items.length) {
       
   532 				for (i = 0; i < base.length; i++) {
       
   533 					if (i >= items.length || base[i] != items[i]) {
       
   534 						bp = i + 1;
   476 						break;
   535 						break;
   477 					}
   536 					}
   478 				}
   537 				}
   479 
   538 			}
   480 				if (!skip) {
   539 
   481 					if (tinyMCE.settings.strict_loading_mode) {
   540 			if (base.length < items.length) {
   482 						nl = document.getElementsByTagName("head");
   541 				for (i = 0; i < items.length; i++) {
   483 
   542 					if (i >= base.length || base[i] != items[i]) {
   484 						le = document.createElement('link');
   543 						bp = i + 1;
   485 						le.setAttribute('href', ar[x]);
       
   486 						le.setAttribute('rel', 'stylesheet');
       
   487 						le.setAttribute('type', 'text/css');
       
   488 
       
   489 						nl[0].appendChild(le);			
       
   490 					} else
       
   491           {
       
   492             document.write('<link href="' + ar[x] + '" rel="stylesheet" type="text/css" />');
       
   493           }
       
   494 
       
   495 					this.loadedFiles[this.loadedFiles.length] = ar[x];
       
   496 				}
       
   497 			}
       
   498 		}
       
   499 	},
       
   500 
       
   501 	importCSS : function(doc, css) {
       
   502 		var css_ary = css.replace(/\s+/, '').split(',');
       
   503 		var csslen, elm, headArr, x, css_file;
       
   504 
       
   505 		for (x = 0, csslen = css_ary.length; x<csslen; x++) {
       
   506 			css_file = css_ary[x];
       
   507 
       
   508 			if (css_file != null && css_file != 'null' && css_file.length > 0) {
       
   509 				// Is relative, make absolute
       
   510 				if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/')
       
   511 					css_file = this.documentBasePath + "/" + css_file;
       
   512 
       
   513 				if (typeof(doc.createStyleSheet) == "undefined") {
       
   514 					elm = doc.createElement("link");
       
   515 
       
   516 					elm.rel = "stylesheet";
       
   517 					elm.href = css_file;
       
   518 
       
   519 					if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0)
       
   520 						headArr[0].appendChild(elm);
       
   521 				} else
       
   522 					doc.createStyleSheet(css_file);
       
   523 			}
       
   524 		}
       
   525 	},
       
   526 
       
   527 	confirmAdd : function(e, settings) {
       
   528 		var elm = tinyMCE.isIE ? event.srcElement : e.target;
       
   529 		var elementId = elm.name ? elm.name : elm.id;
       
   530 
       
   531 		tinyMCE.settings = settings;
       
   532 
       
   533 		if (tinyMCE.settings['convert_on_click'] || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm'])))
       
   534 			tinyMCE.addMCEControl(elm, elementId);
       
   535 
       
   536 		elm.setAttribute('mce_noask', 'true');
       
   537 	},
       
   538 
       
   539 	updateContent : function(form_element_name) {
       
   540 		// Find MCE instance linked to given form element and copy it's value
       
   541 		var formElement = document.getElementById(form_element_name);
       
   542 		for (var n in tinyMCE.instances) {
       
   543 			var inst = tinyMCE.instances[n];
       
   544 			if (!tinyMCE.isInstance(inst))
       
   545 				continue;
       
   546 
       
   547 			inst.switchSettings();
       
   548 
       
   549 			if (inst.formElement == formElement) {
       
   550 				var doc = inst.getDoc();
       
   551 		
       
   552 				tinyMCE._setHTML(doc, inst.formElement.value);
       
   553 
       
   554 				if (!tinyMCE.isIE)
       
   555 					doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid);
       
   556 			}
       
   557 		}
       
   558 	},
       
   559 
       
   560 	addMCEControl : function(replace_element, form_element_name, target_document) {
       
   561 		var id = "mce_editor_" + tinyMCE.idCounter++;
       
   562     
       
   563     var inst = new TinyMCE_Control(tinyMCE.settings);
       
   564 
       
   565 		inst.editorId = id;
       
   566 		this.instances[id] = inst;
       
   567 
       
   568 		inst._onAdd(replace_element, form_element_name, target_document);
       
   569 	},
       
   570 
       
   571 	removeInstance : function(ti) {
       
   572 		var t = [], n, i;
       
   573 
       
   574 		// Remove from instances
       
   575 		for (n in tinyMCE.instances) {
       
   576 			i = tinyMCE.instances[n];
       
   577 
       
   578 			if (tinyMCE.isInstance(i) && ti != i)
       
   579 					t[n] = i;
       
   580 		}
       
   581 
       
   582 		tinyMCE.instances = t;
       
   583 
       
   584 		// Remove from global undo/redo
       
   585 		n = [];
       
   586 		t = tinyMCE.undoLevels;
       
   587 
       
   588 		for (i=0; i<t.length; i++) {
       
   589 			if (t[i] != ti)
       
   590 				n.push(t[i]);
       
   591 		}
       
   592 
       
   593 		tinyMCE.undoLevels = n;
       
   594 		tinyMCE.undoIndex = n.length;
       
   595 
       
   596 		// Dispatch remove instance call
       
   597 		tinyMCE.dispatchCallback(ti, 'remove_instance_callback', 'removeInstance', ti);
       
   598 
       
   599 		return ti;
       
   600 	},
       
   601 
       
   602 	removeMCEControl : function(editor_id) {
       
   603 		var inst = tinyMCE.getInstanceById(editor_id), h, re, ot, tn;
       
   604 
       
   605 		if (inst) {
       
   606 			inst.switchSettings();
       
   607 
       
   608 			editor_id = inst.editorId;
       
   609 			h = tinyMCE.getContent(editor_id);
       
   610 
       
   611 			this.removeInstance(inst);
       
   612 
       
   613 			tinyMCE.selectedElement = null;
       
   614 			tinyMCE.selectedInstance = null;
       
   615 
       
   616 			// Remove element
       
   617 			re = document.getElementById(editor_id + "_parent");
       
   618 			ot = inst.oldTargetElement;
       
   619 			tn = ot.nodeName.toLowerCase();
       
   620 
       
   621 			if (tn == "textarea" || tn == "input") {
       
   622 				re.parentNode.removeChild(re);
       
   623 				ot.style.display = "inline";
       
   624 				ot.value = h;
       
   625 			} else {
       
   626 				ot.innerHTML = h;
       
   627 				ot.style.display = 'block';
       
   628 				re.parentNode.insertBefore(ot, re);
       
   629 				re.parentNode.removeChild(re);
       
   630 			}
       
   631 		}
       
   632 	},
       
   633 
       
   634 	triggerSave : function(skip_cleanup, skip_callback) {
       
   635 		var inst, n;
       
   636 
       
   637 		// Default to false
       
   638 		if (typeof(skip_cleanup) == "undefined")
       
   639 			skip_cleanup = false;
       
   640 
       
   641 		// Default to false
       
   642 		if (typeof(skip_callback) == "undefined")
       
   643 			skip_callback = false;
       
   644 
       
   645 		// Cleanup and set all form fields
       
   646 		for (n in tinyMCE.instances) {
       
   647 			inst = tinyMCE.instances[n];
       
   648 
       
   649 			if (!tinyMCE.isInstance(inst))
       
   650 				continue;
       
   651 
       
   652 			inst.triggerSave(skip_cleanup, skip_callback);
       
   653 		}
       
   654 	},
       
   655 
       
   656 	resetForm : function(form_index) {
       
   657 		var i, inst, n, formObj = document.forms[form_index];
       
   658 
       
   659 		for (n in tinyMCE.instances) {
       
   660 			inst = tinyMCE.instances[n];
       
   661 
       
   662 			if (!tinyMCE.isInstance(inst))
       
   663 				continue;
       
   664 
       
   665 			inst.switchSettings();
       
   666 
       
   667 			for (i=0; i<formObj.elements.length; i++) {
       
   668 				if (inst.formTargetElementId == formObj.elements[i].name)
       
   669 					inst.getBody().innerHTML = inst.startContent;
       
   670 			}
       
   671 		}
       
   672 	},
       
   673 
       
   674 	execInstanceCommand : function(editor_id, command, user_interface, value, focus) {
       
   675 		var inst = tinyMCE.getInstanceById(editor_id), r;
       
   676 
       
   677 		if (inst) {
       
   678 			r = inst.selection.getRng();
       
   679 
       
   680 			if (typeof(focus) == "undefined")
       
   681 				focus = true;
       
   682 
       
   683 			// IE bug lost focus on images in absolute divs Bug #1534575
       
   684 			if (focus && (!r || !r.item))
       
   685 				inst.contentWindow.focus();
       
   686 
       
   687 			// Reset design mode if lost
       
   688 			inst.autoResetDesignMode();
       
   689 
       
   690 			this.selectedElement = inst.getFocusElement();
       
   691 			inst.select();
       
   692 			tinyMCE.execCommand(command, user_interface, value);
       
   693 
       
   694 			// Cancel event so it doesn't call onbeforeonunlaod
       
   695 			if (tinyMCE.isIE && window.event != null)
       
   696 				tinyMCE.cancelEvent(window.event);
       
   697 		}
       
   698 	},
       
   699 
       
   700 	execCommand : function(command, user_interface, value) {
       
   701 		var inst = tinyMCE.selectedInstance;
       
   702 
       
   703 		// Default input
       
   704 		user_interface = user_interface ? user_interface : false;
       
   705 		value = value ? value : null;
       
   706 
       
   707 		if (inst)
       
   708 			inst.switchSettings();
       
   709 
       
   710 		switch (command) {
       
   711 			case "Undo":
       
   712 				if (this.getParam('custom_undo_redo_global')) {
       
   713 					if (this.undoIndex > 0) {
       
   714 						tinyMCE.nextUndoRedoAction = 'Undo';
       
   715 						inst = this.undoLevels[--this.undoIndex];
       
   716 						inst.select();
       
   717 
       
   718 						if (!tinyMCE.nextUndoRedoInstanceId)
       
   719 							inst.execCommand('Undo');
       
   720 					}
       
   721 				} else
       
   722 					inst.execCommand('Undo');
       
   723 				return true;
       
   724 
       
   725 			case "Redo":
       
   726 				if (this.getParam('custom_undo_redo_global')) {
       
   727 					if (this.undoIndex <= this.undoLevels.length - 1) {
       
   728 						tinyMCE.nextUndoRedoAction = 'Redo';
       
   729 						inst = this.undoLevels[this.undoIndex++];
       
   730 						inst.select();
       
   731 
       
   732 						if (!tinyMCE.nextUndoRedoInstanceId)
       
   733 							inst.execCommand('Redo');
       
   734 					}
       
   735 				} else
       
   736 					inst.execCommand('Redo');
       
   737 
       
   738 				return true;
       
   739 
       
   740 			case 'mceFocus':
       
   741 				var inst = tinyMCE.getInstanceById(value);
       
   742 				if (inst)
       
   743 					inst.getWin().focus();
       
   744 			return;
       
   745 
       
   746 			case "mceAddControl":
       
   747 			case "mceAddEditor":
       
   748 				tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
       
   749 				return;
       
   750 
       
   751 			case "mceAddFrameControl":
       
   752 				tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'], value['document']), value['element'], value['document']);
       
   753 				return;
       
   754 
       
   755 			case "mceRemoveControl":
       
   756 			case "mceRemoveEditor":
       
   757 				tinyMCE.removeMCEControl(value);
       
   758 				return;
       
   759 
       
   760 			case "mceToggleEditor":
       
   761 				var inst = tinyMCE.getInstanceById(value), pe, te;
       
   762 
       
   763 				if (inst) {
       
   764 					pe = document.getElementById(inst.editorId + '_parent');
       
   765 					te = inst.oldTargetElement;
       
   766 
       
   767 					if (typeof(inst.enabled) == 'undefined')
       
   768 						inst.enabled = true;
       
   769 
       
   770 					inst.enabled = !inst.enabled;
       
   771 
       
   772 					if (!inst.enabled) {
       
   773 						pe.style.display = 'none';
       
   774 						te.value = inst.getHTML();
       
   775 						te.style.display = inst.oldTargetDisplay;
       
   776 						tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst);
       
   777 					} else {
       
   778 						pe.style.display = 'block';
       
   779 						te.style.display = 'none';
       
   780 						inst.setHTML(te.value);
       
   781 						inst.useCSS = false;
       
   782 						tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst);
       
   783 					}
       
   784 				} else
       
   785 					tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
       
   786 
       
   787 				return;
       
   788 
       
   789 			case "mceResetDesignMode":
       
   790 				// Resets the designmode state of the editors in Gecko
       
   791 				if (!tinyMCE.isIE) {
       
   792 					for (var n in tinyMCE.instances) {
       
   793 						if (!tinyMCE.isInstance(tinyMCE.instances[n]))
       
   794 							continue;
       
   795 
       
   796 						try {
       
   797 							tinyMCE.instances[n].getDoc().designMode = "on";
       
   798 						} catch (e) {
       
   799 							// Ignore any errors
       
   800 						}
       
   801 					}
       
   802 				}
       
   803 
       
   804 				return;
       
   805 		}
       
   806 
       
   807 		if (inst) {
       
   808 			inst.execCommand(command, user_interface, value);
       
   809 		} else if (tinyMCE.settings['focus_alert'])
       
   810 			alert(tinyMCELang['lang_focus_alert']);
       
   811 	},
       
   812 
       
   813 	_createIFrame : function(replace_element, doc, win) {
       
   814 		var iframe, id = replace_element.getAttribute("id");
       
   815 		var aw, ah;
       
   816 
       
   817 		if (typeof(doc) == "undefined")
       
   818 			doc = document;
       
   819 
       
   820 		if (typeof(win) == "undefined")
       
   821 			win = window;
       
   822 
       
   823 		iframe = doc.createElement("iframe");
       
   824 
       
   825 		aw = "" + tinyMCE.settings['area_width'];
       
   826 		ah = "" + tinyMCE.settings['area_height'];
       
   827 
       
   828 		if (aw.indexOf('%') == -1) {
       
   829 			aw = parseInt(aw);
       
   830 			aw = (isNaN(aw) || aw < 0) ? 300 : aw;
       
   831 			aw = aw + "px";
       
   832 		}
       
   833 
       
   834 		if (ah.indexOf('%') == -1) {
       
   835 			ah = parseInt(ah);
       
   836 			ah = (isNaN(ah) || ah < 0) ? 240 : ah;
       
   837 			ah = ah + "px";
       
   838 		}
       
   839 
       
   840 		iframe.setAttribute("id", id);
       
   841 		iframe.setAttribute("name", id);
       
   842 		iframe.setAttribute("class", "mceEditorIframe");
       
   843 		iframe.setAttribute("border", "0");
       
   844 		iframe.setAttribute("frameBorder", "0");
       
   845 		iframe.setAttribute("marginWidth", "0");
       
   846 		iframe.setAttribute("marginHeight", "0");
       
   847 		iframe.setAttribute("leftMargin", "0");
       
   848 		iframe.setAttribute("topMargin", "0");
       
   849 		iframe.setAttribute("width", aw);
       
   850 		iframe.setAttribute("height", ah);
       
   851 		iframe.setAttribute("allowtransparency", "true");
       
   852 		iframe.className = 'mceEditorIframe';
       
   853 
       
   854 		if (tinyMCE.settings["auto_resize"])
       
   855 			iframe.setAttribute("scrolling", "no");
       
   856 
       
   857 		// Must have a src element in MSIE HTTPs breaks aswell as absoute URLs
       
   858 		if (tinyMCE.isRealIE)
       
   859 			iframe.setAttribute("src", this.settings['default_document']);
       
   860 
       
   861 		iframe.style.width = aw;
       
   862 		iframe.style.height = ah;
       
   863 
       
   864 		// Ugly hack for Gecko problem in strict mode
       
   865 		if (tinyMCE.settings.strict_loading_mode)
       
   866 			iframe.style.marginBottom = '-5px';
       
   867 
       
   868 		// MSIE 5.0 issue
       
   869 		if (tinyMCE.isRealIE)
       
   870 			replace_element.outerHTML = iframe.outerHTML;
       
   871 		else
       
   872 			replace_element.parentNode.replaceChild(iframe, replace_element);
       
   873 
       
   874 		if (tinyMCE.isRealIE)
       
   875 			return win.frames[id];
       
   876 		else
       
   877 			return iframe;
       
   878 	},
       
   879 
       
   880 	setupContent : function(editor_id) {
       
   881 		var inst = tinyMCE.instances[editor_id], i;
       
   882 		var doc = inst.getDoc();
       
   883 		var head = doc.getElementsByTagName('head').item(0);
       
   884 		var content = inst.startContent;
       
   885 
       
   886 		// HTML values get XML encoded in strict mode
       
   887 		if (tinyMCE.settings.strict_loading_mode) {
       
   888 			content = content.replace(/&lt;/g, '<');
       
   889 			content = content.replace(/&gt;/g, '>');
       
   890 			content = content.replace(/&quot;/g, '"');
       
   891 			content = content.replace(/&amp;/g, '&');
       
   892 		}
       
   893 
       
   894 		tinyMCE.selectedInstance = inst;
       
   895 		inst.switchSettings();
       
   896 
       
   897 		// Not loaded correctly hit it again, Mozilla bug #997860
       
   898 		if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") {
       
   899 			// This part will remove the designMode status
       
   900 			// Failes first time in Firefox 1.5b2 on Mac
       
   901 			try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {}
       
   902 			window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000);
       
   903 			return;
       
   904 		}
       
   905 
       
   906 		if (!head) {
       
   907 			window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10);
       
   908 			return;
       
   909 		}
       
   910 
       
   911 		// Import theme specific content CSS the user specific
       
   912 		tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css");
       
   913 		tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);
       
   914 		tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst);
       
   915 
       
   916 		// Setup keyboard shortcuts
       
   917 		if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) {
       
   918 			inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo');
       
   919 			inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo');
       
   920 		}
       
   921 
       
   922 		// BlockFormat shortcuts keys
       
   923 		for (i=1; i<=6; i++)
       
   924 			inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, '<h' + i + '>');
       
   925 
       
   926 		inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '<p>');
       
   927 		inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '<div>');
       
   928 		inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '<address>');
       
   929 
       
   930 		// Add default shortcuts for gecko
       
   931 		if (tinyMCE.isGecko) {
       
   932 			inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold');
       
   933 			inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic');
       
   934 			inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline');
       
   935 		}
       
   936 
       
   937 		// Setup span styles
       
   938 		if (tinyMCE.getParam("convert_fonts_to_spans"))
       
   939 			inst.getBody().setAttribute('id', 'mceSpanFonts');
       
   940 
       
   941 		if (tinyMCE.settings['nowrap'])
       
   942 			doc.body.style.whiteSpace = "nowrap";
       
   943 
       
   944 		doc.body.dir = this.settings['directionality'];
       
   945 		doc.editorId = editor_id;
       
   946 
       
   947 		// Add on document element in Mozilla
       
   948 		if (!tinyMCE.isIE)
       
   949 			doc.documentElement.editorId = editor_id;
       
   950 
       
   951 		inst.setBaseHREF(tinyMCE.settings['base_href']);
       
   952 
       
   953 		// Replace new line characters to BRs
       
   954 		if (tinyMCE.settings['convert_newlines_to_brs']) {
       
   955 			content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi");
       
   956 			content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi");
       
   957 			content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi");
       
   958 		}
       
   959 
       
   960 		// Open closed anchors
       
   961 	//	content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
       
   962 
       
   963 		// Call custom cleanup code
       
   964 		content = tinyMCE.storeAwayURLs(content);
       
   965 		content = tinyMCE._customCleanup(inst, "insert_to_editor", content);
       
   966 
       
   967 		if (tinyMCE.isIE) {
       
   968 			// Ugly!!!
       
   969 			window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500);
       
   970 
       
   971 			if (tinyMCE.settings["force_br_newlines"])
       
   972 				doc.styleSheets[0].addRule("p", "margin: 0;");
       
   973 
       
   974 			var body = inst.getBody();
       
   975 			body.editorId = editor_id;
       
   976 		}
       
   977 
       
   978 		content = tinyMCE.cleanupHTMLCode(content);
       
   979 
       
   980 		// Fix for bug #958637
       
   981 		if (!tinyMCE.isIE) {
       
   982 			var contentElement = inst.getDoc().createElement("body");
       
   983 			var doc = inst.getDoc();
       
   984 
       
   985 			contentElement.innerHTML = content;
       
   986 
       
   987 			// Remove weridness!
       
   988 			if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])
       
   989 				content = content.replace(new RegExp('&lt;&gt;', 'g'), "");
       
   990 
       
   991 			if (tinyMCE.settings['cleanup_on_startup'])
       
   992 				tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));
       
   993 			else
       
   994 				tinyMCE.setInnerHTML(inst.getBody(), content);
       
   995 
       
   996 			tinyMCE.convertAllRelativeURLs(inst.getBody());
       
   997 		} else {
       
   998 			if (tinyMCE.settings['cleanup_on_startup']) {
       
   999 				tinyMCE._setHTML(inst.getDoc(), content);
       
  1000 
       
  1001 				// Produces permission denied error in MSIE 5.5
       
  1002 				eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');
       
  1003 			} else
       
  1004 				tinyMCE._setHTML(inst.getDoc(), content);
       
  1005 		}
       
  1006 
       
  1007 		// Fix for bug #957681
       
  1008 		//inst.getDoc().designMode = inst.getDoc().designMode;
       
  1009 
       
  1010 		tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);
       
  1011 		tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc());
       
  1012 
       
  1013 		// Re-add design mode on mozilla
       
  1014 		if (!tinyMCE.isIE)
       
  1015 			tinyMCE.addEventHandlers(inst);
       
  1016 
       
  1017 		// Add blur handler
       
  1018 		if (tinyMCE.isIE) {
       
  1019 			tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch);
       
  1020 			tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953
       
  1021 
       
  1022 			// Workaround for drag drop/copy paste base href bug
       
  1023 			if (!tinyMCE.isOpera) {
       
  1024 				tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove);
       
  1025 				tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch);
       
  1026 				tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch);
       
  1027 			}
       
  1028 		}
       
  1029 
       
  1030 		// Trigger node change, this call locks buttons for tables and so forth
       
  1031 		inst.select();
       
  1032 		tinyMCE.selectedElement = inst.contentWindow.document.body;
       
  1033 
       
  1034 		// Call custom DOM cleanup
       
  1035 		tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody());
       
  1036 		tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody());
       
  1037 		tinyMCE._setEventsEnabled(inst.getBody(), false);
       
  1038 		tinyMCE.cleanupAnchors(inst.getDoc());
       
  1039 
       
  1040 		if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  1041 			tinyMCE.convertSpansToFonts(inst.getDoc());
       
  1042 
       
  1043 		inst.startContent = tinyMCE.trim(inst.getBody().innerHTML);
       
  1044 		inst.undoRedo.add({ content : inst.startContent });
       
  1045 
       
  1046 		// Cleanup any mess left from storyAwayURLs
       
  1047 		if (tinyMCE.isGecko) {
       
  1048 			// Remove mce_src from textnodes and comments
       
  1049 			tinyMCE.selectNodes(inst.getBody(), function(n) {
       
  1050 				if (n.nodeType == 3 || n.nodeType == 8)
       
  1051 					n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), "");
       
  1052 
       
  1053 				return false;
       
  1054 			});
       
  1055 		}
       
  1056 
       
  1057 		// Remove Gecko spellchecking
       
  1058 		if (tinyMCE.isGecko)
       
  1059 			inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck");
       
  1060 
       
  1061 		// Cleanup any mess left from storyAwayURLs
       
  1062 		tinyMCE._removeInternal(inst.getBody());
       
  1063 
       
  1064 		inst.select();
       
  1065 		tinyMCE.triggerNodeChange(false, true);
       
  1066 	},
       
  1067 
       
  1068 	storeAwayURLs : function(s) {
       
  1069 		// Remove all mce_src, mce_href and replace them with new ones
       
  1070 		// s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
       
  1071 		// s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
       
  1072 
       
  1073 		if (!s.match(/(mce_src|mce_href)/gi, s)) {
       
  1074 			s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"');
       
  1075 			s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"');
       
  1076 		}
       
  1077 
       
  1078 		return s;
       
  1079 	},
       
  1080 
       
  1081 	_removeInternal : function(n) {
       
  1082 		if (tinyMCE.isGecko) {
       
  1083 			// Remove mce_src from textnodes and comments
       
  1084 			tinyMCE.selectNodes(n, function(n) {
       
  1085 				if (n.nodeType == 3 || n.nodeType == 8)
       
  1086 					n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), "");
       
  1087 
       
  1088 				return false;
       
  1089 			});
       
  1090 		}
       
  1091 	},
       
  1092 
       
  1093 	removeTinyMCEFormElements : function(form_obj) {
       
  1094 		var i, elementId;
       
  1095 
       
  1096 		// Skip form element removal
       
  1097 		if (!tinyMCE.getParam('hide_selects_on_submit'))
       
  1098 			return;
       
  1099 
       
  1100 		// Check if form is valid
       
  1101 		if (typeof(form_obj) == "undefined" || form_obj == null)
       
  1102 			return;
       
  1103 
       
  1104 		// If not a form, find the form
       
  1105 		if (form_obj.nodeName != "FORM") {
       
  1106 			if (form_obj.form)
       
  1107 				form_obj = form_obj.form;
       
  1108 			else
       
  1109 				form_obj = tinyMCE.getParentElement(form_obj, "form");
       
  1110 		}
       
  1111 
       
  1112 		// Still nothing
       
  1113 		if (form_obj == null)
       
  1114 			return;
       
  1115 
       
  1116 		// Disable all UI form elements that TinyMCE created
       
  1117 		for (i=0; i<form_obj.elements.length; i++) {
       
  1118 			elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id;
       
  1119 
       
  1120 			if (elementId.indexOf('mce_editor_') == 0)
       
  1121 				form_obj.elements[i].disabled = true;
       
  1122 		}
       
  1123 	},
       
  1124 
       
  1125 	handleEvent : function(e) {
       
  1126 		var inst = tinyMCE.selectedInstance;
       
  1127 
       
  1128 		// Remove odd, error
       
  1129 		if (typeof(tinyMCE) == "undefined")
       
  1130 			return true;
       
  1131 
       
  1132 		//tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : ""));
       
  1133 
       
  1134 		if (tinyMCE.executeCallback(tinyMCE.selectedInstance, 'handle_event_callback', 'handleEvent', e))
       
  1135 			return false;
       
  1136 
       
  1137 		switch (e.type) {
       
  1138 			case "beforedeactivate": // Was added due to bug #1439953
       
  1139 			case "blur":
       
  1140 				if (tinyMCE.selectedInstance)
       
  1141 					tinyMCE.selectedInstance.execCommand('mceEndTyping');
       
  1142 
       
  1143 				tinyMCE.hideMenus();
       
  1144 
       
  1145 				return;
       
  1146 
       
  1147 			// Workaround for drag drop/copy paste base href bug
       
  1148 			case "drop":
       
  1149 			case "beforepaste":
       
  1150 				if (tinyMCE.selectedInstance)
       
  1151 					tinyMCE.selectedInstance.setBaseHREF(null);
       
  1152 
       
  1153 				// Fixes odd MSIE bug where drag/droping elements in a iframe with height 100% breaks
       
  1154 				// This logic forces the width/height to be in pixels while the user is drag/dropping
       
  1155 				if (tinyMCE.isRealIE) {
       
  1156 					var ife = tinyMCE.selectedInstance.iframeElement;
       
  1157 
       
  1158 					/*if (ife.style.width.indexOf('%') != -1) {
       
  1159 						ife._oldWidth = ife.width.height;
       
  1160 						ife.style.width = ife.clientWidth;
       
  1161 					}*/
       
  1162 
       
  1163 					if (ife.style.height.indexOf('%') != -1) {
       
  1164 						ife._oldHeight = ife.style.height;
       
  1165 						ife.style.height = ife.clientHeight;
       
  1166 					}
       
  1167 				}
       
  1168 
       
  1169 				window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings['base_href']);tinyMCE._resetIframeHeight();", 1);
       
  1170 				return;
       
  1171 
       
  1172 			case "submit":
       
  1173 				tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target);
       
  1174 				tinyMCE.triggerSave();
       
  1175 				tinyMCE.isNotDirty = true;
       
  1176 				return;
       
  1177 
       
  1178 			case "reset":
       
  1179 				var formObj = tinyMCE.isIE ? window.event.srcElement : e.target;
       
  1180 
       
  1181 				for (var i=0; i<document.forms.length; i++) {
       
  1182 					if (document.forms[i] == formObj)
       
  1183 						window.setTimeout('tinyMCE.resetForm(' + i + ');', 10);
       
  1184 				}
       
  1185 
       
  1186 				return;
       
  1187 
       
  1188 			case "keypress":
       
  1189 				if (inst && inst.handleShortcut(e))
       
  1190 					return false;
       
  1191 
       
  1192 				if (e.target.editorId) {
       
  1193 					tinyMCE.instances[e.target.editorId].select();
       
  1194 				} else {
       
  1195 					if (e.target.ownerDocument.editorId)
       
  1196 						tinyMCE.instances[e.target.ownerDocument.editorId].select();
       
  1197 				}
       
  1198 
       
  1199 				if (tinyMCE.selectedInstance)
       
  1200 					tinyMCE.selectedInstance.switchSettings();
       
  1201 
       
  1202 				// Insert P element
       
  1203 				if ((tinyMCE.isGecko || tinyMCE.isOpera || tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) {
       
  1204 					// Insert P element instead of BR
       
  1205 					if (TinyMCE_ForceParagraphs._insertPara(tinyMCE.selectedInstance, e)) {
       
  1206 						// Cancel event
       
  1207 						tinyMCE.execCommand("mceAddUndoLevel");
       
  1208 						return tinyMCE.cancelEvent(e);
       
  1209 					}
       
  1210 				}
       
  1211 
       
  1212 				// Handle backspace
       
  1213 				if ((tinyMCE.isGecko && !tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
       
  1214 					// Insert P element instead of BR
       
  1215 					if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
       
  1216 						// Cancel event
       
  1217 						tinyMCE.execCommand("mceAddUndoLevel");
       
  1218 						return tinyMCE.cancelEvent(e);
       
  1219 					}
       
  1220 				}
       
  1221 
       
  1222 				// Return key pressed
       
  1223 				if (tinyMCE.isIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) {
       
  1224 					if (e.target.editorId)
       
  1225 						tinyMCE.instances[e.target.editorId].select();
       
  1226 
       
  1227 					if (tinyMCE.selectedInstance) {
       
  1228 						var sel = tinyMCE.selectedInstance.getDoc().selection;
       
  1229 						var rng = sel.createRange();
       
  1230 
       
  1231 						if (tinyMCE.getParentElement(rng.parentElement(), "li") != null)
       
  1232 							return false;
       
  1233 
       
  1234 						// Cancel event
       
  1235 						e.returnValue = false;
       
  1236 						e.cancelBubble = true;
       
  1237 
       
  1238 						// Insert BR element
       
  1239 						rng.pasteHTML("<br />");
       
  1240 						rng.collapse(false);
       
  1241 						rng.select();
       
  1242 
       
  1243 						tinyMCE.execCommand("mceAddUndoLevel");
       
  1244 						tinyMCE.triggerNodeChange(false);
       
  1245 						return false;
       
  1246 					}
       
  1247 				}
       
  1248 
       
  1249 				// Backspace or delete
       
  1250 				if (e.keyCode == 8 || e.keyCode == 46) {
       
  1251 					tinyMCE.selectedElement = e.target;
       
  1252 					tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a");
       
  1253 					tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img");
       
  1254 					tinyMCE.triggerNodeChange(false);
       
  1255 				}
       
  1256 
       
  1257 				return false;
       
  1258 			break;
       
  1259 
       
  1260 			case "keyup":
       
  1261 			case "keydown":
       
  1262 				tinyMCE.hideMenus();
       
  1263 				tinyMCE.hasMouseMoved = false;
       
  1264 
       
  1265 				if (inst && inst.handleShortcut(e))
       
  1266 					return false;
       
  1267 
       
  1268 				if (e.target.editorId)
       
  1269 					tinyMCE.instances[e.target.editorId].select();
       
  1270 
       
  1271 				if (tinyMCE.selectedInstance)
       
  1272 					tinyMCE.selectedInstance.switchSettings();
       
  1273 
       
  1274 				var inst = tinyMCE.selectedInstance;
       
  1275 
       
  1276 				// Handle backspace
       
  1277 				if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
       
  1278 					// Insert P element instead of BR
       
  1279 					if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
       
  1280 						// Cancel event
       
  1281 						tinyMCE.execCommand("mceAddUndoLevel");
       
  1282 						e.preventDefault();
       
  1283 						return false;
       
  1284 					}
       
  1285 				}
       
  1286 
       
  1287 				tinyMCE.selectedElement = null;
       
  1288 				tinyMCE.selectedNode = null;
       
  1289 				var elm = tinyMCE.selectedInstance.getFocusElement();
       
  1290 				tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a");
       
  1291 				tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img");
       
  1292 				tinyMCE.selectedElement = elm;
       
  1293 
       
  1294 				// Update visualaids on tabs
       
  1295 				if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)
       
  1296 					tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);
       
  1297 
       
  1298 				// Fix empty elements on return/enter, check where enter occured
       
  1299 				if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13)
       
  1300 					tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement();
       
  1301 
       
  1302 				// Fix empty elements on return/enter
       
  1303 				if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) {
       
  1304 					var elm = tinyMCE.enterKeyElement;
       
  1305 					if (elm) {
       
  1306 						var re = new RegExp('^HR|IMG|BR$','g'); // Skip these
       
  1307 						var dre = new RegExp('^H[1-6]$','g'); // Add double on these
       
  1308 
       
  1309 						if (!elm.hasChildNodes() && !re.test(elm.nodeName)) {
       
  1310 							if (dre.test(elm.nodeName))
       
  1311 								elm.innerHTML = "&nbsp;&nbsp;";
       
  1312 							else
       
  1313 								elm.innerHTML = "&nbsp;";
       
  1314 						}
       
  1315 					}
       
  1316 				}
       
  1317 
       
  1318 				// Check if it's a position key
       
  1319 				var keys = tinyMCE.posKeyCodes;
       
  1320 				var posKey = false;
       
  1321 				for (var i=0; i<keys.length; i++) {
       
  1322 					if (keys[i] == e.keyCode) {
       
  1323 						posKey = true;
       
  1324 						break;
   544 						break;
  1325 					}
   545 					}
  1326 				}
   546 				}
  1327 
   547 			}
  1328 				// MSIE custom key handling
   548 
  1329 				if (tinyMCE.isIE && tinyMCE.settings['custom_undo_redo']) {
   549 			if (bp == 1)
  1330 					var keys = new Array(8,46); // Backspace,Delete
   550 				return path;
  1331 
   551 
  1332 					for (var i=0; i<keys.length; i++) {
   552 			for (i = 0; i < base.length - (bp - 1); i++)
  1333 						if (keys[i] == e.keyCode) {
   553 				out += "../";
  1334 							if (e.type == "keyup")
   554 
  1335 								tinyMCE.triggerNodeChange(false);
   555 			for (i = bp - 1; i < items.length; i++) {
  1336 						}
   556 				if (i != bp - 1)
  1337 					}
   557 					out += "/" + items[i];
  1338 				}
   558 				else
  1339 
   559 					out += items[i];
  1340 				// If Ctrl key
   560 			}
  1341 				if (e.keyCode == 17)
   561 
  1342 					return true;
   562 			return out;
  1343 
   563 		},
  1344 				// Handle Undo/Redo when typing content
   564 
  1345 
   565 		toAbsPath : function(base, path) {
  1346 				if (tinyMCE.isGecko) {
   566 			var i, nb = 0, o = [];
  1347 					// Start typing (not a position key or ctrl key, but ctrl+x and ctrl+p is ok)
   567 
  1348 					if (!posKey && e.type == "keyup" && !e.ctrlKey || (e.ctrlKey && (e.keyCode == 86 || e.keyCode == 88)))
   568 			// Split paths
  1349 						tinyMCE.execCommand("mceStartTyping");
   569 			base = base.split('/');
  1350 				} else {
   570 			path = path.split('/');
  1351 					// IE seems to be working better with this setting
   571 
  1352 					if (!posKey && e.type == "keyup")
   572 			// Remove empty chunks
  1353 						tinyMCE.execCommand("mceStartTyping");
   573 			each(base, function(k) {
  1354 				}
   574 				if (k)
  1355 
   575 					o.push(k);
  1356 				// Store undo bookmark
   576 			});
  1357 				if (e.type == "keydown" && (posKey || e.ctrlKey) && inst)
   577 
  1358 					inst.undoBookmark = inst.selection.getBookmark();
   578 			base = o;
  1359 
   579 
  1360 				// End typing (position key) or some Ctrl event
   580 			// Merge relURLParts chunks
  1361 				if (e.type == "keyup" && (posKey || e.ctrlKey))
   581 			for (i = path.length - 1, o = []; i >= 0; i--) {
  1362 					tinyMCE.execCommand("mceEndTyping");
   582 				// Ignore empty or .
  1363 
   583 				if (path[i].length == 0 || path[i] == ".")
  1364 				if (posKey && e.type == "keyup")
   584 					continue;
  1365 					tinyMCE.triggerNodeChange(false);
   585 
  1366 
   586 				// Is parent
  1367 				if (tinyMCE.isIE && e.ctrlKey)
   587 				if (path[i] == '..') {
  1368 					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
   588 					nb++;
  1369 			break;
   589 					continue;
  1370 
   590 				}
  1371 			case "mousedown":
   591 
  1372 			case "mouseup":
   592 				// Move up
  1373 			case "click":
   593 				if (nb > 0) {
  1374 			case "dblclick":
   594 					nb--;
  1375 			case "focus":
   595 					continue;
  1376 				tinyMCE.hideMenus();
   596 				}
  1377 
   597 
  1378 				if (tinyMCE.selectedInstance) {
   598 				o.push(path[i]);
  1379 					tinyMCE.selectedInstance.switchSettings();
   599 			}
  1380 					tinyMCE.selectedInstance.isFocused = true;
   600 
  1381 				}
   601 			i = base.length - nb;
  1382 
   602 
  1383 				// Check instance event trigged on
   603 			// If /a/b/c or /
  1384 				var targetBody = tinyMCE.getParentElement(e.target, "html");
   604 			if (i <= 0)
  1385 				for (var instanceName in tinyMCE.instances) {
   605 				return '/' + o.reverse().join('/');
  1386 					if (!tinyMCE.isInstance(tinyMCE.instances[instanceName]))
   606 
  1387 						continue;
   607 			return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');
  1388 
   608 		},
  1389 					var inst = tinyMCE.instances[instanceName];
   609 
  1390 
   610 		getURI : function(nh) {
  1391 					// Reset design mode if lost (on everything just in case)
   611 			var s, t = this;
  1392 					inst.autoResetDesignMode();
   612 
  1393 
   613 			// Rebuild source
  1394 					// Use HTML element since users might click outside of body element
   614 			if (!t.source || nh) {
  1395 					if (inst.getBody().parentNode == targetBody) {
   615 				s = '';
  1396 						inst.select();
   616 
  1397 						tinyMCE.selectedElement = e.target;
   617 				if (!nh) {
  1398 						tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
   618 					if (t.protocol)
  1399 						tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img");
   619 						s += t.protocol + '://';
  1400 						break;
   620 
  1401 					}
   621 					if (t.userInfo)
  1402 				}
   622 						s += t.userInfo + '@';
  1403 
   623 
  1404 				// Add first bookmark location
   624 					if (t.host)
  1405 				if (!tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark && (e.type == "mouseup" || e.type == "dblclick"))
   625 						s += t.host;
  1406 					tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark = tinyMCE.selectedInstance.selection.getBookmark();
   626 
  1407 
   627 					if (t.port)
  1408 				// Reset selected node
   628 						s += ':' + t.port;
  1409 				if (e.type != "focus")
   629 				}
  1410 					tinyMCE.selectedNode = null;
   630 
  1411 
   631 				if (t.path)
  1412 				tinyMCE.triggerNodeChange(false);
   632 					s += t.path;
  1413 				tinyMCE.execCommand("mceEndTyping");
   633 
  1414 
   634 				if (t.query)
  1415 				if (e.type == "mouseup")
   635 					s += '?' + t.query;
  1416 					tinyMCE.execCommand("mceAddUndoLevel");
   636 
  1417 
   637 				if (t.anchor)
  1418 				// Just in case
   638 					s += '#' + t.anchor;
  1419 				if (!tinyMCE.selectedInstance && e.target.editorId)
   639 
  1420 					tinyMCE.instances[e.target.editorId].select();
   640 				t.source = s;
  1421 
   641 			}
  1422 				return false;
   642 
  1423 			break;
   643 			return t.source;
  1424 		}
   644 		}
       
   645 
       
   646 		});
       
   647 })();
       
   648 
       
   649 /* file:jscripts/tiny_mce/classes/util/Cookie.js */
       
   650 
       
   651 (function() {
       
   652 	var each = tinymce.each;
       
   653 
       
   654 	tinymce.create('static tinymce.util.Cookie', {
       
   655 		getHash : function(n) {
       
   656 			var v = this.get(n), h;
       
   657 
       
   658 			if (v) {
       
   659 				each(v.split('&'), function(v) {
       
   660 					v = v.split('=');
       
   661 					h = h || {};
       
   662 					h[unescape(v[0])] = unescape(v[1]);
       
   663 				});
       
   664 			}
       
   665 
       
   666 			return h;
       
   667 		},
       
   668 
       
   669 		setHash : function(n, v, e, p, d, s) {
       
   670 			var o = '';
       
   671 
       
   672 			each(v, function(v, k) {
       
   673 				o += (!o ? '' : '&') + escape(k) + '=' + escape(v);
       
   674 			});
       
   675 
       
   676 			this.set(n, o, e, p, d, s);
       
   677 		},
       
   678 
       
   679 		get : function(n) {
       
   680 			var c = document.cookie, e, p = n + "=", b = c.indexOf("; " + p);
       
   681 
       
   682 			if (b == -1) {
       
   683 				b = c.indexOf(p);
       
   684 
       
   685 				if (b != 0)
       
   686 					return null;
       
   687 			} else
       
   688 				b += 2;
       
   689 
       
   690 			e = c.indexOf(";", b);
       
   691 
       
   692 			if (e == -1)
       
   693 				e = c.length;
       
   694 
       
   695 			return unescape(c.substring(b + p.length, e));
       
   696 		},
       
   697 
       
   698 		set : function(n, v, e, p, d, s) {
       
   699 			document.cookie = n + "=" + escape(v) +
       
   700 				((e) ? "; expires=" + e.toGMTString() : "") +
       
   701 				((p) ? "; path=" + escape(p) : "") +
       
   702 				((d) ? "; domain=" + d : "") +
       
   703 				((s) ? "; secure" : "");
       
   704 		},
       
   705 
       
   706 		remove : function(n, p) {
       
   707 			var d = new Date();
       
   708 
       
   709 			d.setTime(d.getTime() - 1000);
       
   710 
       
   711 			this.set(n, '', d, p, d);
       
   712 		}
       
   713 
       
   714 		});
       
   715 })();
       
   716 
       
   717 /* file:jscripts/tiny_mce/classes/util/JSON.js */
       
   718 
       
   719 tinymce.create('static tinymce.util.JSON', {
       
   720 	serialize : function(o) {
       
   721 		var i, v, s = tinymce.util.JSON.serialize, t;
       
   722 
       
   723 		if (o == null)
       
   724 			return 'null';
       
   725 
       
   726 		t = typeof o;
       
   727 
       
   728 		if (t == 'string') {
       
   729 			v = '\bb\tt\nn\ff\rr\""\'\'\\\\';
       
   730 
       
   731 			return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g, function(a, b) {
       
   732 				i = v.indexOf(b);
       
   733 
       
   734 				if (i + 1)
       
   735 					return '\\' + v.charAt(i + 1);
       
   736 
       
   737 				a = b.charCodeAt().toString(16);
       
   738 
       
   739 				return '\\u' + '0000'.substring(a.length) + a;
       
   740 			}) + '"';
       
   741 		}
       
   742 
       
   743 		if (t == 'object') {
       
   744 			if (o instanceof Array) {
       
   745 					for (i=0, v = '['; i<o.length; i++)
       
   746 						v += (i > 0 ? ',' : '') + s(o[i]);
       
   747 
       
   748 					return v + ']';
       
   749 				}
       
   750 
       
   751 				v = '{';
       
   752 
       
   753 				for (i in o)
       
   754 					v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';
       
   755 
       
   756 				return v + '}';
       
   757 		}
       
   758 
       
   759 		return '' + o;
  1425 	},
   760 	},
  1426 
   761 
  1427 	getButtonHTML : function(id, lang, img, cmd, ui, val) {
   762 	parse : function(s) {
  1428 		var h = '', m, x, io = '';
       
  1429 
       
  1430 		cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\'';
       
  1431 
       
  1432 		if (typeof(ui) != "undefined" && ui != null)
       
  1433 			cmd += ',' + ui;
       
  1434 
       
  1435 		if (typeof(val) != "undefined" && val != null)
       
  1436 			cmd += ",'" + val + "'";
       
  1437 
       
  1438 		cmd += ');';
       
  1439 
       
  1440 		// Patch for IE7 bug with hover out not restoring correctly
       
  1441 		if (tinyMCE.isRealIE)
       
  1442 			io = 'onmouseover="tinyMCE.lastHover = this;"';
       
  1443 
       
  1444 		// Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled
       
  1445 		if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = this.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) {
       
  1446 			// Tiled button
       
  1447 			x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20);
       
  1448 			h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceTiledButton mceButtonNormal" target="_self">';
       
  1449 			h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" title="{$' + lang + '}" />';
       
  1450 			h += '</a>';
       
  1451 		} else {
       
  1452 			// Normal button
       
  1453 			h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceButtonNormal" target="_self">';
       
  1454 			h += '<img src="' + img + '" title="{$' + lang + '}" />';
       
  1455 			h += '</a>';
       
  1456 		}
       
  1457 
       
  1458 		return h;
       
  1459 	},
       
  1460 
       
  1461 	getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) {
       
  1462 		var h = '', m, x;
       
  1463 
       
  1464 		mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');';
       
  1465 		cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\'';
       
  1466 
       
  1467 		if (typeof(ui) != "undefined" && ui != null)
       
  1468 			cmd += ',' + ui;
       
  1469 
       
  1470 		if (typeof(val) != "undefined" && val != null)
       
  1471 			cmd += ",'" + val + "'";
       
  1472 
       
  1473 		cmd += ');';
       
  1474 
       
  1475 		// Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled
       
  1476 		if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) {
       
  1477 			x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20);
       
  1478 
       
  1479 			if (tinyMCE.isRealIE)
       
  1480 				h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">';
       
  1481 			else
       
  1482 				h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton">';
       
  1483 
       
  1484 			h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceTiledButton mceMenuButtonNormal" target="_self">';
       
  1485 			h += '<img src="{$themeurl}/images/spacer.gif" style="width: 20px; height: 20px; background-position: ' + x + 'px 0" title="{$' + lang + '}" /></a>';
       
  1486 			h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />';
       
  1487 			h += '</a></span>';
       
  1488 		} else {
       
  1489 			if (tinyMCE.isRealIE)
       
  1490 				h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">';
       
  1491 			else
       
  1492 				h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton">';
       
  1493 
       
  1494 			h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">';
       
  1495 			h += '<img src="' + img + '" title="{$' + lang + '}" /></a>';
       
  1496 			h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />';
       
  1497 			h += '</a></span>';
       
  1498 		}
       
  1499 
       
  1500 		return h;
       
  1501 	},
       
  1502 
       
  1503 	_menuButtonEvent : function(e, o) {
       
  1504 		if (o.className == 'mceMenuButtonFocus')
       
  1505 			return;
       
  1506 
       
  1507 		if (e == 'over')
       
  1508 			o.className = o.className + ' mceMenuHover';
       
  1509 		else
       
  1510 			o.className = o.className.replace(/\s.*$/, '');
       
  1511 	},
       
  1512 
       
  1513 	addButtonMap : function(m) {
       
  1514 		var i, a = m.replace(/\s+/, '').split(',');
       
  1515 
       
  1516 		for (i=0; i<a.length; i++)
       
  1517 			this.buttonMap[a[i]] = i;
       
  1518 	},
       
  1519 
       
  1520 	submitPatch : function() {
       
  1521 		tinyMCE.removeTinyMCEFormElements(this);
       
  1522 		tinyMCE.triggerSave();
       
  1523 		tinyMCE.isNotDirty = true;
       
  1524 		this.mceOldSubmit();
       
  1525 	},
       
  1526 
       
  1527 	onLoad : function() {
       
  1528 		var r;
       
  1529 
       
  1530 		// Wait for everything to be loaded first
       
  1531 		if (tinyMCE.settings.strict_loading_mode && this.loadingIndex != -1) {
       
  1532 			window.setTimeout('tinyMCE.onLoad();', 1);
       
  1533 			return;
       
  1534 		}
       
  1535 
       
  1536 		if (tinyMCE.isRealIE)
       
  1537     {
       
  1538       try 
       
  1539       {
       
  1540         if ( typeof(window.event) == 'object' && window.event != null )
       
  1541         {
       
  1542           try
       
  1543           {
       
  1544             if ( window.event.type == "onreadystatechange" )
       
  1545             {
       
  1546               try
       
  1547               {
       
  1548                 if ( document.readyState != "complete" )
       
  1549                 {
       
  1550                   return true;
       
  1551                 }
       
  1552               }
       
  1553               catch(e)
       
  1554               {
       
  1555                 alert('inner error: ' + e.description);
       
  1556               }
       
  1557             }
       
  1558           }
       
  1559           catch(e)
       
  1560           {
       
  1561             alert('middle error: ' + e.description);
       
  1562           }
       
  1563         }
       
  1564       }
       
  1565       catch(e)
       
  1566       {
       
  1567         alert('Outer error: ' + e.description);
       
  1568       }
       
  1569     }
       
  1570 
       
  1571 		if (tinyMCE.isLoaded)
       
  1572 			return true;
       
  1573 
       
  1574 		tinyMCE.isLoaded = true;
       
  1575 
       
  1576 		// IE produces JS error if TinyMCE is placed in a frame
       
  1577 		// It seems to have something to do with the selection not beeing
       
  1578 		// correctly initialized in IE so this hack solves the problem
       
  1579 		if (tinyMCE.isRealIE && document.body) {
       
  1580 			r = document.body.createTextRange();
       
  1581 			r.collapse(true);
       
  1582 			r.select();
       
  1583 		}
       
  1584 
       
  1585 		tinyMCE.dispatchCallback(null, 'onpageload', 'onPageLoad');
       
  1586 
       
  1587 		for (var c=0; c<tinyMCE.configs.length; c++) {
       
  1588 			tinyMCE.settings = tinyMCE.configs[c];
       
  1589 
       
  1590 			var selector = tinyMCE.getParam("editor_selector");
       
  1591 			var deselector = tinyMCE.getParam("editor_deselector");
       
  1592 			var elementRefAr = new Array();
       
  1593 
       
  1594 			// Add submit triggers
       
  1595 			if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) {
       
  1596 				for (var i=0; i<document.forms.length; i++) {
       
  1597 					var form = document.forms[i];
       
  1598 
       
  1599 					tinyMCE.addEvent(form, "submit", TinyMCE_Engine.prototype.handleEvent);
       
  1600 					tinyMCE.addEvent(form, "reset", TinyMCE_Engine.prototype.handleEvent);
       
  1601 					tinyMCE.submitTriggers = true; // Do it only once
       
  1602 
       
  1603 					// Patch the form.submit function
       
  1604 					if (tinyMCE.settings['submit_patch']) {
       
  1605 						try {
       
  1606 							form.mceOldSubmit = form.submit;
       
  1607 							form.submit = TinyMCE_Engine.prototype.submitPatch;
       
  1608 						} catch (e) {
       
  1609 							// Do nothing
       
  1610 						}
       
  1611 					}
       
  1612 				}
       
  1613 			}
       
  1614 
       
  1615 			// Add editor instances based on mode
       
  1616 			var mode = tinyMCE.settings['mode'];
       
  1617 			switch (mode) {
       
  1618 				case "exact":
       
  1619 					var elements = tinyMCE.getParam('elements', '', true, ',');
       
  1620 
       
  1621 					for (var i=0; i<elements.length; i++) {
       
  1622 						var element = tinyMCE._getElementById(elements[i]);
       
  1623 						var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : "";
       
  1624 
       
  1625 						if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(element, "class")))
       
  1626 							continue;
       
  1627 
       
  1628 						if (trigger == "false")
       
  1629 							continue;
       
  1630 
       
  1631 						if ((tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) && element) {
       
  1632 							elementRefAr[elementRefAr.length] = element;
       
  1633 							continue;
       
  1634 						}
       
  1635 
       
  1636 						if (element)
       
  1637 							tinyMCE.addMCEControl(element, elements[i]);
       
  1638 						else if (tinyMCE.settings['debug'])
       
  1639 							alert("Error: Could not find element by id or name: " + elements[i]);
       
  1640 					}
       
  1641 				break;
       
  1642 
       
  1643 				case "specific_textareas":
       
  1644 				case "textareas":
       
  1645 					var nodeList = document.getElementsByTagName("textarea");
       
  1646 
       
  1647 					for (var i=0; i<nodeList.length; i++) {
       
  1648 						var elm = nodeList.item(i);
       
  1649 						var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']);
       
  1650 
       
  1651 						if (selector != '' && !new RegExp('\\b' + selector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
       
  1652 							continue;
       
  1653 
       
  1654 						if (selector != '')
       
  1655 							trigger = selector != "" ? "true" : "";
       
  1656 
       
  1657 						if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
       
  1658 							continue;
       
  1659 
       
  1660 						if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false"))
       
  1661 							elementRefAr[elementRefAr.length] = elm;
       
  1662 					}
       
  1663 				break;
       
  1664 			}
       
  1665 
       
  1666 			for (var i=0; i<elementRefAr.length; i++) {
       
  1667 				var element = elementRefAr[i];
       
  1668 				var elementId = element.name ? element.name : element.id;
       
  1669 
       
  1670 				if (tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) {
       
  1671 					// Focus breaks in Mozilla
       
  1672 					if (tinyMCE.isGecko) {
       
  1673 						var settings = tinyMCE.settings;
       
  1674 
       
  1675 						tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
       
  1676 
       
  1677 						if (element.nodeName != "TEXTAREA" && element.nodeName != "INPUT")
       
  1678 							tinyMCE.addEvent(element, "click", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
       
  1679 						// tinyMCE.addEvent(element, "mouseover", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
       
  1680 					} else {
       
  1681 						var settings = tinyMCE.settings;
       
  1682 
       
  1683 						tinyMCE.addEvent(element, "focus", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
       
  1684 						tinyMCE.addEvent(element, "click", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
       
  1685 						// tinyMCE.addEvent(element, "mouseenter", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
       
  1686 					}
       
  1687 				} else
       
  1688 					tinyMCE.addMCEControl(element, elementId);
       
  1689 			}
       
  1690 
       
  1691 			// Handle auto focus
       
  1692 			if (tinyMCE.settings['auto_focus']) {
       
  1693 				window.setTimeout(function () {
       
  1694 					var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']);
       
  1695 					inst.selection.selectNode(inst.getBody(), true, true);
       
  1696 					inst.contentWindow.focus();
       
  1697 				}, 100);
       
  1698 			}
       
  1699 
       
  1700 			tinyMCE.dispatchCallback(null, 'oninit', 'onInit');
       
  1701 		}
       
  1702 	},
       
  1703 
       
  1704 	isInstance : function(o) {
       
  1705 		return o != null && typeof(o) == "object" && o.isTinyMCE_Control;
       
  1706 	},
       
  1707 
       
  1708 	getParam : function(name, default_value, strip_whitespace, split_chr) {
       
  1709 		var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
       
  1710 
       
  1711 		// Fix bool values
       
  1712 		if (value == "true" || value == "false")
       
  1713 			return (value == "true");
       
  1714 
       
  1715 		if (strip_whitespace)
       
  1716 			value = tinyMCE.regexpReplace(value, "[ \t\r\n]", "") + '';
       
  1717 
       
  1718 		if (typeof(split_chr) != "undefined" && split_chr != null) {
       
  1719 			value = value.split(split_chr);
       
  1720 			var outArray = new Array();
       
  1721 
       
  1722 			for (var i=0; i<value.length; i++) {
       
  1723 				if (value[i] && value[i] != "")
       
  1724 					outArray[outArray.length] = value[i];
       
  1725 			}
       
  1726 
       
  1727 			value = outArray;
       
  1728 		}
       
  1729 
       
  1730 		return value;
       
  1731 	},
       
  1732 
       
  1733 	getLang : function(name, default_value, parse_entities, va) {
       
  1734 		var v = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name], n;
       
  1735 
       
  1736 		if (parse_entities)
       
  1737 			v = tinyMCE.entityDecode(v);
       
  1738 
       
  1739 		if (va) {
       
  1740 			for (n in va)
       
  1741 				v = this.replaceVar(v, n, va[n]);
       
  1742 		}
       
  1743 
       
  1744 		return v;
       
  1745 	},
       
  1746 
       
  1747 	entityDecode : function(s) {
       
  1748 		var e = document.createElement("div");
       
  1749 
       
  1750 		e.innerHTML = s;
       
  1751 
       
  1752 		return e.firstChild.nodeValue;
       
  1753 	},
       
  1754 
       
  1755 	addToLang : function(prefix, ar) {
       
  1756 		for (var key in ar) {
       
  1757 			if (typeof(ar[key]) == 'function')
       
  1758 				continue;
       
  1759 
       
  1760 			tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key];
       
  1761 		}
       
  1762 
       
  1763 		this.loadNextScript();
       
  1764 
       
  1765 	//	for (var key in ar)
       
  1766 	//		tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|";
       
  1767 	},
       
  1768 
       
  1769 	triggerNodeChange : function(focus, setup_content) {
       
  1770 		var elm, inst, editorId, undoIndex = -1, undoLevels = -1, doc, anySelection = false, st;
       
  1771 
       
  1772 		if (tinyMCE.selectedInstance) {
       
  1773 			inst = tinyMCE.selectedInstance;
       
  1774 			elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement();
       
  1775 
       
  1776 /*			if (elm == inst.lastTriggerEl)
       
  1777 				return;
       
  1778 
       
  1779 			inst.lastTriggerEl = elm;*/
       
  1780 
       
  1781 			editorId = inst.editorId;
       
  1782 			st = inst.selection.getSelectedText();
       
  1783 
       
  1784 			if (tinyMCE.settings.auto_resize)
       
  1785 				inst.resizeToContent();
       
  1786 
       
  1787 			if (setup_content && tinyMCE.isGecko && inst.isHidden())
       
  1788 				elm = inst.getBody();
       
  1789 
       
  1790 			inst.switchSettings();
       
  1791 
       
  1792 			if (tinyMCE.selectedElement)
       
  1793 				anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0);
       
  1794 
       
  1795 			if (tinyMCE.settings['custom_undo_redo']) {
       
  1796 				undoIndex = inst.undoRedo.undoIndex;
       
  1797 				undoLevels = inst.undoRedo.undoLevels.length;
       
  1798 			}
       
  1799 
       
  1800 			tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);
       
  1801 		}
       
  1802 
       
  1803 		if (this.selectedInstance && (typeof(focus) == "undefined" || focus))
       
  1804 			this.selectedInstance.contentWindow.focus();
       
  1805 	},
       
  1806 
       
  1807 	_customCleanup : function(inst, type, content) {
       
  1808 		var pl, po, i;
       
  1809 
       
  1810 		// Call custom cleanup
       
  1811 		var customCleanup = tinyMCE.settings['cleanup_callback'];
       
  1812 		if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined")
       
  1813 			content = eval(customCleanup + "(type, content, inst);");
       
  1814 
       
  1815 		// Trigger theme cleanup
       
  1816 		po = tinyMCE.themes[tinyMCE.settings['theme']];
       
  1817 		if (po && po.cleanup)
       
  1818 			content = po.cleanup(type, content, inst);
       
  1819 
       
  1820 		// Trigger plugin cleanups
       
  1821 		pl = inst.plugins;
       
  1822 		for (i=0; i<pl.length; i++) {
       
  1823 			po = tinyMCE.plugins[pl[i]];
       
  1824 
       
  1825 			if (po && po.cleanup)
       
  1826 				content = po.cleanup(type, content, inst);
       
  1827 		}
       
  1828 
       
  1829 		return content;
       
  1830 	},
       
  1831 
       
  1832 	setContent : function(h) {
       
  1833 		if (tinyMCE.selectedInstance) {
       
  1834 			tinyMCE.selectedInstance.execCommand('mceSetContent', false, h);
       
  1835 			tinyMCE.selectedInstance.repaint();
       
  1836 		}
       
  1837 	},
       
  1838 
       
  1839 	importThemeLanguagePack : function(name) {
       
  1840 		if (typeof(name) == "undefined")
       
  1841 			name = tinyMCE.settings['theme'];
       
  1842 
       
  1843 		tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js');
       
  1844 	},
       
  1845 
       
  1846 	importPluginLanguagePack : function(name) {
       
  1847 		var b = tinyMCE.baseURL + '/plugins/' + name;
       
  1848 
       
  1849 		if (this.plugins[name])
       
  1850 			b = this.plugins[name].baseURL;
       
  1851 
       
  1852 		tinyMCE.loadScript(b + '/langs/' + tinyMCE.settings['language'] +  '.js');
       
  1853 	},
       
  1854 
       
  1855 	applyTemplate : function(h, as) {
       
  1856 		return h.replace(new RegExp('\\{\\$([a-z0-9_]+)\\}', 'gi'), function(m, s) {
       
  1857 			if (s.indexOf('lang_') == 0 && tinyMCELang[s])
       
  1858 				return tinyMCELang[s];
       
  1859 
       
  1860 			if (as && as[s])
       
  1861 				return as[s];
       
  1862 
       
  1863 			if (tinyMCE.settings[s])
       
  1864 				return tinyMCE.settings[s];
       
  1865 
       
  1866 			if (m == 'themeurl')
       
  1867 				return tinyMCE.themeURL;
       
  1868 
       
  1869 			return m;
       
  1870 		});
       
  1871 	},
       
  1872 
       
  1873 	replaceVar : function(h, r, v) {
       
  1874 		return h.replace(new RegExp('{\\\$' + r + '}', 'g'), v);
       
  1875 	},
       
  1876 
       
  1877 	openWindow : function(template, args) {
       
  1878 		var html, width, height, x, y, resizable, scrollbars, url;
       
  1879 
       
  1880 		args = !args ? {} : args;
       
  1881 
       
  1882 		args['mce_template_file'] = template['file'];
       
  1883 		args['mce_width'] = template['width'];
       
  1884 		args['mce_height'] = template['height'];
       
  1885 		tinyMCE.windowArgs = args;
       
  1886 
       
  1887 		html = template['html'];
       
  1888 		if (!(width = parseInt(template['width'])))
       
  1889 			width = 320;
       
  1890 
       
  1891 		if (!(height = parseInt(template['height'])))
       
  1892 			height = 200;
       
  1893 
       
  1894 		// Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!!
       
  1895 		if (tinyMCE.isIE)
       
  1896 			height += 40;
       
  1897 		else
       
  1898 			height += 20;
       
  1899 
       
  1900 		x = parseInt(screen.width / 2.0) - (width / 2.0);
       
  1901 		y = parseInt(screen.height / 2.0) - (height / 2.0);
       
  1902 
       
  1903 		resizable = (args && args['resizable']) ? args['resizable'] : "no";
       
  1904 		scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
       
  1905 
       
  1906 		if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
       
  1907 			url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
       
  1908 		else
       
  1909 			url = template['file'];
       
  1910 
       
  1911 		// Replace all args as variables in URL
       
  1912 		for (var name in args) {
       
  1913 			if (typeof(args[name]) == 'function')
       
  1914 				continue;
       
  1915 
       
  1916 			url = tinyMCE.replaceVar(url, name, escape(args[name]));
       
  1917 		}
       
  1918 
       
  1919 		if (html) {
       
  1920 			html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']);
       
  1921 			html = tinyMCE.applyTemplate(html, args);
       
  1922 
       
  1923 			var win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable);
       
  1924 			if (win == null) {
       
  1925 				alert(tinyMCELang['lang_popup_blocked']);
       
  1926 				return;
       
  1927 			}
       
  1928 
       
  1929       //alert('docwrite 2');
       
  1930 			win.document.write(html);
       
  1931 			win.document.close();
       
  1932 			win.resizeTo(width, height);
       
  1933 			win.focus();
       
  1934 		} else {
       
  1935 			if ((tinyMCE.isRealIE) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {
       
  1936 				height += 10;
       
  1937 
       
  1938 				var features = "resizable:" + resizable 
       
  1939 					+ ";scroll:"
       
  1940 					+ scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"
       
  1941 					+ width + "px;dialogHeight:" + height + "px;";
       
  1942 
       
  1943 				window.showModalDialog(url, window, features);
       
  1944 			} else {
       
  1945 				var modal = (resizable == "yes") ? "no" : "yes";
       
  1946 
       
  1947 				if (tinyMCE.isGecko && tinyMCE.isMac)
       
  1948 					modal = "no";
       
  1949 
       
  1950 				if (template['close_previous'] != "no")
       
  1951 					try {tinyMCE.lastWindow.close();} catch (ex) {}
       
  1952 
       
  1953 				var win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
       
  1954 				if (win == null) {
       
  1955 					alert(tinyMCELang['lang_popup_blocked']);
       
  1956 					return;
       
  1957 				}
       
  1958 
       
  1959 				if (template['close_previous'] != "no")
       
  1960 					tinyMCE.lastWindow = win;
       
  1961 
       
  1962 				eval('try { win.resizeTo(width, height); } catch(e) { }');
       
  1963 
       
  1964 				// Make it bigger if statusbar is forced
       
  1965 				if (tinyMCE.isGecko) {
       
  1966 					if (win.document.defaultView.statusbar.visible)
       
  1967 						win.resizeBy(0, tinyMCE.isMac ? 10 : 24);
       
  1968 				}
       
  1969 
       
  1970 				win.focus();
       
  1971 			}
       
  1972 		}
       
  1973 	},
       
  1974 
       
  1975 	closeWindow : function(win) {
       
  1976 		win.close();
       
  1977 	},
       
  1978 
       
  1979 	getVisualAidClass : function(class_name, state) {
       
  1980 		var aidClass = tinyMCE.settings['visual_table_class'];
       
  1981 
       
  1982 		if (typeof(state) == "undefined")
       
  1983 			state = tinyMCE.settings['visual'];
       
  1984 
       
  1985 		// Split
       
  1986 		var classNames = new Array();
       
  1987 		var ar = class_name.split(' ');
       
  1988 		for (var i=0; i<ar.length; i++) {
       
  1989 			if (ar[i] == aidClass)
       
  1990 				ar[i] = "";
       
  1991 
       
  1992 			if (ar[i] != "")
       
  1993 				classNames[classNames.length] = ar[i];
       
  1994 		}
       
  1995 
       
  1996 		if (state)
       
  1997 			classNames[classNames.length] = aidClass;
       
  1998 
       
  1999 		// Glue
       
  2000 		var className = "";
       
  2001 		for (var i=0; i<classNames.length; i++) {
       
  2002 			if (i > 0)
       
  2003 				className += " ";
       
  2004 
       
  2005 			className += classNames[i];
       
  2006 		}
       
  2007 
       
  2008 		return className;
       
  2009 	},
       
  2010 
       
  2011 	handleVisualAid : function(el, deep, state, inst, skip_dispatch) {
       
  2012 		if (!el)
       
  2013 			return;
       
  2014 
       
  2015 		if (!skip_dispatch)
       
  2016 			tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst);
       
  2017 
       
  2018 		var tableElement = null;
       
  2019 
       
  2020 		switch (el.nodeName) {
       
  2021 			case "TABLE":
       
  2022 				var oldW = el.style.width;
       
  2023 				var oldH = el.style.height;
       
  2024 				var bo = tinyMCE.getAttrib(el, "border");
       
  2025 
       
  2026 				bo = bo == "" || bo == "0" ? true : false;
       
  2027 
       
  2028 				tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));
       
  2029 
       
  2030 				el.style.width = oldW;
       
  2031 				el.style.height = oldH;
       
  2032 
       
  2033 				for (var y=0; y<el.rows.length; y++) {
       
  2034 					for (var x=0; x<el.rows[y].cells.length; x++) {
       
  2035 						var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
       
  2036 						tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);
       
  2037 					}
       
  2038 				}
       
  2039 
       
  2040 				break;
       
  2041 
       
  2042 			case "A":
       
  2043 				var anchorName = tinyMCE.getAttrib(el, "name");
       
  2044 
       
  2045 				if (anchorName != '' && state) {
       
  2046 					el.title = anchorName;
       
  2047 					tinyMCE.addCSSClass(el, 'mceItemAnchor');
       
  2048 				} else if (anchorName != '' && !state)
       
  2049 					el.className = '';
       
  2050 
       
  2051 				break;
       
  2052 		}
       
  2053 
       
  2054 		if (deep && el.hasChildNodes()) {
       
  2055 			for (var i=0; i<el.childNodes.length; i++)
       
  2056 				tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst, true);
       
  2057 		}
       
  2058 	},
       
  2059 
       
  2060 	/*
       
  2061 	applyClassesToFonts : function(doc, size) {
       
  2062 		var f = doc.getElementsByTagName("font");
       
  2063 		for (var i=0; i<f.length; i++) {
       
  2064 			var s = tinyMCE.getAttrib(f[i], "size");
       
  2065 
       
  2066 			if (s != "")
       
  2067 				tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);
       
  2068 		}
       
  2069 
       
  2070 		if (typeof(size) != "undefined") {
       
  2071 			var css = "";
       
  2072 
       
  2073 			for (var x=0; x<doc.styleSheets.length; x++) {
       
  2074 				for (var i=0; i<doc.styleSheets[x].rules.length; i++) {
       
  2075 					if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {
       
  2076 						css = doc.styleSheets[x].rules[i].style.cssText;
       
  2077 						break;
       
  2078 					}
       
  2079 				}
       
  2080 
       
  2081 				if (css != "")
       
  2082 					break;
       
  2083 			}
       
  2084 
       
  2085 			if (doc.styleSheets[0].rules[0].selectorText == "FONT")
       
  2086 				doc.styleSheets[0].removeRule(0);
       
  2087 
       
  2088 			doc.styleSheets[0].addRule("FONT", css, 0);
       
  2089 		}
       
  2090 	},
       
  2091 	*/
       
  2092 
       
  2093 	fixGeckoBaseHREFBug : function(m, e, h) {
       
  2094 		var xsrc, xhref;
       
  2095 
       
  2096 		if (tinyMCE.isGecko) {
       
  2097 			if (m == 1) {
       
  2098 				h = h.replace(/\ssrc=/gi, " mce_tsrc=");
       
  2099 				h = h.replace(/\shref=/gi, " mce_thref=");
       
  2100 
       
  2101 				return h;
       
  2102 			} else {
       
  2103 				// Why bother if there is no src or href broken
       
  2104 				if (!new RegExp('(src|href)=', 'g').test(h))
       
  2105 					return h;
       
  2106 
       
  2107 				// Restore src and href that gets messed up by Gecko
       
  2108 				tinyMCE.selectElements(e, 'A,IMG,SELECT,AREA,IFRAME,BASE,INPUT,SCRIPT,EMBED,OBJECT,LINK', function (n) {
       
  2109 					xsrc = tinyMCE.getAttrib(n, "mce_tsrc");
       
  2110 					xhref = tinyMCE.getAttrib(n, "mce_thref");
       
  2111 
       
  2112 					if (xsrc != "") {
       
  2113 						try {
       
  2114 							n.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
       
  2115 						} catch (e) {
       
  2116 							// Ignore, Firefox cast exception if local file wasn't found
       
  2117 						}
       
  2118 
       
  2119 						n.removeAttribute("mce_tsrc");
       
  2120 					}
       
  2121 
       
  2122 					if (xhref != "") {
       
  2123 						try {
       
  2124 							n.href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);
       
  2125 						} catch (e) {
       
  2126 							// Ignore, Firefox cast exception if local file wasn't found
       
  2127 						}
       
  2128 
       
  2129 						n.removeAttribute("mce_thref");
       
  2130 					}
       
  2131 
       
  2132 					return false;
       
  2133 				});
       
  2134 
       
  2135 				// Restore text/comment nodes
       
  2136 				tinyMCE.selectNodes(e, function(n) {
       
  2137 					if (n.nodeType == 3 || n.nodeType == 8) {
       
  2138 						n.nodeValue = n.nodeValue.replace(/\smce_tsrc=/gi, " src=");
       
  2139 						n.nodeValue = n.nodeValue.replace(/\smce_thref=/gi, " href=");
       
  2140 					}
       
  2141 
       
  2142 					return false;
       
  2143 				});
       
  2144 			}
       
  2145 		}
       
  2146 
       
  2147 		return h;
       
  2148 	},
       
  2149 
       
  2150 	_setHTML : function(doc, html_content) {
       
  2151 		// Force closed anchors open
       
  2152 		//html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
       
  2153 
       
  2154 		html_content = tinyMCE.cleanupHTMLCode(html_content);
       
  2155 
       
  2156 		// Try innerHTML if it fails use pasteHTML in MSIE
       
  2157 		try {
   763 		try {
  2158 			tinyMCE.setInnerHTML(doc.body, html_content);
   764 			return eval('(' + s + ')');
  2159 		} catch (e) {
       
  2160 			if (this.isMSIE)
       
  2161 				doc.body.createTextRange().pasteHTML(html_content);
       
  2162 		}
       
  2163 
       
  2164 		// Content duplication bug fix
       
  2165 		if (tinyMCE.isIE && tinyMCE.settings['fix_content_duplication']) {
       
  2166 			// Remove P elements in P elements
       
  2167 			var paras = doc.getElementsByTagName("P");
       
  2168 			for (var i=0; i<paras.length; i++) {
       
  2169 				var node = paras[i];
       
  2170 				while ((node = node.parentNode) != null) {
       
  2171 					if (node.nodeName == "P")
       
  2172 						node.outerHTML = node.innerHTML;
       
  2173 				}
       
  2174 			}
       
  2175 
       
  2176 			// Content duplication bug fix (Seems to be word crap)
       
  2177 			var html = doc.body.innerHTML;
       
  2178 /*
       
  2179 			if (html.indexOf('="mso') != -1) {
       
  2180 				for (var i=0; i<doc.body.all.length; i++) {
       
  2181 					var el = doc.body.all[i];
       
  2182 					el.removeAttribute("className","",0);
       
  2183 					el.removeAttribute("style","",0);
       
  2184 				}
       
  2185 
       
  2186 				html = doc.body.innerHTML;
       
  2187 				html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />");
       
  2188 				html = tinyMCE.regexpReplace(html, "<o:p>&nbsp;<\/o:p>", "");
       
  2189 				html = tinyMCE.regexpReplace(html, "<st1:.*?>", "");
       
  2190 				html = tinyMCE.regexpReplace(html, "<p><\/p>", "");
       
  2191 				html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", "");
       
  2192 				html = tinyMCE.regexpReplace(html, "<p>&nbsp;<\/p>", "<br />");
       
  2193 				html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>");
       
  2194 				html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>");
       
  2195 			}*/
       
  2196 
       
  2197 			// Always set the htmlText output
       
  2198 			tinyMCE.setInnerHTML(doc.body, html);
       
  2199 		}
       
  2200 
       
  2201 		tinyMCE.cleanupAnchors(doc);
       
  2202 
       
  2203 		if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  2204 			tinyMCE.convertSpansToFonts(doc);
       
  2205 	},
       
  2206 
       
  2207 	getEditorId : function(form_element) {
       
  2208 		var inst = this.getInstanceById(form_element);
       
  2209 		if (!inst)
       
  2210 			return null;
       
  2211 
       
  2212 		return inst.editorId;
       
  2213 	},
       
  2214 
       
  2215 	getInstanceById : function(editor_id) {
       
  2216 		var inst = this.instances[editor_id];
       
  2217 		if (!inst) {
       
  2218 			for (var n in tinyMCE.instances) {
       
  2219 				var instance = tinyMCE.instances[n];
       
  2220 				if (!tinyMCE.isInstance(instance))
       
  2221 					continue;
       
  2222 
       
  2223 				if (instance.formTargetElementId == editor_id) {
       
  2224 					inst = instance;
       
  2225 					break;
       
  2226 				}
       
  2227 			}
       
  2228 		}
       
  2229 
       
  2230 		return inst;
       
  2231 	},
       
  2232 
       
  2233 	queryInstanceCommandValue : function(editor_id, command) {
       
  2234 		var inst = tinyMCE.getInstanceById(editor_id);
       
  2235 		if (inst)
       
  2236 			return inst.queryCommandValue(command);
       
  2237 
       
  2238 		return false;
       
  2239 	},
       
  2240 
       
  2241 	queryInstanceCommandState : function(editor_id, command) {
       
  2242 		var inst = tinyMCE.getInstanceById(editor_id);
       
  2243 		if (inst)
       
  2244 			return inst.queryCommandState(command);
       
  2245 
       
  2246 		return null;
       
  2247 	},
       
  2248 
       
  2249 	setWindowArg : function(n, v) {
       
  2250 		this.windowArgs[n] = v;
       
  2251 	},
       
  2252 
       
  2253 	getWindowArg : function(n, d) {
       
  2254 		return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n];
       
  2255 	},
       
  2256 
       
  2257 	getCSSClasses : function(editor_id, doc) {
       
  2258 		var inst = tinyMCE.getInstanceById(editor_id);
       
  2259 
       
  2260 		// Is cached, use that
       
  2261 		if (inst && inst.cssClasses.length > 0)
       
  2262 			return inst.cssClasses;
       
  2263 
       
  2264 		if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") {
       
  2265 			var instance;
       
  2266 
       
  2267 			for (var instanceName in tinyMCE.instances) {
       
  2268 				instance = tinyMCE.instances[instanceName];
       
  2269 				if (!tinyMCE.isInstance(instance))
       
  2270 					continue;
       
  2271 
       
  2272 				break;
       
  2273 			}
       
  2274 
       
  2275 			doc = instance.getDoc();
       
  2276 		}
       
  2277 
       
  2278 		if (typeof(doc) == "undefined") {
       
  2279 			var instance = tinyMCE.getInstanceById(editor_id);
       
  2280 			doc = instance.getDoc();
       
  2281 		}
       
  2282 
       
  2283 		if (doc) {
       
  2284 			var styles = doc.styleSheets;
       
  2285 
       
  2286 			if (styles && styles.length > 0) {
       
  2287 				for (var x=0; x<styles.length; x++) {
       
  2288 					var csses = null;
       
  2289 
       
  2290 					// Just ignore any errors
       
  2291 					eval("try {var csses = tinyMCE.isIE ? doc.styleSheets(" + x + ").rules : styles[" + x + "].cssRules;} catch(e) {}");
       
  2292 					if (!csses)
       
  2293 						return new Array();
       
  2294 
       
  2295 					for (var i=0; i<csses.length; i++) {
       
  2296 						var selectorText = csses[i].selectorText;
       
  2297 
       
  2298 						// Can be multiple rules per selector
       
  2299 						if (selectorText) {
       
  2300 							var rules = selectorText.split(',');
       
  2301 							for (var c=0; c<rules.length; c++) {
       
  2302 								var rule = rules[c];
       
  2303 
       
  2304 								// Strip spaces between selectors
       
  2305 								while (rule.indexOf(' ') == 0)
       
  2306 									rule = rule.substring(1);
       
  2307 
       
  2308 								// Invalid rule
       
  2309 								if (rule.indexOf(' ') != -1 || rule.indexOf(':') != -1 || rule.indexOf('mceItem') != -1)
       
  2310 									continue;
       
  2311 
       
  2312 								if (rule.indexOf(tinyMCE.settings['visual_table_class']) != -1 || rule.indexOf('mceEditable') != -1 || rule.indexOf('mceNonEditable') != -1)
       
  2313 									continue;
       
  2314 
       
  2315 								// Is class rule
       
  2316 								if (rule.indexOf('.') != -1) {
       
  2317 									var cssClass = rule.substring(rule.indexOf('.') + 1);
       
  2318 									var addClass = true;
       
  2319 
       
  2320 									for (var p=0; p<inst.cssClasses.length && addClass; p++) {
       
  2321 										if (inst.cssClasses[p] == cssClass)
       
  2322 											addClass = false;
       
  2323 									}
       
  2324 
       
  2325 									if (addClass)
       
  2326 										inst.cssClasses[inst.cssClasses.length] = cssClass;
       
  2327 								}
       
  2328 							}
       
  2329 						}
       
  2330 					}
       
  2331 				}
       
  2332 			}
       
  2333 		}
       
  2334 
       
  2335 		return inst.cssClasses;
       
  2336 	},
       
  2337 
       
  2338 	regexpReplace : function(in_str, reg_exp, replace_str, opts) {
       
  2339 		if (in_str == null)
       
  2340 			return in_str;
       
  2341 
       
  2342 		if (typeof(opts) == "undefined")
       
  2343 			opts = 'g';
       
  2344 
       
  2345 		var re = new RegExp(reg_exp, opts);
       
  2346 		return in_str.replace(re, replace_str);
       
  2347 	},
       
  2348 
       
  2349 	trim : function(s) {
       
  2350 		return s.replace(/^\s*|\s*$/g, "");
       
  2351 	},
       
  2352 
       
  2353 	cleanupEventStr : function(s) {
       
  2354 		s = "" + s;
       
  2355 		s = s.replace('function anonymous()\n{\n', '');
       
  2356 		s = s.replace('\n}', '');
       
  2357 		s = s.replace(/^return true;/gi, ''); // Remove event blocker
       
  2358 
       
  2359 		return s;
       
  2360 	},
       
  2361 
       
  2362 	getControlHTML : function(c) {
       
  2363 		var i, l, n, o, v, rtl = tinyMCE.getLang('lang_dir') == 'rtl';
       
  2364 
       
  2365 		l = tinyMCE.plugins;
       
  2366 		for (n in l) {
       
  2367 			o = l[n];
       
  2368 
       
  2369 			if (o.getControlHTML && (v = o.getControlHTML(c)) != '') {
       
  2370 				if (rtl)
       
  2371 					return '<span dir="rtl">' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '</span>';
       
  2372 
       
  2373 				return tinyMCE.replaceVar(v, "pluginurl", o.baseURL);
       
  2374 			}
       
  2375 		}
       
  2376 
       
  2377 		o = tinyMCE.themes[tinyMCE.settings['theme']];
       
  2378 		if (o.getControlHTML && (v = o.getControlHTML(c)) != '') {
       
  2379 			if (rtl)
       
  2380 				return '<span dir="rtl">' + v + '</span>';
       
  2381 
       
  2382 			return v;
       
  2383 		}
       
  2384 
       
  2385 		return '';
       
  2386 	},
       
  2387 
       
  2388 	evalFunc : function(f, idx, a, o) {
       
  2389 		o = !o ? window : o;
       
  2390 		f = typeof(f) == 'function' ? f : o[f];
       
  2391 
       
  2392 		return f.apply(o, Array.prototype.slice.call(a, idx));
       
  2393 	},
       
  2394 
       
  2395 	dispatchCallback : function(i, p, n) {
       
  2396 		return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments);
       
  2397 	},
       
  2398 
       
  2399 	executeCallback : function(i, p, n) {
       
  2400 		return this.callFunc(i, p, n, 1, this.executeCallback.arguments);
       
  2401 	},
       
  2402 
       
  2403 	execCommandCallback : function(i, p, n) {
       
  2404 		return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments);
       
  2405 	},
       
  2406 
       
  2407 	callFunc : function(ins, p, n, m, a) {
       
  2408 		var l, i, on, o, s, v;
       
  2409 
       
  2410 		s = m == 2;
       
  2411 
       
  2412 		l = tinyMCE.getParam(p, '');
       
  2413 
       
  2414 		if (l != '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0)
       
  2415 			return true;
       
  2416 
       
  2417 		if (ins != null) {
       
  2418 			for (i=0, l = ins.plugins; i<l.length; i++) {
       
  2419 				o = tinyMCE.plugins[l[i]];
       
  2420 
       
  2421 				if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0)
       
  2422 					return true;
       
  2423 			}
       
  2424 		}
       
  2425 
       
  2426 		l = tinyMCE.themes;
       
  2427 		for (on in l) {
       
  2428 			o = l[on];
       
  2429 
       
  2430 			if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0)
       
  2431 				return true;
       
  2432 		}
       
  2433 
       
  2434 		return false;
       
  2435 	},
       
  2436 
       
  2437 	xmlEncode : function(s, skip_apos) {
       
  2438 		return s ? ('' + s).replace(!skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe, function (c, b) {
       
  2439 			switch (c) {
       
  2440 				case '&':
       
  2441 					return '&amp;';
       
  2442 
       
  2443 				case '"':
       
  2444 					return '&quot;';
       
  2445 
       
  2446 				case '\'':
       
  2447 					return '&#39;'; // &apos; is not working in MSIE
       
  2448 
       
  2449 				case '<':
       
  2450 					return '&lt;';
       
  2451 
       
  2452 				case '>':
       
  2453 					return '&gt;';
       
  2454 			}
       
  2455 
       
  2456 			return c;
       
  2457 		}) : s;
       
  2458 	},
       
  2459 
       
  2460 	extend : function(p, np) {
       
  2461 		var o = {};
       
  2462 
       
  2463 		o.parent = p;
       
  2464 
       
  2465 		for (n in p)
       
  2466 			o[n] = p[n];
       
  2467 
       
  2468 		for (n in np)
       
  2469 			o[n] = np[n];
       
  2470 
       
  2471 		return o;
       
  2472 	},
       
  2473 
       
  2474 	hideMenus : function() {
       
  2475 		var e = tinyMCE.lastSelectedMenuBtn;
       
  2476 
       
  2477 		if (tinyMCE.lastMenu) {
       
  2478 			tinyMCE.lastMenu.hide();
       
  2479 			tinyMCE.lastMenu = null;
       
  2480 		}
       
  2481 
       
  2482 		if (e) {
       
  2483 			tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass);
       
  2484 			tinyMCE.lastSelectedMenuBtn = null;
       
  2485 		}
       
  2486 	}
       
  2487 
       
  2488 	};
       
  2489 
       
  2490 // Global instances
       
  2491 var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors
       
  2492 var tinyMCE = new TinyMCE_Engine();
       
  2493 var tinyMCELang = {};
       
  2494 
       
  2495 /* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */
       
  2496 
       
  2497 function TinyMCE_Control(settings) {
       
  2498   
       
  2499 	var t, i, to, fu, p, x, fn, fu, pn, s = settings;
       
  2500 
       
  2501 	this.undoRedoLevel = true;
       
  2502 	this.isTinyMCE_Control = true;
       
  2503   
       
  2504 	// Default settings
       
  2505 	this.settings = s;
       
  2506 	this.settings['theme'] = tinyMCE.getParam("theme", "default");
       
  2507 	this.settings['width'] = tinyMCE.getParam("width", -1);
       
  2508 	this.settings['height'] = tinyMCE.getParam("height", -1);
       
  2509 	this.selection = new TinyMCE_Selection(this);
       
  2510 	this.undoRedo = new TinyMCE_UndoRedo(this);
       
  2511 	this.cleanup = new TinyMCE_Cleanup();
       
  2512 	this.shortcuts = new Array();
       
  2513 	this.hasMouseMoved = false;
       
  2514 	this.foreColor = this.backColor = "#999999";
       
  2515 	this.data = {};
       
  2516 	this.cssClasses = [];
       
  2517 
       
  2518 	this.cleanup.init({
       
  2519 		valid_elements : s.valid_elements,
       
  2520 		extended_valid_elements : s.extended_valid_elements,
       
  2521 		valid_child_elements : s.valid_child_elements,
       
  2522 		entities : s.entities,
       
  2523 		entity_encoding : s.entity_encoding,
       
  2524 		debug : s.cleanup_debug,
       
  2525 		indent : s.apply_source_formatting,
       
  2526 		invalid_elements : s.invalid_elements,
       
  2527 		verify_html : s.verify_html,
       
  2528 		fix_content_duplication : s.fix_content_duplication,
       
  2529 		convert_fonts_to_spans : s.convert_fonts_to_spans
       
  2530 	});
       
  2531 
       
  2532 	// Wrap old theme
       
  2533 	t = this.settings['theme'];
       
  2534 	if (!tinyMCE.hasTheme(t)) {
       
  2535 		fn = tinyMCE.callbacks;
       
  2536 		to = {};
       
  2537 
       
  2538 		for (i=0; i<fn.length; i++) {
       
  2539 			if ((fu = window['TinyMCE_' + t + "_" + fn[i]]))
       
  2540 				to[fn[i]] = fu;
       
  2541 		}
       
  2542 
       
  2543 		tinyMCE.addTheme(t, to);
       
  2544 	}
       
  2545 
       
  2546 	// Wrap old plugins
       
  2547 	this.plugins = new Array();
       
  2548 	p = tinyMCE.getParam('plugins', '', true, ',');
       
  2549 	if (p.length > 0) {
       
  2550 		for (i=0; i<p.length; i++) {
       
  2551 			pn = p[i];
       
  2552 
       
  2553 			if (pn.charAt(0) == '-')
       
  2554 				pn = pn.substring(1);
       
  2555 
       
  2556 			if (!tinyMCE.hasPlugin(pn)) {
       
  2557 				fn = tinyMCE.callbacks;
       
  2558 				to = {};
       
  2559 
       
  2560 				for (x=0; x<fn.length; x++) {
       
  2561 					if ((fu = window['TinyMCE_' + pn + "_" + fn[x]]))
       
  2562 						to[fn[x]] = fu;
       
  2563 				}
       
  2564 
       
  2565 				tinyMCE.addPlugin(pn, to);
       
  2566 			}
       
  2567 
       
  2568 			this.plugins[this.plugins.length] = pn; 
       
  2569 		}
       
  2570 	}
       
  2571 };
       
  2572 
       
  2573 TinyMCE_Control.prototype = {
       
  2574 	selection : null,
       
  2575 
       
  2576 	settings : null,
       
  2577 
       
  2578 	cleanup : null,
       
  2579 
       
  2580 	getData : function(na) {
       
  2581 		var o = this.data[na];
       
  2582 
       
  2583 		if (!o)
       
  2584 			o = this.data[na] = {};
       
  2585 
       
  2586 		return o;
       
  2587 	},
       
  2588 
       
  2589 	hasPlugin : function(n) {
       
  2590 		var i;
       
  2591 
       
  2592 		for (i=0; i<this.plugins.length; i++) {
       
  2593 			if (this.plugins[i] == n)
       
  2594 				return true;
       
  2595 		}
       
  2596 
       
  2597 		return false;
       
  2598 	},
       
  2599 
       
  2600 	addPlugin : function(n, p) {
       
  2601 		if (!this.hasPlugin(n)) {
       
  2602 			tinyMCE.addPlugin(n, p);
       
  2603 			this.plugins[this.plugins.length] = n;
       
  2604 		}
       
  2605 	},
       
  2606 
       
  2607 	repaint : function() {
       
  2608 		var s, b, ex;
       
  2609 
       
  2610 		if (tinyMCE.isRealIE)
       
  2611 			return;
       
  2612 
       
  2613 		try {
       
  2614 			s = this.selection;
       
  2615 			b = s.getBookmark(true);
       
  2616 			this.getBody().style.display = 'none';
       
  2617 			this.getDoc().execCommand('selectall', false, null);
       
  2618 			this.getSel().collapseToStart();
       
  2619 			this.getBody().style.display = 'block';
       
  2620 			s.moveToBookmark(b);
       
  2621 		} catch (ex) {
   765 		} catch (ex) {
  2622 			// Ignore
   766 			// Ignore
  2623 		}
   767 		}
  2624 	},
   768 	}
  2625 
   769 
  2626 	switchSettings : function() {
   770 	});
  2627 		if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) {
   771 
  2628 			tinyMCE.settings = this.settings;
   772 /* file:jscripts/tiny_mce/classes/util/XHR.js */
  2629 			tinyMCE.currentConfig = this.settings['index'];
   773 
       
   774 tinymce.create('static tinymce.util.XHR', {
       
   775 	send : function(o) {
       
   776 		var x, t, w = window, c = 0;
       
   777 
       
   778 		// Default settings
       
   779 		o.scope = o.scope || this;
       
   780 		o.success_scope = o.success_scope || o.scope;
       
   781 		o.error_scope = o.error_scope || o.scope;
       
   782 		o.async = o.async === false ? false : true;
       
   783 		o.data = o.data || '';
       
   784 
       
   785 		function get(s) {
       
   786 			x = 0;
       
   787 
       
   788 			try {
       
   789 				x = new ActiveXObject(s);
       
   790 			} catch (ex) {
       
   791 			}
       
   792 
       
   793 			return x;
       
   794 		};
       
   795 
       
   796 		x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');
       
   797 
       
   798 		if (x) {
       
   799 			if (x.overrideMimeType)
       
   800 				x.overrideMimeType(o.content_type);
       
   801 
       
   802 			x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);
       
   803 
       
   804 			if (o.content_type)
       
   805 				x.setRequestHeader('Content-Type', o.content_type);
       
   806 
       
   807 			x.send(o.data);
       
   808 
       
   809 			// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
       
   810 			t = w.setInterval(function() {
       
   811 				if (x.readyState == 4 || c++ > 10000) {
       
   812 					w.clearInterval(t);
       
   813 
       
   814 					if (o.success && c < 10000 && x.status == 200)
       
   815 						o.success.call(o.success_scope, '' + x.responseText, x, o);
       
   816 					else if (o.error)
       
   817 						o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
       
   818 
       
   819 					x = null;
       
   820 				}
       
   821 			}, 10);
  2630 		}
   822 		}
  2631 	},
   823 
  2632 
       
  2633 	select : function() {
       
  2634 		var oldInst = tinyMCE.selectedInstance;
       
  2635 
       
  2636 		if (oldInst != this) {
       
  2637 			if (oldInst)
       
  2638 				oldInst.execCommand('mceEndTyping');
       
  2639 
       
  2640 			tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst);
       
  2641 			tinyMCE.selectedInstance = this;
       
  2642 		}
   824 		}
  2643 	},
   825 });
  2644 
   826 
  2645 	getBody : function() {
   827 /* file:jscripts/tiny_mce/classes/util/JSONRequest.js */
  2646 		return this.contentBody ? this.contentBody : this.getDoc().body;
   828 
  2647 	},
   829 (function() {
  2648 
   830 	var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
  2649 	getDoc : function() {
   831 
  2650 //		return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ?
   832 	tinymce.create('tinymce.util.JSONRequest', {
  2651 		return this.contentWindow.document;
   833 		JSONRequest : function(s) {
  2652 	},
   834 			this.settings = extend({
  2653 
   835 			}, s);
  2654 	getWin : function() {
   836 			this.count = 0;
  2655 		return this.contentWindow;
   837 		},
  2656 	},
   838 
  2657 
   839 		send : function(o) {
  2658 	getContainerWin : function() {
   840 			var ecb = o.error, scb = o.success;
  2659 		return this.containerWindow ? this.containerWindow : window;
   841 
  2660 	},
   842 			o = extend(this.settings, o);
  2661 
   843 
  2662 	getViewPort : function() {
   844 			o.success = function(c, x) {
  2663 		return tinyMCE.getViewPort(this.getWin());
   845 				c = JSON.parse(c);
  2664 	},
   846 
  2665 
   847 				if (typeof(c) == 'undefined') {
  2666 	getParentNode : function(n, f) {
   848 					c = {
  2667 		return tinyMCE.getParentNode(n, f, this.getBody());
   849 						error : 'JSON Parse error.'
  2668 	},
   850 					};
  2669 
   851 				}
  2670 	getParentElement : function(n, na, f) {
   852 
  2671 		return tinyMCE.getParentElement(n, na, f, this.getBody());
   853 				if (c.error)
  2672 	},
   854 					ecb.call(o.error_scope || o.scope, c.error, x);
  2673 
   855 				else
  2674 	getParentBlockElement : function(n) {
   856 					scb.call(o.success_scope || o.scope, c.result);
  2675 		return tinyMCE.getParentBlockElement(n, this.getBody());
   857 			};
  2676 	},
   858 
  2677 
   859 			o.error = function(ty, x) {
  2678 	resizeToContent : function() {
   860 				ecb.call(o.error_scope || o.scope, ty, x);
  2679 		var d = this.getDoc(), b = d.body, de = d.documentElement;
   861 			};
  2680 
   862 
  2681 		this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px';
   863 			o.data = JSON.serialize({
  2682 	},
   864 				id : o.id || 'c' + (this.count++),
  2683 
   865 				method : o.method,
  2684 	addShortcut : function(m, k, d, cmd, ui, va) {
   866 				params : o.params
  2685 		var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts;
   867 			});
  2686 
   868 
  2687 		if (!tinyMCE.getParam('custom_shortcuts'))
   869 			XHR.send(o);
       
   870 		},
       
   871 
       
   872 		'static' : {
       
   873 			sendRPC : function(o) {
       
   874 				return new tinymce.util.JSONRequest().send(o);
       
   875 			}
       
   876 		}
       
   877 
       
   878 		});
       
   879 }());
       
   880 /* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */
       
   881 
       
   882 (function() {
       
   883 	// Shorten names
       
   884 	var each = tinymce.each, is = tinymce.is;
       
   885 	var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE;
       
   886 
       
   887 	tinymce.create('tinymce.dom.DOMUtils', {
       
   888 		doc : null,
       
   889 		root : null,
       
   890 		files : null,
       
   891 		listeners : {},
       
   892 		pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,
       
   893 		cache : {},
       
   894 		idPattern : /^#[\w]+$/,
       
   895 		elmPattern : /^[\w_*]+$/,
       
   896 		elmClassPattern : /^([\w_]*)\.([\w_]+)$/,
       
   897 
       
   898 		DOMUtils : function(d, s) {
       
   899 			var t = this;
       
   900 
       
   901 			t.doc = d;
       
   902 			t.files = {};
       
   903 			t.cssFlicker = false;
       
   904 			t.counter = 0;
       
   905 			t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 
       
   906 
       
   907 			this.settings = s = tinymce.extend({
       
   908 				keep_values : false,
       
   909 				hex_colors : 1
       
   910 			}, s);
       
   911 
       
   912 			// Fix IE6SP2 flicker and check it failed for pre SP2
       
   913 			if (tinymce.isIE6) {
       
   914 				try {
       
   915 					d.execCommand('BackgroundImageCache', false, true);
       
   916 				} catch (e) {
       
   917 					t.cssFlicker = true;
       
   918 				}
       
   919 			}
       
   920 
       
   921 			tinymce.addUnload(function() {
       
   922 				t.doc = t.root = null;
       
   923 			});
       
   924 		},
       
   925 
       
   926 		getRoot : function() {
       
   927 			var t = this, s = t.settings;
       
   928 
       
   929 			return (s && t.get(s.root_element)) || t.doc.body;
       
   930 		},
       
   931 
       
   932 		getViewPort : function(w) {
       
   933 			var d, b;
       
   934 
       
   935 			w = !w ? window : w;
       
   936 			d = w.document;
       
   937 			b = this.boxModel ? d.documentElement : d.body;
       
   938 
       
   939 			// Returns viewport size excluding scrollbars
       
   940 			return {
       
   941 				x : w.pageXOffset || b.scrollLeft,
       
   942 				y : w.pageYOffset || b.scrollTop,
       
   943 				w : w.innerWidth || b.clientWidth,
       
   944 				h : w.innerHeight || b.clientHeight
       
   945 			};
       
   946 		},
       
   947 
       
   948 		getRect : function(e) {
       
   949 			var p, t = this;
       
   950 
       
   951 			e = t.get(e);
       
   952 			p = t.getPos(e);
       
   953 
       
   954 			return {
       
   955 				x : p.x,
       
   956 				y : p.y,
       
   957 				w : parseInt(t.getStyle(e, 'width')) || e.offsetWidth || e.clientWidth,
       
   958 				h : parseInt(t.getStyle(e, 'height')) || e.offsetHeight || e.clientHeight
       
   959 			};
       
   960 		},
       
   961 
       
   962 		getParent : function(n, f, r) {
       
   963 			var na;
       
   964 
       
   965 			n = this.get(n);
       
   966 
       
   967 			if (this.settings.strict_root)
       
   968 				r = r || this.getRoot();
       
   969 
       
   970 			// Wrap node name as func
       
   971 			if (is(f, 'string')) {
       
   972 				na = f.toUpperCase();
       
   973 
       
   974 				f = function(n) {
       
   975 					var s = false;
       
   976 
       
   977 					// Any element
       
   978 					if (n.nodeType == 1 && na === '*') {
       
   979 						s = true;
       
   980 						return false;
       
   981 					}
       
   982 
       
   983 					each(na.split(','), function(v) {
       
   984 						if (n.nodeType == 1 && n.nodeName == v) {
       
   985 							s = true;
       
   986 							return false; // Break loop
       
   987 						}
       
   988 					});
       
   989 
       
   990 					return s;
       
   991 				};
       
   992 			}
       
   993 
       
   994 			while (n) {
       
   995 				if (n == r)
       
   996 					return null;
       
   997 
       
   998 				if (f(n))
       
   999 					return n;
       
  1000 
       
  1001 				n = n.parentNode;
       
  1002 			}
       
  1003 
       
  1004 			return null;
       
  1005 		},
       
  1006 
       
  1007 		get : function(e) {
       
  1008 			if (typeof(e) == 'string')
       
  1009 				return this.doc.getElementById(e);
       
  1010 
       
  1011 			return e;
       
  1012 		},
       
  1013 
       
  1014 		// #if !jquery
       
  1015 
       
  1016 		select : function(pa, s) {
       
  1017 			var t = this, cs, c, pl, o = [], x, i, l, n;
       
  1018 
       
  1019 			s = t.get(s) || t.doc;
       
  1020 
       
  1021 			// Simple element pattern. For example: "p" or "*"
       
  1022 			if (t.elmPattern.test(pa)) {
       
  1023 				x = s.getElementsByTagName(pa);
       
  1024 
       
  1025 				for (i = 0, l = x.length; i<l; i++)
       
  1026 					o.push(x[i]);
       
  1027 
       
  1028 				return o;
       
  1029 			}
       
  1030 
       
  1031 			// Simple class pattern. For example: "p.class" or ".class"
       
  1032 			if (t.elmClassPattern.test(pa)) {
       
  1033 				pl = t.elmClassPattern.exec(pa);
       
  1034 				x = s.getElementsByTagName(pl[1] || '*');
       
  1035 				c = ' ' + pl[2] + ' ';
       
  1036 
       
  1037 				for (i = 0, l = x.length; i<l; i++) {
       
  1038 					n = x[i];
       
  1039 
       
  1040 					if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1)
       
  1041 						o.push(n);
       
  1042 				}
       
  1043 
       
  1044 				return o;
       
  1045 			}
       
  1046 
       
  1047 			function collect(n) {
       
  1048 				if (!n.mce_save) {
       
  1049 					n.mce_save = 1;
       
  1050 					o.push(n);
       
  1051 				}
       
  1052 			};
       
  1053 
       
  1054 			function collectIE(n) {
       
  1055 				if (!n.getAttribute('mce_save')) {
       
  1056 					n.setAttribute('mce_save', '1');
       
  1057 					o.push(n);
       
  1058 				}
       
  1059 			};
       
  1060 
       
  1061 			function find(n, f, r) {
       
  1062 				var i, l, nl = r.getElementsByTagName(n);
       
  1063 
       
  1064 				for (i = 0, l = nl.length; i < l; i++)
       
  1065 					f(nl[i]);
       
  1066 			};
       
  1067 
       
  1068 			each(pa.split(','), function(v, i) {
       
  1069 				v = tinymce.trim(v);
       
  1070 
       
  1071 				// Simple element pattern, most common in TinyMCE
       
  1072 				if (t.elmPattern.test(v)) {
       
  1073 					each(s.getElementsByTagName(v), function(n) {
       
  1074 						collect(n);
       
  1075 					});
       
  1076 
       
  1077 					return;
       
  1078 				}
       
  1079 
       
  1080 				// Simple element pattern with class, fairly common in TinyMCE
       
  1081 				if (t.elmClassPattern.test(v)) {
       
  1082 					x = t.elmClassPattern.exec(v);
       
  1083 
       
  1084 					each(s.getElementsByTagName(x[1]), function(n) {
       
  1085 						if (t.hasClass(n, x[2]))
       
  1086 							collect(n);
       
  1087 					});
       
  1088 
       
  1089 					return;
       
  1090 				}
       
  1091 
       
  1092 				if (!(cs = t.cache[pa])) {
       
  1093 					cs = 'x=(function(cf, s) {';
       
  1094 					pl = v.split(' ');
       
  1095 
       
  1096 					each(pl, function(v) {
       
  1097 						var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v);
       
  1098 
       
  1099 						// Find elements
       
  1100 						p[1] = p[1] || '*';
       
  1101 						cs += 'find("' + p[1] + '", function(n) {';
       
  1102 
       
  1103 						// Check id
       
  1104 						if (p[2])
       
  1105 							cs += 'if (n.id !== "' + p[2] + '") return;';
       
  1106 
       
  1107 						// Check classes
       
  1108 						if (p[3]) {
       
  1109 							cs += 'var c = " " + n.className + " ";';
       
  1110 							cs += 'if (';
       
  1111 							c = '';
       
  1112 							each(p[3].split('.'), function(v) {
       
  1113 								if (v)
       
  1114 									c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1';
       
  1115 							});
       
  1116 							cs += c + ') return;';
       
  1117 						}
       
  1118 					});
       
  1119 
       
  1120 					cs += 'cf(n);';
       
  1121 
       
  1122 					for (i = pl.length - 1; i >= 0; i--)
       
  1123 						cs += '}, ' + (i ? 'n' : 's') + ');';
       
  1124 
       
  1125 					cs += '})';
       
  1126 
       
  1127 					// Compile CSS pattern function
       
  1128 					t.cache[pa] = cs = eval(cs);
       
  1129 				}
       
  1130 
       
  1131 				// Run selector function
       
  1132 				cs(isIE ? collectIE : collect, s);
       
  1133 			});
       
  1134 
       
  1135 			// Cleanup
       
  1136 			each(o, function(n) {
       
  1137 				if (isIE)
       
  1138 					n.removeAttribute('mce_save');
       
  1139 				else
       
  1140 					delete n.mce_save;
       
  1141 			});
       
  1142 
       
  1143 			return o;
       
  1144 		},
       
  1145 
       
  1146 		// #endif
       
  1147 
       
  1148 		add : function(p, n, a, h, c) {
       
  1149 			var t = this;
       
  1150 
       
  1151 			return this.run(p, function(p) {
       
  1152 				var e, k;
       
  1153 
       
  1154 				e = is(n, 'string') ? t.doc.createElement(n) : n;
       
  1155 
       
  1156 				if (a) {
       
  1157 					for (k in a) {
       
  1158 						if (a.hasOwnProperty(k) && !is(a[k], 'object'))
       
  1159 							t.setAttrib(e, k, '' + a[k]);
       
  1160 					}
       
  1161 
       
  1162 					if (a.style && !is(a.style, 'string')) {
       
  1163 						each(a.style, function(v, n) {
       
  1164 							t.setStyle(e, n, v);
       
  1165 						});
       
  1166 					}
       
  1167 				}
       
  1168 
       
  1169 				if (h) {
       
  1170 					if (h.nodeType)
       
  1171 						e.appendChild(h);
       
  1172 					else
       
  1173 						e.innerHTML = h;
       
  1174 				}
       
  1175 
       
  1176 				return !c ? p.appendChild(e) : e;
       
  1177 			});
       
  1178 		},
       
  1179 
       
  1180 		create : function(n, a, h) {
       
  1181 			return this.add(this.doc.createElement(n), n, a, h, 1);
       
  1182 		},
       
  1183 
       
  1184 		createHTML : function(n, a, h) {
       
  1185 			var o = '', t = this, k;
       
  1186 
       
  1187 			o += '<' + n;
       
  1188 
       
  1189 			for (k in a) {
       
  1190 				if (a.hasOwnProperty(k))
       
  1191 					o += ' ' + k + '="' + t.encode(a[k]) + '"';
       
  1192 			}
       
  1193 
       
  1194 			if (tinymce.is(h))
       
  1195 				return o + '>' + h + '</' + n + '>';
       
  1196 
       
  1197 			return o + ' />';
       
  1198 		},
       
  1199 
       
  1200 		remove : function(n, k) {
       
  1201 			return this.run(n, function(n) {
       
  1202 				var p;
       
  1203 
       
  1204 				p = n.parentNode;
       
  1205 
       
  1206 				if (!p)
       
  1207 					return null;
       
  1208 
       
  1209 				if (k) {
       
  1210 					each (n.childNodes, function(c) {
       
  1211 						p.insertBefore(c.cloneNode(true), n);
       
  1212 					});
       
  1213 				}
       
  1214 
       
  1215 				return p.removeChild(n);
       
  1216 			});
       
  1217 		},
       
  1218 
       
  1219 		// #if !jquery
       
  1220 
       
  1221 		setStyle : function(n, na, v) {
       
  1222 			return this.run(n, function(e) {
       
  1223 				var s, i;
       
  1224 
       
  1225 				s = e.style;
       
  1226 
       
  1227 				// Camelcase it, if needed
       
  1228 				na = na.replace(/-(\D)/g, function(a, b){
       
  1229 					return b.toUpperCase();
       
  1230 				});
       
  1231 
       
  1232 				// Default px suffix on these
       
  1233 				if (this.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))
       
  1234 					v += 'px';
       
  1235 
       
  1236 				switch (na) {
       
  1237 					case 'opacity':
       
  1238 						// IE specific opacity
       
  1239 						if (isIE) {
       
  1240 							s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";
       
  1241 
       
  1242 							if (!n.currentStyle || !n.currentStyle.hasLayout)
       
  1243 								s.display = 'inline-block';
       
  1244 						}
       
  1245 
       
  1246 						// Fix for older browsers
       
  1247 						s['-moz-opacity'] = s['-khtml-opacity'] = v;
       
  1248 						break;
       
  1249 
       
  1250 					case 'float':
       
  1251 						isIE ? s.styleFloat = v : s.cssFloat = v;
       
  1252 						break;
       
  1253 				}
       
  1254 
       
  1255 				s[na] = v;
       
  1256 			});
       
  1257 		},
       
  1258 
       
  1259 		getStyle : function(n, na, c) {
       
  1260 			n = this.get(n);
       
  1261 
       
  1262 			if (!n)
       
  1263 				return false;
       
  1264 
       
  1265 			// Gecko
       
  1266 			if (this.doc.defaultView && c) {
       
  1267 				// Remove camelcase
       
  1268 				na = na.replace(/[A-Z]/g, function(a){
       
  1269 					return '-' + a;
       
  1270 				});
       
  1271 
       
  1272 				try {
       
  1273 					return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);
       
  1274 				} catch (ex) {
       
  1275 					// Old safari might fail
       
  1276 					return null;
       
  1277 				}
       
  1278 			}
       
  1279 
       
  1280 			// Camelcase it, if needed
       
  1281 			na = na.replace(/-(\D)/g, function(a, b){
       
  1282 				return b.toUpperCase();
       
  1283 			});
       
  1284 
       
  1285 			if (na == 'float')
       
  1286 				na = isIE ? 'styleFloat' : 'cssFloat';
       
  1287 
       
  1288 			// IE & Opera
       
  1289 			if (n.currentStyle && c)
       
  1290 				return n.currentStyle[na];
       
  1291 
       
  1292 			return n.style[na];
       
  1293 		},
       
  1294 
       
  1295 		setStyles : function(e, o) {
       
  1296 			var t = this;
       
  1297 
       
  1298 			each(o, function(v, n) {
       
  1299 				t.setStyle(e, n, v);
       
  1300 			});
       
  1301 		},
       
  1302 
       
  1303 		setAttrib : function(e, n, v) {
       
  1304 			var t = this;
       
  1305 
       
  1306 			return this.run(e, function(e) {
       
  1307 				var s = t.settings;
       
  1308 
       
  1309 				switch (n) {
       
  1310 					case "style":
       
  1311 						if (s.keep_values) {
       
  1312 							if (v)
       
  1313 								e.setAttribute('mce_style', v, 2);
       
  1314 							else
       
  1315 								e.removeAttribute('mce_style', 2);
       
  1316 						}
       
  1317 
       
  1318 						e.style.cssText = v;
       
  1319 						break;
       
  1320 
       
  1321 					case "class":
       
  1322 						e.className = v;
       
  1323 						break;
       
  1324 
       
  1325 					case "src":
       
  1326 					case "href":
       
  1327 						if (s.keep_values) {
       
  1328 							if (s.url_converter)
       
  1329 								v = s.url_converter.call(s.url_converter_scope || t, v, n, e);
       
  1330 
       
  1331 							t.setAttrib(e, 'mce_' + n, v, 2);
       
  1332 						}
       
  1333 
       
  1334 						break;
       
  1335 				}
       
  1336 
       
  1337 				if (is(v) && v !== null && v.length !== 0)
       
  1338 					e.setAttribute(n, '' + v, 2);
       
  1339 				else
       
  1340 					e.removeAttribute(n, 2);
       
  1341 			});
       
  1342 		},
       
  1343 
       
  1344 		setAttribs : function(e, o) {
       
  1345 			var t = this;
       
  1346 
       
  1347 			return this.run(e, function(e) {
       
  1348 				each(o, function(v, n) {
       
  1349 					t.setAttrib(e, n, v);
       
  1350 				});
       
  1351 			});
       
  1352 		},
       
  1353 
       
  1354 		// #endif
       
  1355 
       
  1356 		getAttrib : function(e, n, dv) {
       
  1357 			var v, t = this;
       
  1358 
       
  1359 			e = t.get(e);
       
  1360 
       
  1361 			if (!e)
       
  1362 				return false;
       
  1363 
       
  1364 			if (!is(dv))
       
  1365 				dv = "";
       
  1366 
       
  1367 			// Try the mce variant for these
       
  1368 			if (/^(src|href|style)$/.test(n)) {
       
  1369 				v = t.getAttrib(e, "mce_" + n);
       
  1370 
       
  1371 				if (v)
       
  1372 					return v;
       
  1373 			}
       
  1374 
       
  1375 			v = e.getAttribute(n, 2);
       
  1376 
       
  1377 			if (!v) {
       
  1378 				switch (n) {
       
  1379 					case 'class':
       
  1380 						v = e.className;
       
  1381 						break;
       
  1382 
       
  1383 					default:
       
  1384 						v = e.attributes[n];
       
  1385 						v = v && is(v.nodeValue) ? v.nodeValue : v;
       
  1386 				}
       
  1387 			}
       
  1388 
       
  1389 			switch (n) {
       
  1390 				case 'style':
       
  1391 					v = v || e.style.cssText;
       
  1392 
       
  1393 					if (v) {
       
  1394 						v = t.serializeStyle(t.parseStyle(v));
       
  1395 
       
  1396 						if (t.settings.keep_values)
       
  1397 							e.setAttribute('mce_style', v);
       
  1398 					}
       
  1399 
       
  1400 					break;
       
  1401 			}
       
  1402 
       
  1403 			// Remove Apple and WebKit stuff
       
  1404 			if (isWebKit && n == "class" && v)
       
  1405 				v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');
       
  1406 
       
  1407 			// Handle IE issues
       
  1408 			if (isIE) {
       
  1409 				switch (n) {
       
  1410 					case 'rowspan':
       
  1411 					case 'colspan':
       
  1412 						// IE returns 1 as default value
       
  1413 						if (v === 1)
       
  1414 							v = '';
       
  1415 
       
  1416 						break;
       
  1417 
       
  1418 					case 'size':
       
  1419 						// IE returns +0 as default value for size
       
  1420 						if (v === '+0')
       
  1421 							v = '';
       
  1422 
       
  1423 						break;
       
  1424 
       
  1425 					case 'hspace':
       
  1426 						// IE returns -1 as default value
       
  1427 						if (v === -1)
       
  1428 							v = '';
       
  1429 
       
  1430 						break;
       
  1431 
       
  1432 					case 'tabindex':
       
  1433 						// IE returns 32768 as default value
       
  1434 						if (v === 32768)
       
  1435 							v = '';
       
  1436 
       
  1437 						break;
       
  1438 
       
  1439 					default:
       
  1440 						// IE has odd anonymous function for event attributes
       
  1441 						if (n.indexOf('on') === 0 && v)
       
  1442 							v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
       
  1443 				}
       
  1444 			}
       
  1445 
       
  1446 			return (v && v != '') ? '' + v : dv;
       
  1447 		},
       
  1448 
       
  1449 		getPos : function(n) {
       
  1450 			var t = this, x = 0, y = 0, e, d = t.doc;
       
  1451 
       
  1452 			n = t.get(n);
       
  1453 
       
  1454 			// Use getBoundingClientRect on IE, Opera has it but it's not perfect
       
  1455 			if (n && isIE) {
       
  1456 				n = n.getBoundingClientRect();
       
  1457 				e = t.boxModel ? d.documentElement : d.body;
       
  1458 				x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border
       
  1459 				x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;
       
  1460 				n.top += window.self != window.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
       
  1461 
       
  1462 				return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};
       
  1463 			}
       
  1464 
       
  1465 			while (n) {
       
  1466 				x += n.offsetLeft || 0;
       
  1467 				y += n.offsetTop || 0;
       
  1468 				x -= n.scrollLeft || 0;
       
  1469 				y -= n.scrollTop || 0;
       
  1470 				n = n.offsetParent;
       
  1471 			}
       
  1472 
       
  1473 			return {x : x, y : y};
       
  1474 		},
       
  1475 
       
  1476 		parseStyle : function(st) {
       
  1477 			var t = this, s = t.settings, o = {};
       
  1478 
       
  1479 			if (!st)
       
  1480 				return o;
       
  1481 
       
  1482 			function compress(p, s, ot) {
       
  1483 				var t, r, b, l;
       
  1484 
       
  1485 				// Get values and check it it needs compressing
       
  1486 				t = o[p + '-top' + s];
       
  1487 				if (!t)
       
  1488 					return;
       
  1489 
       
  1490 				r = o[p + '-right' + s];
       
  1491 				if (t != r)
       
  1492 					return;
       
  1493 
       
  1494 				b = o[p + '-bottom' + s];
       
  1495 				if (r != b)
       
  1496 					return;
       
  1497 
       
  1498 				l = o[p + '-left' + s];
       
  1499 				if (b != l)
       
  1500 					return;
       
  1501 
       
  1502 				// Compress
       
  1503 				o[ot] = l;
       
  1504 				delete o[p + '-top' + s];
       
  1505 				delete o[p + '-right' + s];
       
  1506 				delete o[p + '-bottom' + s];
       
  1507 				delete o[p + '-left' + s];
       
  1508 			};
       
  1509 
       
  1510 			function compress2(ta, a, b, c) {
       
  1511 				var t;
       
  1512 
       
  1513 				t = o[a];
       
  1514 				if (!t)
       
  1515 					return;
       
  1516 
       
  1517 				t = o[b];
       
  1518 				if (!t)
       
  1519 					return;
       
  1520 
       
  1521 				t = o[c];
       
  1522 				if (!t)
       
  1523 					return;
       
  1524 
       
  1525 				// Compress
       
  1526 				o[ta] = o[a] + ' ' + o[b] + ' ' + o[c];
       
  1527 				delete o[a];
       
  1528 				delete o[b];
       
  1529 				delete o[c];
       
  1530 			};
       
  1531 
       
  1532 			each(st.split(';'), function(v) {
       
  1533 				var sv, ur = [];
       
  1534 
       
  1535 				if (v) {
       
  1536 					v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';});
       
  1537 					v = v.split(':');
       
  1538 					sv = tinymce.trim(v[1]);
       
  1539 					sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];});
       
  1540 
       
  1541 					sv = sv.replace(/rgb\([^\)]+\)/g, function(v) {
       
  1542 						return t.toHex(v);
       
  1543 					});
       
  1544 
       
  1545 					if (s.url_converter) {
       
  1546 						sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) {
       
  1547 							return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null)) + ')';
       
  1548 						});
       
  1549 					}
       
  1550 
       
  1551 					o[tinymce.trim(v[0]).toLowerCase()] = sv;
       
  1552 				}
       
  1553 			});
       
  1554 
       
  1555 			compress("border", "", "border");
       
  1556 			compress("border", "-width", "border-width");
       
  1557 			compress("border", "-color", "border-color");
       
  1558 			compress("border", "-style", "border-style");
       
  1559 			compress("padding", "", "padding");
       
  1560 			compress("margin", "", "margin");
       
  1561 			compress2('border', 'border-width', 'border-style', 'border-color');
       
  1562 
       
  1563 			return o;
       
  1564 		},
       
  1565 
       
  1566 		serializeStyle : function(o) {
       
  1567 			var s = '';
       
  1568 
       
  1569 			each(o, function(v, k) {
       
  1570 				if (k && v) {
       
  1571 					switch (k) {
       
  1572 						case 'color':
       
  1573 						case 'background-color':
       
  1574 							v = v.toLowerCase();
       
  1575 							break;
       
  1576 					}
       
  1577 
       
  1578 					s += (s ? ' ' : '') + k + ': ' + v + ';';
       
  1579 				}
       
  1580 			});
       
  1581 
       
  1582 			return s;
       
  1583 		},
       
  1584 
       
  1585 		loadCSS : function(u) {
       
  1586 			var t = this, d = this.doc;
       
  1587 
       
  1588 			if (!u)
       
  1589 				u = '';
       
  1590 
       
  1591 			each(u.split(','), function(u) {
       
  1592 				if (t.files[u])
       
  1593 					return;
       
  1594 
       
  1595 				t.files[u] = true;
       
  1596 
       
  1597 				if (!d.createStyleSheet)
       
  1598 					t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : u});
       
  1599 				else
       
  1600 					d.createStyleSheet(u);
       
  1601 			});
       
  1602 		},
       
  1603 
       
  1604 		// #if !jquery
       
  1605 
       
  1606 		addClass : function(e, c) {
       
  1607 			return this.run(e, function(e) {
       
  1608 				var o;
       
  1609 
       
  1610 				if (!c)
       
  1611 					return 0;
       
  1612 
       
  1613 				if (this.hasClass(e, c))
       
  1614 					return e.className;
       
  1615 
       
  1616 				o = this.removeClass(e, c);
       
  1617 
       
  1618 				return e.className = (o != '' ? (o + ' ') : '') + c;
       
  1619 			});
       
  1620 		},
       
  1621 
       
  1622 		removeClass : function(e, c) {
       
  1623 			var t = this, re;
       
  1624 
       
  1625 			return t.run(e, function(e) {
       
  1626 				var v;
       
  1627 
       
  1628 				if (t.hasClass(e, c)) {
       
  1629 					if (!re)
       
  1630 						re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");
       
  1631 
       
  1632 					v = e.className.replace(re, ' ');
       
  1633 
       
  1634 					return e.className = tinymce.trim(v != ' ' ? v : '');
       
  1635 				}
       
  1636 
       
  1637 				return e.className;
       
  1638 			});
       
  1639 		},
       
  1640 
       
  1641 		hasClass : function(n, c) {
       
  1642 			n = this.get(n);
       
  1643 
       
  1644 			if (!n || !c)
       
  1645 				return false;
       
  1646 
       
  1647 			return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;
       
  1648 		},
       
  1649 
       
  1650 		show : function(e) {
       
  1651 			return this.setStyle(e, 'display', 'block');
       
  1652 		},
       
  1653 
       
  1654 		hide : function(e) {
       
  1655 			return this.setStyle(e, 'display', 'none');
       
  1656 		},
       
  1657 
       
  1658 		isHidden : function(e) {
       
  1659 			e = this.get(e);
       
  1660 
       
  1661 			return e.style.display == 'none' || this.getStyle(e, 'display') == 'none';
       
  1662 		},
       
  1663 
       
  1664 		// #endif
       
  1665 
       
  1666 		uniqueId : function(p) {
       
  1667 			return (!p ? 'mce_' : p) + (this.counter++);
       
  1668 		},
       
  1669 
       
  1670 		setHTML : function(e, h) {
       
  1671 			var t = this;
       
  1672 
       
  1673 			return this.run(e, function(e) {
       
  1674 				h = t.processHTML(h);
       
  1675 
       
  1676 				if (isIE) {
       
  1677 					// Fix for IE bug, first node comments gets stripped
       
  1678 					e.innerHTML = '<br />' + h;
       
  1679 					e.removeChild(e.firstChild);
       
  1680 				} else
       
  1681 					e.innerHTML = h;
       
  1682 
       
  1683 				return h;
       
  1684 			});
       
  1685 		},
       
  1686 
       
  1687 		processHTML : function(h) {
       
  1688 			var t = this, s = t.settings;
       
  1689 
       
  1690 			// Convert strong and em to b and i in FF since it can't handle them
       
  1691 			if (tinymce.isGecko) {
       
  1692 				h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');
       
  1693 				h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');
       
  1694 			}
       
  1695 
       
  1696 			// Store away src and href in mce_src and mce_href since browsers mess them up
       
  1697 			if (s.keep_values) {
       
  1698 				// Process all tags with src, href or style
       
  1699 				h = h.replace(/<([\w:]+) [^>]*(src|href|style)[^>]*>/gi, function(a, n) {
       
  1700 					function handle(m, b, c) {
       
  1701 						var u = c;
       
  1702 
       
  1703 						// Tag already got a mce_ version
       
  1704 						if (a.indexOf('mce_' + b) != -1)
       
  1705 							return m;
       
  1706 
       
  1707 						if (b == 'style') {
       
  1708 							// Why did I need this one?
       
  1709 							//if (isIE)
       
  1710 							//	u = t.serializeStyle(t.parseStyle(u));
       
  1711 
       
  1712 							if (s.hex_colors) {
       
  1713 								u = u.replace(/rgb\([^\)]+\)/g, function(v) {
       
  1714 									return t.toHex(v);
       
  1715 								});
       
  1716 							}
       
  1717 
       
  1718 							if (s.url_converter) {
       
  1719 								u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {
       
  1720 									return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';
       
  1721 								});
       
  1722 							}
       
  1723 						} else {
       
  1724 							if (s.url_converter)
       
  1725 								u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));
       
  1726 						}
       
  1727 
       
  1728 						return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"';
       
  1729 					};
       
  1730 
       
  1731 					a = a.replace(/ (src|href|style)=[\"]([^\"]+)[\"]/gi, handle); // W3C
       
  1732 					a = a.replace(/ (src|href|style)=[\']([^\']+)[\']/gi, handle); // W3C
       
  1733 
       
  1734 					return a.replace(/ (src|href|style)=([^\s\"\'>]+)/gi, handle); // IE
       
  1735 				});
       
  1736 			}
       
  1737 
       
  1738 			return h;
       
  1739 		},
       
  1740 
       
  1741 		getOuterHTML : function(e) {
       
  1742 			var d;
       
  1743 
       
  1744 			e = this.get(e);
       
  1745 
       
  1746 			if (!e)
       
  1747 				return null;
       
  1748 
       
  1749 			if (isIE)
       
  1750 				return e.outerHTML;
       
  1751 
       
  1752 			d = (e.ownerDocument || this.doc).createElement("body");
       
  1753 			d.appendChild(e.cloneNode(true));
       
  1754 
       
  1755 			return d.innerHTML;
       
  1756 		},
       
  1757 
       
  1758 		setOuterHTML : function(e, h, d) {
       
  1759 			var t = this;
       
  1760 
       
  1761 			return this.run(e, function(e) {
       
  1762 				var n, tp;
       
  1763 
       
  1764 				e = t.get(e);
       
  1765 				d = d || e.ownerDocument || t.doc;
       
  1766 
       
  1767 				if (isIE && e.nodeType == 1)
       
  1768 					e.outerHTML = h;
       
  1769 				else {
       
  1770 					tp = d.createElement("body");
       
  1771 					tp.innerHTML = h;
       
  1772 
       
  1773 					n = tp.lastChild;
       
  1774 					while (n) {
       
  1775 						t.insertAfter(n.cloneNode(true), e);
       
  1776 						n = n.previousSibling;
       
  1777 					}
       
  1778 
       
  1779 					t.remove(e);
       
  1780 				}
       
  1781 			});
       
  1782 		},
       
  1783 
       
  1784 		decode : function(s) {
       
  1785 			var e = document.createElement("div");
       
  1786 
       
  1787 			e.innerHTML = s;
       
  1788 
       
  1789 			return !e.firstChild ? s : e.firstChild.nodeValue;
       
  1790 		},
       
  1791 
       
  1792 		encode : function(s) {
       
  1793 			return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) {
       
  1794 				switch (c) {
       
  1795 					case '&':
       
  1796 						return '&amp;';
       
  1797 
       
  1798 					case '"':
       
  1799 						return '&quot;';
       
  1800 
       
  1801 					case '<':
       
  1802 						return '&lt;';
       
  1803 
       
  1804 					case '>':
       
  1805 						return '&gt;';
       
  1806 				}
       
  1807 
       
  1808 				return c;
       
  1809 			}) : s;
       
  1810 		},
       
  1811 
       
  1812 		// #if !jquery
       
  1813 
       
  1814 		insertAfter : function(n, r) {
       
  1815 			var t = this;
       
  1816 
       
  1817 			r = t.get(r);
       
  1818 
       
  1819 			return this.run(n, function(n) {
       
  1820 				var p, ns;
       
  1821 
       
  1822 				p = r.parentNode;
       
  1823 				ns = r.nextSibling;
       
  1824 
       
  1825 				if (ns)
       
  1826 					p.insertBefore(n, ns);
       
  1827 				else
       
  1828 					p.appendChild(n);
       
  1829 
       
  1830 				return n;
       
  1831 			});
       
  1832 		},
       
  1833 
       
  1834 		// #endif
       
  1835 
       
  1836 		isBlock : function(n) {
       
  1837 			if (n.nodeType && n.nodeType !== 1)
       
  1838 				return false;
       
  1839 
       
  1840 			n = n.nodeName || n;
       
  1841 
       
  1842 			return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);
       
  1843 		},
       
  1844 
       
  1845 		// #if !jquery
       
  1846 
       
  1847 		replace : function(n, o, k) {
       
  1848 			if (is(o, 'array'))
       
  1849 				n = n.cloneNode(true);
       
  1850 
       
  1851 			return this.run(o, function(o) {
       
  1852 				if (k) {
       
  1853 					each(o.childNodes, function(c) {
       
  1854 						n.appendChild(c.cloneNode(true));
       
  1855 					});
       
  1856 				}
       
  1857 
       
  1858 				return o.parentNode.replaceChild(n, o);
       
  1859 			});
       
  1860 		},
       
  1861 
       
  1862 		// #endif
       
  1863 
       
  1864 		toHex : function(s) {
       
  1865 			var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);
       
  1866 
       
  1867 			function hex(s) {
       
  1868 				s = parseInt(s).toString(16);
       
  1869 
       
  1870 				return s.length > 1 ? s : '0' + s; // 0 -> 00
       
  1871 			};
       
  1872 
       
  1873 			if (c) {
       
  1874 				s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]);
       
  1875 
       
  1876 				return s;
       
  1877 			}
       
  1878 
       
  1879 			return s;
       
  1880 		},
       
  1881 
       
  1882 		getClasses : function() {
       
  1883 			var t = this, cl = [], i, lo = {}, f = t.settings.class_filter;
       
  1884 
       
  1885 			if (t.classes)
       
  1886 				return t.classes;
       
  1887 
       
  1888 			function addClasses(s) {
       
  1889 				// IE style imports
       
  1890 				each(s.imports, function(r) {
       
  1891 					addClasses(r);
       
  1892 				});
       
  1893 
       
  1894 				each(s.cssRules || s.rules, function(r) {
       
  1895 					// Real type or fake it on IE
       
  1896 					switch (r.type || 1) {
       
  1897 						// Rule
       
  1898 						case 1:
       
  1899 							if (r.selectorText) {
       
  1900 								each(r.selectorText.split(','), function(v) {
       
  1901 									v = v.replace(/^\s*|\s*$|^\s\./g, "");
       
  1902 
       
  1903 									if (f && !(v = f(v)))
       
  1904 										return;
       
  1905 
       
  1906 									if (/^\.mce/.test(v) || !/^\.[\w\-]+$/.test(v))
       
  1907 										return;
       
  1908 
       
  1909 									v = v.substring(1);
       
  1910 									if (!lo[v]) {
       
  1911 										cl.push({'class' : v});
       
  1912 										lo[v] = 1;
       
  1913 									}
       
  1914 								});
       
  1915 							}
       
  1916 							break;
       
  1917 
       
  1918 						// Import
       
  1919 						case 3:
       
  1920 							addClasses(r.styleSheet);
       
  1921 							break;
       
  1922 					}
       
  1923 				});
       
  1924 			};
       
  1925 
       
  1926 			try {
       
  1927 				each(t.doc.styleSheets, addClasses);
       
  1928 			} catch (ex) {
       
  1929 				// Ignore
       
  1930 			}
       
  1931 
       
  1932 			if (cl.length > 0)
       
  1933 				t.classes = cl;
       
  1934 
       
  1935 			return cl;
       
  1936 		},
       
  1937 
       
  1938 		run : function(e, f, s) {
       
  1939 			var t = this, o;
       
  1940 
       
  1941 			if (typeof(e) === 'string')
       
  1942 				e = t.doc.getElementById(e);
       
  1943 
       
  1944 			if (!e)
       
  1945 				return false;
       
  1946 
       
  1947 			s = s || this;
       
  1948 			if (!e.nodeType && (e.length || e.length === 0)) {
       
  1949 				o = [];
       
  1950 
       
  1951 				each(e, function(e, i) {
       
  1952 					if (e) {
       
  1953 						if (typeof(e) == 'string')
       
  1954 							e = t.doc.getElementById(e);
       
  1955 
       
  1956 						o.push(f.call(s, e, i));
       
  1957 					}
       
  1958 				});
       
  1959 
       
  1960 				return o;
       
  1961 			}
       
  1962 
       
  1963 			return f.call(s, e);
       
  1964 		}
       
  1965 
       
  1966 		/*
       
  1967 		walk : function(n, f, s) {
       
  1968 			var d = this.doc, w;
       
  1969 
       
  1970 			if (d.createTreeWalker) {
       
  1971 				w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
       
  1972 
       
  1973 				while ((n = w.nextNode()) != null)
       
  1974 					f.call(s || this, n);
       
  1975 			} else
       
  1976 				tinymce.walk(n, f, 'childNodes', s);
       
  1977 		}
       
  1978 		*/
       
  1979 
       
  1980 		/*
       
  1981 		toRGB : function(s) {
       
  1982 			var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s);
       
  1983 
       
  1984 			if (c) {
       
  1985 				// #FFF -> #FFFFFF
       
  1986 				if (!is(c[3]))
       
  1987 					c[3] = c[2] = c[1];
       
  1988 
       
  1989 				return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")";
       
  1990 			}
       
  1991 
       
  1992 			return s;
       
  1993 		}
       
  1994 		*/
       
  1995 
       
  1996 		});
       
  1997 
       
  1998 	// Setup page DOM
       
  1999 	tinymce.DOM = new tinymce.dom.DOMUtils(document);
       
  2000 })();
       
  2001 
       
  2002 /* file:jscripts/tiny_mce/classes/dom/Event.js */
       
  2003 
       
  2004 (function() {
       
  2005 	// Shorten names
       
  2006 	var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;
       
  2007 
       
  2008 	tinymce.create('static tinymce.dom.Event', {
       
  2009 		inits : [],
       
  2010 		events : [],
       
  2011 
       
  2012 		// #if !jquery
       
  2013 
       
  2014 		add : function(o, n, f, s) {
       
  2015 			var cb, t = this, el = t.events, r;
       
  2016 
       
  2017 			// Handle array
       
  2018 			if (o && o instanceof Array) {
       
  2019 				r = [];
       
  2020 
       
  2021 				each(o, function(o) {
       
  2022 					o = DOM.get(o);
       
  2023 					r.push(t.add(o, n, f, s));
       
  2024 				});
       
  2025 
       
  2026 				return r;
       
  2027 			}
       
  2028 
       
  2029 			o = DOM.get(o);
       
  2030 
       
  2031 			if (!o)
       
  2032 				return;
       
  2033 
       
  2034 			// Setup event callback
       
  2035 			cb = function(e) {
       
  2036 				e = e || window.event;
       
  2037 
       
  2038 				// Patch in target in IE it's W3C valid
       
  2039 				if (e && !e.target && isIE)
       
  2040 					e.target = e.srcElement;
       
  2041 
       
  2042 				if (!s)
       
  2043 					return f(e);
       
  2044 
       
  2045 				return f.call(s, e);
       
  2046 			};
       
  2047 
       
  2048 			if (n == 'unload') {
       
  2049 				tinymce.unloads.unshift({func : cb});
       
  2050 				return cb;
       
  2051 			}
       
  2052 
       
  2053 			if (n == 'init') {
       
  2054 				if (t.domLoaded)
       
  2055 					cb();
       
  2056 				else
       
  2057 					t.inits.push(cb);
       
  2058 
       
  2059 				return cb;
       
  2060 			}
       
  2061 
       
  2062 			// Store away listener reference
       
  2063 			el.push({
       
  2064 				obj : o,
       
  2065 				name : n,
       
  2066 				func : f,
       
  2067 				cfunc : cb,
       
  2068 				scope : s
       
  2069 			});
       
  2070 
       
  2071 			t._add(o, n, cb);
       
  2072 
       
  2073 			return f;
       
  2074 		},
       
  2075 
       
  2076 		remove : function(o, n, f) {
       
  2077 			var t = this, a = t.events, s = false, r;
       
  2078 
       
  2079 			// Handle array
       
  2080 			if (o && o instanceof Array) {
       
  2081 				r = [];
       
  2082 
       
  2083 				each(o, function(o) {
       
  2084 					o = DOM.get(o);
       
  2085 					r.push(t.remove(o, n, f));
       
  2086 				});
       
  2087 
       
  2088 				return r;
       
  2089 			}
       
  2090 
       
  2091 			o = DOM.get(o);
       
  2092 
       
  2093 			each(a, function(e, i) {
       
  2094 				if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {
       
  2095 					a.splice(i, 1);
       
  2096 					t._remove(o, n, e.cfunc);
       
  2097 					s = true;
       
  2098 					return false;
       
  2099 				}
       
  2100 			});
       
  2101 
       
  2102 			return s;
       
  2103 		},
       
  2104 
       
  2105 		// #endif
       
  2106 
       
  2107 		cancel : function(e) {
       
  2108 			if (!e)
       
  2109 				return false;
       
  2110 
       
  2111 			this.stop(e);
       
  2112 			return this.prevent(e);
       
  2113 		},
       
  2114 
       
  2115 		stop : function(e) {
       
  2116 			if (e.stopPropagation)
       
  2117 				e.stopPropagation();
       
  2118 			else
       
  2119 				e.cancelBubble = true;
       
  2120 
  2688 			return false;
  2121 			return false;
  2689 
  2122 		},
  2690 		m = m.toLowerCase();
  2123 
  2691 		k = ie && !n ? k.toUpperCase() : k;
  2124 		prevent : function(e) {
  2692 		c = n ? null : k.charCodeAt(0);
  2125 			if (e.preventDefault)
  2693 		d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d;
  2126 				e.preventDefault();
  2694 
  2127 			else
  2695 		sc = {
  2128 				e.returnValue = false;
  2696 			alt : m.indexOf('alt') != -1,
  2129 
  2697 			ctrl : m.indexOf('ctrl') != -1,
       
  2698 			shift : m.indexOf('shift') != -1,
       
  2699 			charCode : c,
       
  2700 			keyCode : n ? k : (ie ? c : null),
       
  2701 			desc : d,
       
  2702 			cmd : cmd,
       
  2703 			ui : ui,
       
  2704 			val : va
       
  2705 		};
       
  2706 
       
  2707 		for (i=0; i<scl.length; i++) {
       
  2708 			if (sc.alt == scl[i].alt && sc.ctrl == scl[i].ctrl && sc.shift == scl[i].shift
       
  2709 				&& sc.charCode == scl[i].charCode && sc.keyCode == scl[i].keyCode) {
       
  2710 				return false;
       
  2711 			}
       
  2712 		}
       
  2713 
       
  2714 		scl[scl.length] = sc;
       
  2715 
       
  2716 		return true;
       
  2717 	},
       
  2718 
       
  2719 	handleShortcut : function(e) {
       
  2720 		var i, s, o;
       
  2721 
       
  2722 		// Normal key press, then ignore it
       
  2723 		if (!e.altKey && !e.ctrlKey)
       
  2724 			return false;
  2130 			return false;
  2725 
  2131 		},
  2726 		s = this.shortcuts;
  2132 
  2727 
  2133 		_unload : function() {
  2728 		for (i=0; i<s.length; i++) {
  2134 			var t = Event;
  2729 			o = s[i];
  2135 
  2730 
  2136 			each(t.events, function(e, i) {
  2731 			if (o.alt == e.altKey && o.ctrl == e.ctrlKey && (o.keyCode == e.keyCode || o.charCode == e.charCode)) {
  2137 				t._remove(e.obj, e.name, e.cfunc);
  2732 				if (o.cmd && (e.type == "keydown" || (e.type == "keypress" && !tinyMCE.isOpera)))
  2138 				e.obj = e.cfunc = null;
  2733 					tinyMCE.execCommand(o.cmd, o.ui, o.val);
  2139 			});
  2734 
  2140 
  2735 				tinyMCE.cancelEvent(e);
  2141 			t.events = [];
  2736 				return true;
  2142 			t = null;
  2737 			}
  2143 		},
  2738 		}
  2144 
  2739 
  2145 		_add : function(o, n, f) {
  2740 		return false;
  2146 			if (o.attachEvent)
  2741 	},
  2147 				o.attachEvent('on' + n, f);
  2742 
  2148 			else if (o.addEventListener)
  2743 	autoResetDesignMode : function() {
  2149 				o.addEventListener(n, f, false);
  2744 		// Add fix for tab/style.display none/block problems in Gecko
  2150 			else
  2745 		if (!tinyMCE.isIE && this.isHidden() && tinyMCE.getParam('auto_reset_designmode'))
  2151 				o['on' + n] = f;
  2746 			eval('try { this.getDoc().designMode = "On"; this.useCSS = false; } catch(e) {}');
  2152 		},
  2747 	},
  2153 
  2748 
  2154 		_remove : function(o, n, f) {
  2749 	isHidden : function() {
  2155 			if (o.detachEvent)
  2750 		var s;
  2156 				o.detachEvent('on' + n, f);
  2751 
  2157 			else if (o.removeEventListener)
  2752 		if (tinyMCE.isIE)
  2158 				o.removeEventListener(n, f, false);
  2753 			return false;
  2159 			else
  2754 
  2160 				o['on' + n] = null;
  2755 		s = this.getSel();
  2161 		},
  2756 
  2162 
  2757 		// Weird, wheres that cursor selection?
  2163 		_pageInit : function() {
  2758 		return (!s || !s.rangeCount || s.rangeCount == 0);
  2164 			var e = Event;
  2759 	},
  2165 
  2760 
  2166 			e._remove(window, 'DOMContentLoaded', e._pageInit);
  2761 	isDirty : function() {
  2167 			e.domLoaded = true;
  2762 		// Is content modified and not in a submit procedure
  2168 
  2763 		return tinyMCE.trim(this.startContent) != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty;
  2169 			each(e.inits, function(c) {
  2764 	},
  2170 				c();
  2765 
  2171 			});
  2766 	_mergeElements : function(scmd, pa, ch, override) {
  2172 
  2767 		if (scmd == "removeformat") {
  2173 			e.inits = [];
  2768 			pa.className = "";
  2174 		},
  2769 			pa.style.cssText = "";
  2175 
  2770 			ch.className = "";
  2176 		_wait : function() {
  2771 			ch.style.cssText = "";
  2177 			var t;
  2772 			return;
  2178 
  2773 		}
  2179 			// No need since the document is already loaded
  2774 
  2180 			if (window.tinyMCE_GZ && tinyMCE_GZ.loaded)
  2775 		var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
       
  2776 		var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
       
  2777 		var className = tinyMCE.getAttrib(pa, "class");
       
  2778 
       
  2779 		// Removed class adding due to bug #1478272
       
  2780 		className = tinyMCE.getAttrib(ch, "class");
       
  2781 
       
  2782 		if (override) {
       
  2783 			for (var n in st) {
       
  2784 				if (typeof(st[n]) == 'function')
       
  2785 					continue;
       
  2786 
       
  2787 				stc[n] = st[n];
       
  2788 			}
       
  2789 		} else {
       
  2790 			for (var n in stc) {
       
  2791 				if (typeof(stc[n]) == 'function')
       
  2792 					continue;
       
  2793 
       
  2794 				st[n] = stc[n];
       
  2795 			}
       
  2796 		}
       
  2797 
       
  2798 		tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st));
       
  2799 		tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className));
       
  2800 		ch.className = "";
       
  2801 		ch.style.cssText = "";
       
  2802 		ch.removeAttribute("class");
       
  2803 		ch.removeAttribute("style");
       
  2804 	},
       
  2805 
       
  2806 	_setUseCSS : function(b) {
       
  2807 		var d = this.getDoc();
       
  2808 
       
  2809 		try {d.execCommand("useCSS", false, !b);} catch (ex) {}
       
  2810 		try {d.execCommand("styleWithCSS", false, b);} catch (ex) {}
       
  2811 
       
  2812 		if (!tinyMCE.getParam("table_inline_editing"))
       
  2813 			try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {}
       
  2814 
       
  2815 		if (!tinyMCE.getParam("object_resizing"))
       
  2816 			try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {}
       
  2817 	},
       
  2818 
       
  2819 	execCommand : function(command, user_interface, value) {
       
  2820 		var doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement();
       
  2821 
       
  2822 		// Is not a undo specific command
       
  2823 		if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command))
       
  2824 			this.undoBookmark = null;
       
  2825 
       
  2826 		// Mozilla issue
       
  2827 		if (!tinyMCE.isIE && !this.useCSS) {
       
  2828 			this._setUseCSS(false);
       
  2829 			this.useCSS = true;
       
  2830 		}
       
  2831 
       
  2832 		//debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value);
       
  2833 		this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks
       
  2834 
       
  2835 		// Don't dispatch key commands
       
  2836 		if (!/mceStartTyping|mceEndTyping/.test(command)) {
       
  2837 			if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value))
       
  2838 				return;
  2181 				return;
  2839 		}
  2182 
  2840 
  2183 			if (isIE && document.location.protocol != 'https:') {
  2841 		// Fix align on images
  2184 				// Fake DOMContentLoaded on IE
  2842 		if (focusElm && focusElm.nodeName == "IMG") {
  2185 				document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');
  2843 			var align = focusElm.getAttribute('align');
  2186 				DOM.get("__ie_onload").onreadystatechange = function() {
  2844 			var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
  2187 					if (this.readyState == "complete") {
  2845 
  2188 						Event._pageInit();
  2846 			switch (command) {
  2189 						DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak
  2847 				case "JustifyLeft":
       
  2848 					if (align == 'left')
       
  2849 						img.removeAttribute('align');
       
  2850 					else
       
  2851 						img.setAttribute('align', 'left');
       
  2852 
       
  2853 					// Remove the div
       
  2854 					var div = focusElm.parentNode;
       
  2855 					if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
       
  2856 						div.parentNode.replaceChild(img, div);
       
  2857 
       
  2858 					this.selection.selectNode(img);
       
  2859 					this.repaint();
       
  2860 					tinyMCE.triggerNodeChange();
       
  2861 					return;
       
  2862 
       
  2863 				case "JustifyCenter":
       
  2864 					img.removeAttribute('align');
       
  2865 
       
  2866 					// Is centered
       
  2867 					var div = tinyMCE.getParentElement(focusElm, "div");
       
  2868 					if (div && div.style.textAlign == "center") {
       
  2869 						// Remove div
       
  2870 						if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
       
  2871 							div.parentNode.replaceChild(img, div);
       
  2872 					} else {
       
  2873 						// Add div
       
  2874 						var div = this.getDoc().createElement("div");
       
  2875 						div.style.textAlign = 'center';
       
  2876 						div.appendChild(img);
       
  2877 						focusElm.parentNode.replaceChild(div, focusElm);
       
  2878 					}
  2190 					}
  2879 
       
  2880 					this.selection.selectNode(img);
       
  2881 					this.repaint();
       
  2882 					tinyMCE.triggerNodeChange();
       
  2883 					return;
       
  2884 
       
  2885 				case "JustifyRight":
       
  2886 					if (align == 'right')
       
  2887 						img.removeAttribute('align');
       
  2888 					else
       
  2889 						img.setAttribute('align', 'right');
       
  2890 
       
  2891 					// Remove the div
       
  2892 					var div = focusElm.parentNode;
       
  2893 					if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
       
  2894 						div.parentNode.replaceChild(img, div);
       
  2895 
       
  2896 					this.selection.selectNode(img);
       
  2897 					this.repaint();
       
  2898 					tinyMCE.triggerNodeChange();
       
  2899 					return;
       
  2900 			}
       
  2901 		}
       
  2902 
       
  2903 		if (tinyMCE.settings['force_br_newlines']) {
       
  2904 			var alignValue = "";
       
  2905 
       
  2906 			if (doc.selection.type != "Control") {
       
  2907 				switch (command) {
       
  2908 						case "JustifyLeft":
       
  2909 							alignValue = "left";
       
  2910 							break;
       
  2911 
       
  2912 						case "JustifyCenter":
       
  2913 							alignValue = "center";
       
  2914 							break;
       
  2915 
       
  2916 						case "JustifyFull":
       
  2917 							alignValue = "justify";
       
  2918 							break;
       
  2919 
       
  2920 						case "JustifyRight":
       
  2921 							alignValue = "right";
       
  2922 							break;
       
  2923 				}
       
  2924 
       
  2925 				if (alignValue != "") {
       
  2926 					var rng = doc.selection.createRange();
       
  2927 
       
  2928 					if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null)
       
  2929 						divElm.setAttribute("align", alignValue);
       
  2930 					else if (rng.pasteHTML && rng.htmlText.length > 0)
       
  2931 						rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>");
       
  2932 
       
  2933 					tinyMCE.triggerNodeChange();
       
  2934 					return;
       
  2935 				}
       
  2936 			}
       
  2937 		}
       
  2938 
       
  2939 		switch (command) {
       
  2940 			case "mceRepaint":
       
  2941 				this.repaint();
       
  2942 				return true;
       
  2943 
       
  2944 			case "unlink":
       
  2945 				// Unlink if caret is inside link
       
  2946 				if (tinyMCE.isGecko && this.getSel().isCollapsed) {
       
  2947 					focusElm = tinyMCE.getParentElement(focusElm, 'A');
       
  2948 
       
  2949 					if (focusElm)
       
  2950 						this.selection.selectNode(focusElm, false);
       
  2951 				}
       
  2952 
       
  2953 				this.getDoc().execCommand(command, user_interface, value);
       
  2954 
       
  2955 				tinyMCE.isGecko && this.getSel().collapseToEnd();
       
  2956 
       
  2957 				tinyMCE.triggerNodeChange();
       
  2958 
       
  2959 				return true;
       
  2960 
       
  2961 			case "InsertUnorderedList":
       
  2962 			case "InsertOrderedList":
       
  2963 				this.getDoc().execCommand(command, user_interface, value);
       
  2964 				tinyMCE.triggerNodeChange();
       
  2965 				break;
       
  2966 
       
  2967 			case "Strikethrough":
       
  2968 				this.getDoc().execCommand(command, user_interface, value);
       
  2969 				tinyMCE.triggerNodeChange();
       
  2970 				break;
       
  2971 
       
  2972 			case "mceSelectNode":
       
  2973 				this.selection.selectNode(value);
       
  2974 				tinyMCE.triggerNodeChange();
       
  2975 				tinyMCE.selectedNode = value;
       
  2976 				break;
       
  2977 
       
  2978 			case "FormatBlock":
       
  2979 				if (value == null || value == "") {
       
  2980 					var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp");
       
  2981 
       
  2982 					if (elm)
       
  2983 						this.execCommand("mceRemoveNode", false, elm);
       
  2984 				} else {
       
  2985 					if (!this.cleanup.isValid(value))
       
  2986 						return true;
       
  2987 
       
  2988 					if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value))
       
  2989 						value = value.replace(/[^a-z]/gi, '');
       
  2990 
       
  2991 					if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) {
       
  2992 						var b = this.selection.getBookmark();
       
  2993 						this.getDoc().execCommand("FormatBlock", false, '<p>');
       
  2994 						tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value);
       
  2995 						this.selection.moveToBookmark(b);
       
  2996 					} else
       
  2997 						this.getDoc().execCommand("FormatBlock", false, value);
       
  2998 				}
       
  2999 
       
  3000 				tinyMCE.triggerNodeChange();
       
  3001 
       
  3002 				break;
       
  3003 
       
  3004 			case "mceRemoveNode":
       
  3005 				if (!value)
       
  3006 					value = tinyMCE.getParentElement(this.getFocusElement());
       
  3007 
       
  3008 				if (tinyMCE.isIE) {
       
  3009 					value.outerHTML = value.innerHTML;
       
  3010 				} else {
       
  3011 					var rng = value.ownerDocument.createRange();
       
  3012 					rng.setStartBefore(value);
       
  3013 					rng.setEndAfter(value);
       
  3014 					rng.deleteContents();
       
  3015 					rng.insertNode(rng.createContextualFragment(value.innerHTML));
       
  3016 				}
       
  3017 
       
  3018 				tinyMCE.triggerNodeChange();
       
  3019 
       
  3020 				break;
       
  3021 
       
  3022 			case "mceSelectNodeDepth":
       
  3023 				var parentNode = this.getFocusElement();
       
  3024 				for (var i=0; parentNode; i++) {
       
  3025 					if (parentNode.nodeName.toLowerCase() == "body")
       
  3026 						break;
       
  3027 
       
  3028 					if (parentNode.nodeName.toLowerCase() == "#text") {
       
  3029 						i--;
       
  3030 						parentNode = parentNode.parentNode;
       
  3031 						continue;
       
  3032 					}
       
  3033 
       
  3034 					if (i == value) {
       
  3035 						this.selection.selectNode(parentNode, false);
       
  3036 						tinyMCE.triggerNodeChange();
       
  3037 						tinyMCE.selectedNode = parentNode;
       
  3038 						return;
       
  3039 					}
       
  3040 
       
  3041 					parentNode = parentNode.parentNode;
       
  3042 				}
       
  3043 
       
  3044 				break;
       
  3045 
       
  3046 			case "mceSetStyleInfo":
       
  3047 			case "SetStyleInfo":
       
  3048 				var rng = this.getRng();
       
  3049 				var sel = this.getSel();
       
  3050 				var scmd = value['command'];
       
  3051 				var sname = value['name'];
       
  3052 				var svalue = value['value'] == null ? '' : value['value'];
       
  3053 				//var svalue = value['value'] == null ? '' : value['value'];
       
  3054 				var wrapper = value['wrapper'] ? value['wrapper'] : "span";
       
  3055 				var parentElm = null;
       
  3056 				var invalidRe = new RegExp("^BODY|HTML$", "g");
       
  3057 				var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;
       
  3058 
       
  3059 				// Whole element selected check
       
  3060 				if (tinyMCE.isIE) {
       
  3061 					// Control range
       
  3062 					if (rng.item)
       
  3063 						parentElm = rng.item(0);
       
  3064 					else {
       
  3065 						var pelm = rng.parentElement();
       
  3066 						var prng = doc.selection.createRange();
       
  3067 						prng.moveToElementText(pelm);
       
  3068 
       
  3069 						if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) {
       
  3070 							if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName))
       
  3071 								parentElm = pelm;
       
  3072 						}
       
  3073 					}
       
  3074 				} else {
       
  3075 					var felm = this.getFocusElement();
       
  3076 					if (sel.isCollapsed || (new RegExp('td|tr|tbody|table', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode))
       
  3077 						parentElm = felm;
       
  3078 				}
       
  3079 
       
  3080 				// Whole element selected
       
  3081 				if (parentElm && !invalidRe.test(parentElm.nodeName)) {
       
  3082 					if (scmd == "setstyle")
       
  3083 						tinyMCE.setStyleAttrib(parentElm, sname, svalue);
       
  3084 
       
  3085 					if (scmd == "setattrib")
       
  3086 						tinyMCE.setAttrib(parentElm, sname, svalue);
       
  3087 
       
  3088 					if (scmd == "removeformat") {
       
  3089 						parentElm.style.cssText = '';
       
  3090 						tinyMCE.setAttrib(parentElm, 'class', '');
       
  3091 					}
       
  3092 
       
  3093 					// Remove style/attribs from all children
       
  3094 					var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1);
       
  3095 					for (var z=0; z<ch.length; z++) {
       
  3096 						if (ch[z] == parentElm)
       
  3097 							continue;
       
  3098 
       
  3099 						if (scmd == "setstyle")
       
  3100 							tinyMCE.setStyleAttrib(ch[z], sname, '');
       
  3101 
       
  3102 						if (scmd == "setattrib")
       
  3103 							tinyMCE.setAttrib(ch[z], sname, '');
       
  3104 
       
  3105 						if (scmd == "removeformat") {
       
  3106 							ch[z].style.cssText = '';
       
  3107 							tinyMCE.setAttrib(ch[z], 'class', '');
       
  3108 						}
       
  3109 					}
       
  3110 				} else {
       
  3111 					this._setUseCSS(false); // Bug in FF when running in fullscreen
       
  3112 					doc.execCommand("FontName", false, "#mce_temp_font#");
       
  3113 					var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#");
       
  3114 
       
  3115 					// Change them all
       
  3116 					for (var x=0; x<elementArray.length; x++) {
       
  3117 						elm = elementArray[x];
       
  3118 						if (elm) {
       
  3119 							var spanElm = doc.createElement(wrapper);
       
  3120 
       
  3121 							if (scmd == "setstyle")
       
  3122 								tinyMCE.setStyleAttrib(spanElm, sname, svalue);
       
  3123 
       
  3124 							if (scmd == "setattrib")
       
  3125 								tinyMCE.setAttrib(spanElm, sname, svalue);
       
  3126 
       
  3127 							if (scmd == "removeformat") {
       
  3128 								spanElm.style.cssText = '';
       
  3129 								tinyMCE.setAttrib(spanElm, 'class', '');
       
  3130 							}
       
  3131 
       
  3132 							if (elm.hasChildNodes()) {
       
  3133 								for (var i=0; i<elm.childNodes.length; i++)
       
  3134 									spanElm.appendChild(elm.childNodes[i].cloneNode(true));
       
  3135 							}
       
  3136 
       
  3137 							spanElm.setAttribute("mce_new", "true");
       
  3138 							elm.parentNode.replaceChild(spanElm, elm);
       
  3139 
       
  3140 							// Remove style/attribs from all children
       
  3141 							var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1);
       
  3142 							for (var z=0; z<ch.length; z++) {
       
  3143 								if (ch[z] == spanElm)
       
  3144 									continue;
       
  3145 
       
  3146 								if (scmd == "setstyle")
       
  3147 									tinyMCE.setStyleAttrib(ch[z], sname, '');
       
  3148 
       
  3149 								if (scmd == "setattrib")
       
  3150 									tinyMCE.setAttrib(ch[z], sname, '');
       
  3151 
       
  3152 								if (scmd == "removeformat") {
       
  3153 									ch[z].style.cssText = '';
       
  3154 									tinyMCE.setAttrib(ch[z], 'class', '');
       
  3155 								}
       
  3156 							}
       
  3157 						}
       
  3158 					}
       
  3159 				}
       
  3160 
       
  3161 				// Cleaup wrappers
       
  3162 				var nodes = doc.getElementsByTagName(wrapper);
       
  3163 				for (var i=nodes.length-1; i>=0; i--) {
       
  3164 					var elm = nodes[i];
       
  3165 					var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true";
       
  3166 
       
  3167 					elm.removeAttribute("mce_new");
       
  3168 
       
  3169 					// Is only child a element
       
  3170 					if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) {
       
  3171 						//tinyMCE.debug("merge1" + isNew);
       
  3172 						this._mergeElements(scmd, elm, elm.childNodes[0], isNew);
       
  3173 						continue;
       
  3174 					}
       
  3175 
       
  3176 					// Is I the only child
       
  3177 					if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) {
       
  3178 						//tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName);
       
  3179 						if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName))
       
  3180 							this._mergeElements(scmd, elm.parentNode, elm, false);
       
  3181 					}
       
  3182 				}
       
  3183 
       
  3184 				// Remove empty wrappers
       
  3185 				var nodes = doc.getElementsByTagName(wrapper);
       
  3186 				for (var i=nodes.length-1; i>=0; i--) {
       
  3187 					var elm = nodes[i];
       
  3188 					var isEmpty = true;
       
  3189 
       
  3190 					// Check if it has any attribs
       
  3191 					var tmp = doc.createElement("body");
       
  3192 					tmp.appendChild(elm.cloneNode(false));
       
  3193 
       
  3194 					// Is empty span, remove it
       
  3195 					tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), '');
       
  3196 					//tinyMCE.debug(tmp.innerHTML);
       
  3197 					if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {
       
  3198 						for (var x=0; x<elm.childNodes.length; x++) {
       
  3199 							if (elm.parentNode != null)
       
  3200 								elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm);
       
  3201 						}
       
  3202 
       
  3203 						elm.parentNode.removeChild(elm);
       
  3204 					}
       
  3205 				}
       
  3206 
       
  3207 				// Re add the visual aids
       
  3208 				if (scmd == "removeformat")
       
  3209 					tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
       
  3210 
       
  3211 				tinyMCE.triggerNodeChange();
       
  3212 
       
  3213 				break;
       
  3214 
       
  3215 			case "FontName":
       
  3216 				if (value == null) {
       
  3217 					var s = this.getSel();
       
  3218 
       
  3219 					// Find font and select it
       
  3220 					if (tinyMCE.isGecko && s.isCollapsed) {
       
  3221 						var f = tinyMCE.getParentElement(this.getFocusElement(), "font");
       
  3222 
       
  3223 						if (f != null)
       
  3224 							this.selection.selectNode(f, false);
       
  3225 					}
       
  3226 
       
  3227 					// Remove format
       
  3228 					this.getDoc().execCommand("RemoveFormat", false, null);
       
  3229 
       
  3230 					// Collapse range if font was found
       
  3231 					if (f != null && tinyMCE.isGecko) {
       
  3232 						var r = this.getRng().cloneRange();
       
  3233 						r.collapse(true);
       
  3234 						s.removeAllRanges();
       
  3235 						s.addRange(r);
       
  3236 					}
       
  3237 				} else
       
  3238 					this.getDoc().execCommand('FontName', false, value);
       
  3239 
       
  3240 				if (tinyMCE.isGecko)
       
  3241 					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
       
  3242 
       
  3243 				return;
       
  3244 
       
  3245 			case "FontSize":
       
  3246 				this.getDoc().execCommand('FontSize', false, value);
       
  3247 
       
  3248 				if (tinyMCE.isGecko)
       
  3249 					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
       
  3250 
       
  3251 				return;
       
  3252 
       
  3253 			case "forecolor":
       
  3254 				value = value == null ? this.foreColor : value;
       
  3255 				value = tinyMCE.trim(value);
       
  3256 				value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value;
       
  3257 
       
  3258 				this.foreColor = value;
       
  3259 				this.getDoc().execCommand('forecolor', false, value);
       
  3260 				break;
       
  3261 
       
  3262 			case "HiliteColor":
       
  3263 				value = value == null ? this.backColor : value;
       
  3264 				value = tinyMCE.trim(value);
       
  3265 				value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value;
       
  3266 				this.backColor = value;
       
  3267 
       
  3268 				if (tinyMCE.isGecko) {
       
  3269 					this._setUseCSS(true);
       
  3270 					this.getDoc().execCommand('hilitecolor', false, value);
       
  3271 					this._setUseCSS(false);
       
  3272 				} else
       
  3273 					this.getDoc().execCommand('BackColor', false, value);
       
  3274 				break;
       
  3275 
       
  3276 			case "Cut":
       
  3277 			case "Copy":
       
  3278 			case "Paste":
       
  3279 				var cmdFailed = false;
       
  3280 
       
  3281 				// Try executing command
       
  3282 				eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');
       
  3283 
       
  3284 				if (tinyMCE.isOpera && cmdFailed)
       
  3285 					alert('Currently not supported by your browser, use keyboard shortcuts instead.');
       
  3286 
       
  3287 				// Alert error in gecko if command failed
       
  3288 				if (tinyMCE.isGecko && cmdFailed) {
       
  3289 					// Confirm more info
       
  3290 					if (confirm(tinyMCE.entityDecode(tinyMCE.getLang('lang_clipboard_msg'))))
       
  3291 						window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
       
  3292 
       
  3293 					return;
       
  3294 				} else
       
  3295 					tinyMCE.triggerNodeChange();
       
  3296 			break;
       
  3297 
       
  3298 			case "mceSetContent":
       
  3299 				if (!value)
       
  3300 					value = "";
       
  3301 
       
  3302 				// Call custom cleanup code
       
  3303 				value = tinyMCE.storeAwayURLs(value);
       
  3304 				value = tinyMCE._customCleanup(this, "insert_to_editor", value);
       
  3305 
       
  3306 				if (this.getBody().nodeName == 'BODY')
       
  3307 					tinyMCE._setHTML(doc, value);
       
  3308 				else
       
  3309 					this.getBody().innerHTML = value;
       
  3310 
       
  3311 				tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, doc, this.settings, this.getBody(), false, false, false, true));
       
  3312 				tinyMCE.convertAllRelativeURLs(this.getBody());
       
  3313 
       
  3314 				// Cleanup any mess left from storyAwayURLs
       
  3315 				tinyMCE._removeInternal(this.getBody());
       
  3316 
       
  3317 				// When editing always use fonts internaly
       
  3318 				if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  3319 					tinyMCE.convertSpansToFonts(doc);
       
  3320 
       
  3321 				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
       
  3322 				tinyMCE._setEventsEnabled(this.getBody(), false);
       
  3323 				return true;
       
  3324 
       
  3325 			case "mceCleanup":
       
  3326 				var b = this.selection.getBookmark();
       
  3327 				tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML);
       
  3328 				tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid));
       
  3329 				tinyMCE.convertAllRelativeURLs(doc.body);
       
  3330 
       
  3331 				// When editing always use fonts internaly
       
  3332 				if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  3333 					tinyMCE.convertSpansToFonts(doc);
       
  3334 
       
  3335 				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
       
  3336 				tinyMCE._setEventsEnabled(this.getBody(), false);
       
  3337 				this.repaint();
       
  3338 				this.selection.moveToBookmark(b);
       
  3339 				tinyMCE.triggerNodeChange();
       
  3340 			break;
       
  3341 
       
  3342 			case "mceReplaceContent":
       
  3343 				// Force empty string
       
  3344 				if (!value)
       
  3345 					value = '';
       
  3346 
       
  3347 				this.getWin().focus();
       
  3348 
       
  3349 				var selectedText = "";
       
  3350 
       
  3351 				if (tinyMCE.isIE) {
       
  3352 					var rng = doc.selection.createRange();
       
  3353 					selectedText = rng.text;
       
  3354 				} else
       
  3355 					selectedText = this.getSel().toString();
       
  3356 
       
  3357 				if (selectedText.length > 0) {
       
  3358 					value = tinyMCE.replaceVar(value, "selection", selectedText);
       
  3359 					tinyMCE.execCommand('mceInsertContent', false, value);
       
  3360 				}
       
  3361 
       
  3362 				tinyMCE.triggerNodeChange();
       
  3363 			break;
       
  3364 
       
  3365 			case "mceSetAttribute":
       
  3366 				if (typeof(value) == 'object') {
       
  3367 					var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets'];
       
  3368 					var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms);
       
  3369 
       
  3370 					if (targetNode) {
       
  3371 						targetNode.setAttribute(value['name'], value['value']);
       
  3372 						tinyMCE.triggerNodeChange();
       
  3373 					}
       
  3374 				}
       
  3375 			break;
       
  3376 
       
  3377 			case "mceSetCSSClass":
       
  3378 				this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value});
       
  3379 			break;
       
  3380 
       
  3381 			case "mceInsertRawHTML":
       
  3382 				var key = 'tiny_mce_marker';
       
  3383 
       
  3384 				this.execCommand('mceBeginUndoLevel');
       
  3385 
       
  3386 				// Insert marker key
       
  3387 				this.execCommand('mceInsertContent', false, key);
       
  3388 
       
  3389 				// Store away scroll pos
       
  3390 				var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft;
       
  3391 				var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop;
       
  3392 
       
  3393 				// Find marker and replace with RAW HTML
       
  3394 				var html = this.getBody().innerHTML;
       
  3395 				if ((pos = html.indexOf(key)) != -1)
       
  3396 					tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length));
       
  3397 
       
  3398 				// Restore scoll pos
       
  3399 				this.contentWindow.scrollTo(scrollX, scrollY);
       
  3400 
       
  3401 				this.execCommand('mceEndUndoLevel');
       
  3402 
       
  3403 				break;
       
  3404 
       
  3405 			case "mceInsertContent":
       
  3406 				// Force empty string
       
  3407 				if (!value)
       
  3408 					value = '';
       
  3409 
       
  3410 				var insertHTMLFailed = false;
       
  3411 
       
  3412 				// Removed since it produced problems in IE
       
  3413 				// this.getWin().focus();
       
  3414 
       
  3415 				if (tinyMCE.isGecko || tinyMCE.isOpera) {
       
  3416 					try {
       
  3417 						// Is plain text or HTML, &amp;, &nbsp; etc will be encoded wrong in FF
       
  3418 						if (value.indexOf('<') == -1 && !value.match(/(&#38;|&#160;|&#60;|&#62;)/g)) {
       
  3419 							var r = this.getRng();
       
  3420 							var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value));
       
  3421 							var s = this.getSel();
       
  3422 							var r2 = r.cloneRange();
       
  3423 
       
  3424 							// Insert text at cursor position
       
  3425 							s.removeAllRanges();
       
  3426 							r.deleteContents();
       
  3427 							r.insertNode(n);
       
  3428 
       
  3429 							// Move the cursor to the end of text
       
  3430 							r2.selectNode(n);
       
  3431 							r2.collapse(false);
       
  3432 							s.removeAllRanges();
       
  3433 							s.addRange(r2);
       
  3434 						} else {
       
  3435 							value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value);
       
  3436 							this.getDoc().execCommand('inserthtml', false, value);
       
  3437 							tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
       
  3438 						}
       
  3439 					} catch (ex) {
       
  3440 						insertHTMLFailed = true;
       
  3441 					}
       
  3442 
       
  3443 					if (!insertHTMLFailed) {
       
  3444 						tinyMCE.triggerNodeChange();
       
  3445 						return;
       
  3446 					}
       
  3447 				}
       
  3448 
       
  3449 				if (!tinyMCE.isIE) {
       
  3450 					var isHTML = value.indexOf('<') != -1;
       
  3451 					var sel = this.getSel();
       
  3452 					var rng = this.getRng();
       
  3453 
       
  3454 					if (isHTML) {
       
  3455 						if (tinyMCE.isSafari) {
       
  3456 							var tmpRng = this.getDoc().createRange();
       
  3457 
       
  3458 							tmpRng.setStart(this.getBody(), 0);
       
  3459 							tmpRng.setEnd(this.getBody(), 0);
       
  3460 
       
  3461 							value = tmpRng.createContextualFragment(value);
       
  3462 						} else
       
  3463 							value = rng.createContextualFragment(value);
       
  3464 					} else {
       
  3465 						// Setup text node
       
  3466 						var el = document.createElement("div");
       
  3467 						el.innerHTML = value;
       
  3468 						value = el.firstChild.nodeValue;
       
  3469 						value = doc.createTextNode(value);
       
  3470 					}
       
  3471 
       
  3472 					// Insert plain text in Safari
       
  3473 					if (tinyMCE.isSafari && !isHTML) {
       
  3474 						this.execCommand('InsertText', false, value.nodeValue);
       
  3475 						tinyMCE.triggerNodeChange();
       
  3476 						return true;
       
  3477 					} else if (tinyMCE.isSafari && isHTML) {
       
  3478 						rng.deleteContents();
       
  3479 						rng.insertNode(value);
       
  3480 						tinyMCE.triggerNodeChange();
       
  3481 						return true;
       
  3482 					}
       
  3483 
       
  3484 					rng.deleteContents();
       
  3485 
       
  3486 					// If target node is text do special treatment, (Mozilla 1.3 fix)
       
  3487 					if (rng.startContainer.nodeType == 3) {
       
  3488 						var node = rng.startContainer.splitText(rng.startOffset);
       
  3489 						node.parentNode.insertBefore(value, node); 
       
  3490 					} else
       
  3491 						rng.insertNode(value);
       
  3492 
       
  3493 					if (!isHTML) {
       
  3494 						// Removes weird selection trails
       
  3495 						sel.selectAllChildren(doc.body);
       
  3496 						sel.removeAllRanges();
       
  3497 
       
  3498 						// Move cursor to end of content
       
  3499 						var rng = doc.createRange();
       
  3500 
       
  3501 						rng.selectNode(value);
       
  3502 						rng.collapse(false);
       
  3503 
       
  3504 						sel.addRange(rng);
       
  3505 					} else
       
  3506 						rng.collapse(false);
       
  3507 
       
  3508 					tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
       
  3509 				} else {
       
  3510 					var rng = doc.selection.createRange(), tmpRng = null;
       
  3511 					var c = value.indexOf('<!--') != -1;
       
  3512 
       
  3513 					// Fix comment bug, add tag before comments
       
  3514 					if (c)
       
  3515 						value = tinyMCE.uniqueTag + value;
       
  3516 
       
  3517 					//	tmpRng = rng.duplicate(); // Store away range (Fixes Undo bookmark bug in IE)
       
  3518 
       
  3519 					if (rng.item)
       
  3520 						rng.item(0).outerHTML = value;
       
  3521 					else
       
  3522 						rng.pasteHTML(value);
       
  3523 
       
  3524 					//if (tmpRng)
       
  3525 					//	tmpRng.select(); // Restore range  (Fixes Undo bookmark bug in IE)
       
  3526 
       
  3527 					// Remove unique tag
       
  3528 					if (c) {
       
  3529 						var e = this.getDoc().getElementById('mceTMPElement');
       
  3530 						e.parentNode.removeChild(e);
       
  3531 					}
       
  3532 				}
       
  3533 
       
  3534 				tinyMCE.execCommand("mceAddUndoLevel");
       
  3535 				tinyMCE.triggerNodeChange();
       
  3536 			break;
       
  3537 
       
  3538 			case "mceStartTyping":
       
  3539 				if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex == -1) {
       
  3540 					this.undoRedo.typingUndoIndex = this.undoRedo.undoIndex;
       
  3541 					tinyMCE.typingUndoIndex = tinyMCE.undoIndex;
       
  3542 					this.execCommand('mceAddUndoLevel');
       
  3543 				}
       
  3544 				break;
       
  3545 
       
  3546 			case "mceEndTyping":
       
  3547 				if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex != -1) {
       
  3548 					this.execCommand('mceAddUndoLevel');
       
  3549 					this.undoRedo.typingUndoIndex = -1;
       
  3550 				}
       
  3551 
       
  3552 				tinyMCE.typingUndoIndex = -1;
       
  3553 				break;
       
  3554 
       
  3555 			case "mceBeginUndoLevel":
       
  3556 				this.undoRedoLevel = false;
       
  3557 				break;
       
  3558 
       
  3559 			case "mceEndUndoLevel":
       
  3560 				this.undoRedoLevel = true;
       
  3561 				this.execCommand('mceAddUndoLevel');
       
  3562 				break;
       
  3563 
       
  3564 			case "mceAddUndoLevel":
       
  3565 				if (tinyMCE.settings['custom_undo_redo'] && this.undoRedoLevel) {
       
  3566 					if (this.undoRedo.add())
       
  3567 						tinyMCE.triggerNodeChange(false);
       
  3568 				}
       
  3569 				break;
       
  3570 
       
  3571 			case "Undo":
       
  3572 				if (tinyMCE.settings['custom_undo_redo']) {
       
  3573 					tinyMCE.execCommand("mceEndTyping");
       
  3574 					this.undoRedo.undo();
       
  3575 					tinyMCE.triggerNodeChange();
       
  3576 				} else
       
  3577 					this.getDoc().execCommand(command, user_interface, value);
       
  3578 				break;
       
  3579 
       
  3580 			case "Redo":
       
  3581 				if (tinyMCE.settings['custom_undo_redo']) {
       
  3582 					tinyMCE.execCommand("mceEndTyping");
       
  3583 					this.undoRedo.redo();
       
  3584 					tinyMCE.triggerNodeChange();
       
  3585 				} else
       
  3586 					this.getDoc().execCommand(command, user_interface, value);
       
  3587 				break;
       
  3588 
       
  3589 			case "mceToggleVisualAid":
       
  3590 				this.visualAid = !this.visualAid;
       
  3591 				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
       
  3592 				tinyMCE.triggerNodeChange();
       
  3593 				break;
       
  3594 
       
  3595 			case "Indent":
       
  3596 				this.getDoc().execCommand(command, user_interface, value);
       
  3597 				tinyMCE.triggerNodeChange();
       
  3598 
       
  3599 				if (tinyMCE.isIE) {
       
  3600 					var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote");
       
  3601 					do {
       
  3602 						if (n && n.nodeName == "BLOCKQUOTE") {
       
  3603 							n.removeAttribute("dir");
       
  3604 							n.removeAttribute("style");
       
  3605 						}
       
  3606 					} while (n != null && (n = n.parentNode) != null);
       
  3607 				}
       
  3608 				break;
       
  3609 
       
  3610 			case "RemoveFormat":
       
  3611 			case "removeformat":
       
  3612 				var text = this.selection.getSelectedText();
       
  3613 
       
  3614 				if (tinyMCE.isOpera) {
       
  3615 					this.getDoc().execCommand("RemoveFormat", false, null);
       
  3616 					return;
       
  3617 				}
       
  3618 
       
  3619 				if (tinyMCE.isIE) {
       
  3620 					try {
       
  3621 						var rng = doc.selection.createRange();
       
  3622 						rng.execCommand("RemoveFormat", false, null);
       
  3623 					} catch (e) {
       
  3624 						// Do nothing
       
  3625 					}
       
  3626 
       
  3627 					this.execCommand("mceSetStyleInfo", false, {command : "removeformat"});
       
  3628 				} else {
       
  3629 					this.getDoc().execCommand(command, user_interface, value);
       
  3630 
       
  3631 					this.execCommand("mceSetStyleInfo", false, {command : "removeformat"});
       
  3632 				}
       
  3633 
       
  3634 				// Remove class
       
  3635 				if (text.length == 0)
       
  3636 					this.execCommand("mceSetCSSClass", false, "");
       
  3637 
       
  3638 				tinyMCE.triggerNodeChange();
       
  3639 				break;
       
  3640 
       
  3641 			default:
       
  3642 				this.getDoc().execCommand(command, user_interface, value);
       
  3643 
       
  3644 				if (tinyMCE.isGecko)
       
  3645 					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
       
  3646 				else
       
  3647 					tinyMCE.triggerNodeChange();
       
  3648 		}
       
  3649 
       
  3650 		// Add undo level after modification
       
  3651 		if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping")
       
  3652 			tinyMCE.execCommand("mceAddUndoLevel");
       
  3653 	},
       
  3654 
       
  3655 	queryCommandValue : function(c) {
       
  3656 		try {
       
  3657 			return this.getDoc().queryCommandValue(c);
       
  3658 		} catch (e) {
       
  3659 			return null;
       
  3660 		}
       
  3661 	},
       
  3662 
       
  3663 	queryCommandState : function(c) {
       
  3664 		return this.getDoc().queryCommandState(c);
       
  3665 	},
       
  3666 
       
  3667 	_onAdd : function(replace_element, form_element_name, target_document) {
       
  3668 		var hc, th, to, editorTemplate;
       
  3669 
       
  3670 		th = this.settings['theme'];
       
  3671 		to = tinyMCE.themes[th];
       
  3672 
       
  3673 		var targetDoc = target_document ? target_document : document;
       
  3674 
       
  3675 		this.targetDoc = targetDoc;
       
  3676 
       
  3677 		tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme'];
       
  3678 		this.settings['themeurl'] = tinyMCE.themeURL;
       
  3679 
       
  3680 		if (!replace_element) {
       
  3681 			alert("Error: Could not find the target element.");
       
  3682 			return false;
       
  3683 		}
       
  3684 
       
  3685 		if (to.getEditorTemplate)
       
  3686 			editorTemplate = to.getEditorTemplate(this.settings, this.editorId);
       
  3687 
       
  3688 		var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0;
       
  3689 		var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0;
       
  3690 		var html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate['html'];
       
  3691 
       
  3692 		html = tinyMCE.replaceVar(html, "editor_id", this.editorId);
       
  3693 		this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm";
       
  3694 
       
  3695 		this.settings['old_width'] = this.settings['width'];
       
  3696 		this.settings['old_height'] = this.settings['height'];
       
  3697 
       
  3698 		// Set default width, height
       
  3699 		if (this.settings['width'] == -1)
       
  3700 			this.settings['width'] = replace_element.offsetWidth;
       
  3701 
       
  3702 		if (this.settings['height'] == -1)
       
  3703 			this.settings['height'] = replace_element.offsetHeight;
       
  3704 
       
  3705 		// Try the style width
       
  3706 		if (this.settings['width'] == 0)
       
  3707 			this.settings['width'] = replace_element.style.width;
       
  3708 
       
  3709 		// Try the style height
       
  3710 		if (this.settings['height'] == 0)
       
  3711 			this.settings['height'] = replace_element.style.height; 
       
  3712 
       
  3713 		// If no width/height then default to 320x240, better than nothing
       
  3714 		if (this.settings['width'] == 0)
       
  3715 			this.settings['width'] = 320;
       
  3716 
       
  3717 		if (this.settings['height'] == 0)
       
  3718 			this.settings['height'] = 240;
       
  3719 
       
  3720 		this.settings['area_width'] = parseInt(this.settings['width']);
       
  3721 		this.settings['area_height'] = parseInt(this.settings['height']);
       
  3722 		this.settings['area_width'] += deltaWidth;
       
  3723 		this.settings['area_height'] += deltaHeight;
       
  3724 
       
  3725 		this.settings['width_style'] = "" + this.settings['width'];
       
  3726 		this.settings['height_style'] = "" + this.settings['height'];
       
  3727 
       
  3728 		// Special % handling
       
  3729 		if (("" + this.settings['width']).indexOf('%') != -1)
       
  3730 			this.settings['area_width'] = "100%";
       
  3731 		else
       
  3732 			this.settings['width_style'] += 'px';
       
  3733 
       
  3734 		if (("" + this.settings['height']).indexOf('%') != -1)
       
  3735 			this.settings['area_height'] = "100%";
       
  3736 		else
       
  3737 			this.settings['height_style'] += 'px';
       
  3738 
       
  3739 		if (("" + replace_element.style.width).indexOf('%') != -1) {
       
  3740 			this.settings['width'] = replace_element.style.width;
       
  3741 			this.settings['area_width'] = "100%";
       
  3742 			this.settings['width_style'] = "100%";
       
  3743 		}
       
  3744 
       
  3745 		if (("" + replace_element.style.height).indexOf('%') != -1) {
       
  3746 			this.settings['height'] = replace_element.style.height;
       
  3747 			this.settings['area_height'] = "100%";
       
  3748 			this.settings['height_style'] = "100%";
       
  3749 		}
       
  3750 
       
  3751 		html = tinyMCE.applyTemplate(html);
       
  3752 
       
  3753 		this.settings['width'] = this.settings['old_width'];
       
  3754 		this.settings['height'] = this.settings['old_height'];
       
  3755 
       
  3756 		this.visualAid = this.settings['visual'];
       
  3757 		this.formTargetElementId = form_element_name;
       
  3758 
       
  3759 		// Get replace_element contents
       
  3760 		if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT")
       
  3761 			this.startContent = replace_element.value;
       
  3762 		else
       
  3763 			this.startContent = replace_element.innerHTML;
       
  3764 
       
  3765 		// If not text area or input
       
  3766 		if (replace_element.nodeName != "TEXTAREA" && replace_element.nodeName != "INPUT") {
       
  3767 			this.oldTargetElement = replace_element;
       
  3768 
       
  3769 			// Debug mode
       
  3770 			if (tinyMCE.settings['debug']) {
       
  3771 				hc = '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>';
       
  3772 			} else {
       
  3773 				hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />';
       
  3774 				this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
       
  3775 				this.oldTargetElement.style.display = "none";
       
  3776 			}
       
  3777 
       
  3778 			html += '</span>';
       
  3779 
       
  3780 			if (tinyMCE.isGecko)
       
  3781 				html = hc + html;
       
  3782 			else
       
  3783 				html += hc;
       
  3784 
       
  3785 			// Output HTML and set editable
       
  3786 			if (tinyMCE.isGecko) {
       
  3787 				var rng = replace_element.ownerDocument.createRange();
       
  3788 				rng.setStartBefore(replace_element);
       
  3789 
       
  3790 				var fragment = rng.createContextualFragment(html);
       
  3791 				tinyMCE.insertAfter(fragment, replace_element);
       
  3792 			} else
       
  3793 				replace_element.insertAdjacentHTML("beforeBegin", html);
       
  3794 		} else {
       
  3795 			html += '</span>';
       
  3796 
       
  3797 			// Just hide the textarea element
       
  3798 			this.oldTargetElement = replace_element;
       
  3799 
       
  3800 			if (!tinyMCE.settings['debug']) {
       
  3801 				this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
       
  3802 				this.oldTargetElement.style.display = "none";
       
  3803 			}
       
  3804 
       
  3805 			// Output HTML and set editable
       
  3806 			if (tinyMCE.isGecko) {
       
  3807 				var rng = replace_element.ownerDocument.createRange();
       
  3808 				rng.setStartBefore(replace_element);
       
  3809 
       
  3810 				var fragment = rng.createContextualFragment(html);
       
  3811 				tinyMCE.insertAfter(fragment, replace_element);
       
  3812 			} else
       
  3813 				replace_element.insertAdjacentHTML("beforeBegin", html);
       
  3814 		}
       
  3815 
       
  3816 		// Setup iframe
       
  3817 		var dynamicIFrame = false;
       
  3818 		var tElm = targetDoc.getElementById(this.editorId);
       
  3819 
       
  3820 		if (!tinyMCE.isIE) {
       
  3821 			// Node case is preserved in XML strict mode
       
  3822 			if (tElm && (tElm.nodeName == "SPAN" || tElm.nodeName == "span")) {
       
  3823 				tElm = tinyMCE._createIFrame(tElm, targetDoc);
       
  3824 				dynamicIFrame = true;
       
  3825 			}
       
  3826 
       
  3827 			this.targetElement = tElm;
       
  3828 			this.iframeElement = tElm;
       
  3829 			this.contentDocument = tElm.contentDocument;
       
  3830 			this.contentWindow = tElm.contentWindow;
       
  3831 
       
  3832 			//this.getDoc().designMode = "on";
       
  3833 		} else {
       
  3834 			if (tElm && tElm.nodeName == "SPAN")
       
  3835 				tElm = tinyMCE._createIFrame(tElm, targetDoc, targetDoc.parentWindow);
       
  3836 			else
       
  3837 				tElm = targetDoc.frames[this.editorId];
       
  3838 
       
  3839 			this.targetElement = tElm;
       
  3840 			this.iframeElement = targetDoc.getElementById(this.editorId);
       
  3841 
       
  3842 			if (tinyMCE.isOpera) {
       
  3843 				this.contentDocument = this.iframeElement.contentDocument;
       
  3844 				this.contentWindow = this.iframeElement.contentWindow;
       
  3845 				dynamicIFrame = true;
       
  3846 			} else {
       
  3847 				this.contentDocument = tElm.window.document;
       
  3848 				this.contentWindow = tElm.window;
       
  3849 			}
       
  3850 
       
  3851 			this.getDoc().designMode = "on";
       
  3852 		}
       
  3853 
       
  3854 		// Setup base HTML
       
  3855 		var doc = this.contentDocument;
       
  3856 		if (dynamicIFrame) {
       
  3857 			var html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';
       
  3858 
       
  3859 			try {
       
  3860 				if (!this.isHidden())
       
  3861 					this.getDoc().designMode = "on";
       
  3862 
       
  3863 				doc.open();
       
  3864         //alert('docwrite 3');
       
  3865 				doc.write(html);
       
  3866 				doc.close();
       
  3867 			} catch (e) {
       
  3868 				// Failed Mozilla 1.3
       
  3869 				this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm";
       
  3870 			}
       
  3871 		}
       
  3872 
       
  3873 		// This timeout is needed in MSIE 5.5 for some odd reason
       
  3874 		// it seems that the document.frames isn't initialized yet?
       
  3875 		if (tinyMCE.isIE)
       
  3876 			window.setTimeout("tinyMCE.addEventHandlers(tinyMCE.instances[\"" + this.editorId + "\"]);", 1);
       
  3877 
       
  3878 		// Setup element references
       
  3879 		var parentElm = this.targetDoc.getElementById(this.editorId + '_parent');
       
  3880 		this.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;
       
  3881 
       
  3882 		tinyMCE.setupContent(this.editorId, true);
       
  3883 
       
  3884 		return true;
       
  3885 	},
       
  3886 
       
  3887 	setBaseHREF : function(u) {
       
  3888 		var h, b, d, nl;
       
  3889 
       
  3890 		d = this.getDoc();
       
  3891 		nl = d.getElementsByTagName("base");
       
  3892 		b = nl.length > 0 ? nl[0] : null;
       
  3893 
       
  3894 		if (!b) {
       
  3895 			nl = d.getElementsByTagName("head");
       
  3896 			h = nl.length > 0 ? nl[0] : null;
       
  3897 
       
  3898 			b = d.createElement("base");
       
  3899 			b.setAttribute('href', u);
       
  3900 			h.appendChild(b);
       
  3901 		} else {
       
  3902 			if (u == "" || u == null)
       
  3903 				b.parentNode.removeChild(b);
       
  3904 			else
       
  3905 				b.setAttribute('href', u);
       
  3906 		}
       
  3907 	},
       
  3908 
       
  3909 	getHTML : function(r) {
       
  3910 		var h, d = this.getDoc(), b = this.getBody();
       
  3911 
       
  3912 		if (r)
       
  3913 			return b.innerHTML;
       
  3914 
       
  3915 		h = tinyMCE._cleanupHTML(this, d, this.settings, b, false, true, false, true);
       
  3916 
       
  3917 		if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  3918 			tinyMCE.convertSpansToFonts(d);
       
  3919 
       
  3920 		return h;
       
  3921 	},
       
  3922 
       
  3923 	setHTML : function(h) {
       
  3924 		this.execCommand('mceSetContent', false, h);
       
  3925 		this.repaint();
       
  3926 	},
       
  3927 
       
  3928 	getFocusElement : function() {
       
  3929 		return this.selection.getFocusElement();
       
  3930 	},
       
  3931 
       
  3932 	getSel : function() {
       
  3933 		return this.selection.getSel();
       
  3934 	},
       
  3935 
       
  3936 	getRng : function() {
       
  3937 		return this.selection.getRng();
       
  3938 	},
       
  3939 
       
  3940 	triggerSave : function(skip_cleanup, skip_callback) {
       
  3941 		var e, nl = [], i, s;
       
  3942 
       
  3943 		this.switchSettings();
       
  3944 		s = tinyMCE.settings;
       
  3945 
       
  3946 		// Force hidden tabs visible while serializing
       
  3947 		if (tinyMCE.isRealIE) {
       
  3948 			e = this.iframeElement;
       
  3949 
       
  3950 			do {
       
  3951 				if (e.style && e.style.display == 'none') {
       
  3952 					e.style.display = 'block';
       
  3953 					nl[nl.length] = {elm : e, type : 'style'};
       
  3954 				}
       
  3955 
       
  3956 				if (e.style && s.hidden_tab_class.length > 0 && e.className.indexOf(s.hidden_tab_class) != -1) {
       
  3957 					e.className = s.display_tab_class;
       
  3958 					nl[nl.length] = {elm : e, type : 'class'};
       
  3959 				}
       
  3960 			} while ((e = e.parentNode) != null)
       
  3961 		}
       
  3962 
       
  3963 		tinyMCE.settings['preformatted'] = false;
       
  3964 
       
  3965 		// Default to false
       
  3966 		if (typeof(skip_cleanup) == "undefined")
       
  3967 			skip_cleanup = false;
       
  3968 
       
  3969 		// Default to false
       
  3970 		if (typeof(skip_callback) == "undefined")
       
  3971 			skip_callback = false;
       
  3972 
       
  3973 		tinyMCE._setHTML(this.getDoc(), this.getBody().innerHTML);
       
  3974 
       
  3975 		// Remove visual aids when cleanup is disabled
       
  3976 		if (this.settings['cleanup'] == false) {
       
  3977 			tinyMCE.handleVisualAid(this.getBody(), true, false, this);
       
  3978 			tinyMCE._setEventsEnabled(this.getBody(), true);
       
  3979 		}
       
  3980 
       
  3981 		tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body);
       
  3982 		var htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true);
       
  3983 		htm = tinyMCE._customCleanup(this, "submit_content", htm);
       
  3984 
       
  3985 		if (!skip_callback && tinyMCE.settings['save_callback'] != "")
       
  3986 			var content = eval(tinyMCE.settings['save_callback'] + "(this.formTargetElementId,htm,this.getBody());");
       
  3987 
       
  3988 		// Use callback content if available
       
  3989 		if ((typeof(content) != "undefined") && content != null)
       
  3990 			htm = content;
       
  3991 
       
  3992 		// Replace some weird entities (Bug: #1056343)
       
  3993 		htm = tinyMCE.regexpReplace(htm, "&#40;", "(", "gi");
       
  3994 		htm = tinyMCE.regexpReplace(htm, "&#41;", ")", "gi");
       
  3995 		htm = tinyMCE.regexpReplace(htm, "&#59;", ";", "gi");
       
  3996 		htm = tinyMCE.regexpReplace(htm, "&#34;", "&quot;", "gi");
       
  3997 		htm = tinyMCE.regexpReplace(htm, "&#94;", "^", "gi");
       
  3998 
       
  3999 		if (this.formElement)
       
  4000 			this.formElement.value = htm;
       
  4001 
       
  4002 		if (tinyMCE.isSafari && this.formElement)
       
  4003 			this.formElement.innerText = htm;
       
  4004 
       
  4005 		// Hide them again (tabs in MSIE)
       
  4006 		for (i=0; i<nl.length; i++) {
       
  4007 			if (nl[i].type == 'style')
       
  4008 				nl[i].elm.style.display = 'none';
       
  4009 			else
       
  4010 				nl[i].elm.className = s.hidden_tab_class;
       
  4011 		}
       
  4012 	}
       
  4013 
       
  4014 	};
       
  4015 
       
  4016 /* file:jscripts/tiny_mce/classes/TinyMCE_Cleanup.class.js */
       
  4017 
       
  4018 TinyMCE_Engine.prototype.cleanupHTMLCode = function(s) {
       
  4019 	s = s.replace(new RegExp('<p \\/>', 'gi'), '<p>&nbsp;</p>');
       
  4020 	s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p>&nbsp;</p>');
       
  4021 
       
  4022 	// Fix close BR elements
       
  4023 	s = s.replace(new RegExp('<br>\\s*<\\/br>', 'gi'), '<br />');
       
  4024 
       
  4025 	// Open closed tags like <b/> to <b></b>
       
  4026 	s = s.replace(new RegExp('<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|font|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\\\|>]*)\\/>', 'gi'), '<$1$2$3></$1$2>');
       
  4027 
       
  4028 	// Remove trailing space <b > to <b>
       
  4029 	s = s.replace(new RegExp('\\s+></', 'gi'), '></');
       
  4030 
       
  4031 	// Close tags <img></img> to <img/>
       
  4032 	s = s.replace(new RegExp('<(img|br|hr)([^>]*)><\\/(img|br|hr)>', 'gi'), '<$1$2 />');
       
  4033 
       
  4034 	// Weird MSIE bug, <p><hr /></p> breaks runtime?
       
  4035 	if (tinyMCE.isIE)
       
  4036 		s = s.replace(new RegExp('<p><hr \\/><\\/p>', 'gi'), "<hr>");
       
  4037 
       
  4038 	// Weird tags will make IE error #bug: 1538495
       
  4039 	if (tinyMCE.isIE)
       
  4040 		s = s.replace(/<!(\s*)\/>/g, '');
       
  4041 
       
  4042 	// Convert relative anchors to absolute URLs ex: #something to file.htm#something
       
  4043 	// Removed: Since local document anchors should never be forced absolute example edit.php?id=something
       
  4044 	//if (tinyMCE.getParam('convert_urls'))
       
  4045 	//	s = s.replace(new RegExp('(href=\"{0,1})(\\s*#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");
       
  4046 
       
  4047 	return s;
       
  4048 };
       
  4049 
       
  4050 TinyMCE_Engine.prototype.parseStyle = function(str) {
       
  4051 	var ar = new Array();
       
  4052 
       
  4053 	if (str == null)
       
  4054 		return ar;
       
  4055 
       
  4056 	var st = str.split(';');
       
  4057 
       
  4058 	tinyMCE.clearArray(ar);
       
  4059 
       
  4060 	for (var i=0; i<st.length; i++) {
       
  4061 		if (st[i] == '')
       
  4062 			continue;
       
  4063 
       
  4064 		var re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$');
       
  4065 		var pa = st[i].replace(re, '$1||$2').split('||');
       
  4066 //tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2'));
       
  4067 		if (pa.length == 2)
       
  4068 			ar[pa[0].toLowerCase()] = pa[1];
       
  4069 	}
       
  4070 
       
  4071 	return ar;
       
  4072 };
       
  4073 
       
  4074 TinyMCE_Engine.prototype.compressStyle = function(ar, pr, sf, res) {
       
  4075 	var box = new Array();
       
  4076 
       
  4077 	box[0] = ar[pr + '-top' + sf];
       
  4078 	box[1] = ar[pr + '-left' + sf];
       
  4079 	box[2] = ar[pr + '-right' + sf];
       
  4080 	box[3] = ar[pr + '-bottom' + sf];
       
  4081 
       
  4082 	for (var i=0; i<box.length; i++) {
       
  4083 		if (box[i] == null)
       
  4084 			return;
       
  4085 
       
  4086 		for (var a=0; a<box.length; a++) {
       
  4087 			if (box[a] != box[i])
       
  4088 				return;
       
  4089 		}
       
  4090 	}
       
  4091 
       
  4092 	// They are all the same
       
  4093 	ar[res] = box[0];
       
  4094 	ar[pr + '-top' + sf] = null;
       
  4095 	ar[pr + '-left' + sf] = null;
       
  4096 	ar[pr + '-right' + sf] = null;
       
  4097 	ar[pr + '-bottom' + sf] = null;
       
  4098 };
       
  4099 
       
  4100 TinyMCE_Engine.prototype.serializeStyle = function(ar) {
       
  4101 	var str = "";
       
  4102 
       
  4103 	// Compress box
       
  4104 	tinyMCE.compressStyle(ar, "border", "", "border");
       
  4105 	tinyMCE.compressStyle(ar, "border", "-width", "border-width");
       
  4106 	tinyMCE.compressStyle(ar, "border", "-color", "border-color");
       
  4107 	tinyMCE.compressStyle(ar, "border", "-style", "border-style");
       
  4108 	tinyMCE.compressStyle(ar, "padding", "", "padding");
       
  4109 	tinyMCE.compressStyle(ar, "margin", "", "margin");
       
  4110 
       
  4111 	for (var key in ar) {
       
  4112 		var val = ar[key];
       
  4113 
       
  4114 		if (typeof(val) == 'function')
       
  4115 			continue;
       
  4116 
       
  4117 		if (key.indexOf('mso-') == 0)
       
  4118 			continue;
       
  4119 
       
  4120 		if (val != null && val != '') {
       
  4121 			val = '' + val; // Force string
       
  4122 
       
  4123 			// Fix style URL
       
  4124 			val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')");
       
  4125 
       
  4126 			// Convert URL
       
  4127 			if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) {
       
  4128 				var m = new RegExp("url\\('(.*?)'\\)").exec(val);
       
  4129 
       
  4130 				if (m.length > 1)
       
  4131 					val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')";
       
  4132 			}
       
  4133 
       
  4134 			// Force HEX colors
       
  4135 			if (tinyMCE.getParam("force_hex_style_colors"))
       
  4136 				val = tinyMCE.convertRGBToHex(val, true);
       
  4137 
       
  4138 			val = val.replace(/\"/g, '\'');
       
  4139 
       
  4140 			if (val != "url('')")
       
  4141 				str += key.toLowerCase() + ": " + val + "; ";
       
  4142 		}
       
  4143 	}
       
  4144 
       
  4145 	if (new RegExp('; $').test(str))
       
  4146 		str = str.substring(0, str.length - 2);
       
  4147 
       
  4148 	return str;
       
  4149 };
       
  4150 
       
  4151 TinyMCE_Engine.prototype.convertRGBToHex = function(s, k) {
       
  4152 	if (s.toLowerCase().indexOf('rgb') != -1) {
       
  4153 		var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
       
  4154 		var rgb = s.replace(re, "$1,$2,$3,$4,$5").split(',');
       
  4155 		if (rgb.length == 5) {
       
  4156 			r = parseInt(rgb[1]).toString(16);
       
  4157 			g = parseInt(rgb[2]).toString(16);
       
  4158 			b = parseInt(rgb[3]).toString(16);
       
  4159 
       
  4160 			r = r.length == 1 ? '0' + r : r;
       
  4161 			g = g.length == 1 ? '0' + g : g;
       
  4162 			b = b.length == 1 ? '0' + b : b;
       
  4163 
       
  4164 			s = "#" + r + g + b;
       
  4165 
       
  4166 			if (k)
       
  4167 				s = rgb[0] + s + rgb[4];
       
  4168 		}
       
  4169 	}
       
  4170 
       
  4171 	return s;
       
  4172 };
       
  4173 
       
  4174 TinyMCE_Engine.prototype.convertHexToRGB = function(s) {
       
  4175 	if (s.indexOf('#') != -1) {
       
  4176 		s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');
       
  4177 		return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")";
       
  4178 	}
       
  4179 
       
  4180 	return s;
       
  4181 };
       
  4182 
       
  4183 TinyMCE_Engine.prototype.convertSpansToFonts = function(doc) {
       
  4184 	var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
       
  4185 
       
  4186 	/*var h = doc.body.innerHTML;
       
  4187 	h = h.replace(/<span/gi, '<font');
       
  4188 	h = h.replace(/<\/span/gi, '</font');
       
  4189 	tinyMCE.setInnerHTML(doc.body, h);*/
       
  4190 
       
  4191 	var s = tinyMCE.selectElements(doc, 'span,font');
       
  4192 	for (var i=0; i<s.length; i++) {
       
  4193 		var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
       
  4194 		var fSize = 0;
       
  4195 
       
  4196 		for (var x=0; x<sizes.length; x++) {
       
  4197 			if (sizes[x] == size) {
       
  4198 				fSize = x + 1;
       
  4199 				break;
       
  4200 			}
       
  4201 		}
       
  4202 
       
  4203 		if (fSize > 0) {
       
  4204 			tinyMCE.setAttrib(s[i], 'size', fSize);
       
  4205 			s[i].style.fontSize = '';
       
  4206 		}
       
  4207 
       
  4208 		var fFace = s[i].style.fontFamily;
       
  4209 		if (fFace != null && fFace != "") {
       
  4210 			tinyMCE.setAttrib(s[i], 'face', fFace);
       
  4211 			s[i].style.fontFamily = '';
       
  4212 		}
       
  4213 
       
  4214 		var fColor = s[i].style.color;
       
  4215 		if (fColor != null && fColor != "") {
       
  4216 			tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
       
  4217 			s[i].style.color = '';
       
  4218 		}
       
  4219 	}
       
  4220 };
       
  4221 
       
  4222 TinyMCE_Engine.prototype.convertFontsToSpans = function(doc) {
       
  4223 	var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
       
  4224 
       
  4225 /*	var h = doc.body.innerHTML;
       
  4226 	h = h.replace(/<font/gi, '<span');
       
  4227 	h = h.replace(/<\/font/gi, '</span');
       
  4228 	tinyMCE.setInnerHTML(doc.body, h);*/
       
  4229 
       
  4230 	var fsClasses = tinyMCE.getParam('font_size_classes');
       
  4231 	if (fsClasses != '')
       
  4232 		fsClasses = fsClasses.replace(/\s+/, '').split(',');
       
  4233 	else
       
  4234 		fsClasses = null;
       
  4235 
       
  4236 	var s = tinyMCE.selectElements(doc, 'span,font');
       
  4237 	for (var i=0; i<s.length; i++) {
       
  4238 		var fSize, fFace, fColor;
       
  4239 
       
  4240 		fSize = tinyMCE.getAttrib(s[i], 'size');
       
  4241 		fFace = tinyMCE.getAttrib(s[i], 'face');
       
  4242 		fColor = tinyMCE.getAttrib(s[i], 'color');
       
  4243 
       
  4244 		if (fSize != "") {
       
  4245 			fSize = parseInt(fSize);
       
  4246 
       
  4247 			if (fSize > 0 && fSize < 8) {
       
  4248 				if (fsClasses != null)
       
  4249 					tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
       
  4250 				else
       
  4251 					s[i].style.fontSize = sizes[fSize-1];
       
  4252 			}
       
  4253 
       
  4254 			s[i].removeAttribute('size');
       
  4255 		}
       
  4256 
       
  4257 		if (fFace != "") {
       
  4258 			s[i].style.fontFamily = fFace;
       
  4259 			s[i].removeAttribute('face');
       
  4260 		}
       
  4261 
       
  4262 		if (fColor != "") {
       
  4263 			s[i].style.color = fColor;
       
  4264 			s[i].removeAttribute('color');
       
  4265 		}
       
  4266 	}
       
  4267 };
       
  4268 
       
  4269 TinyMCE_Engine.prototype.cleanupAnchors = function(doc) {
       
  4270 	var i, cn, x, an = doc.getElementsByTagName("a");
       
  4271 
       
  4272 	// Loops backwards due to bug #1467987
       
  4273 	for (i=an.length-1; i>=0; i--) {
       
  4274 		if (tinyMCE.getAttrib(an[i], "name") != "" && tinyMCE.getAttrib(an[i], "href") == "") {
       
  4275 			cn = an[i].childNodes;
       
  4276 
       
  4277 			for (x=cn.length-1; x>=0; x--)
       
  4278 				tinyMCE.insertAfter(cn[x], an[i]);
       
  4279 		}
       
  4280 	}
       
  4281 };
       
  4282 
       
  4283 TinyMCE_Engine.prototype.getContent = function(editor_id) {
       
  4284 	if (typeof(editor_id) != "undefined")
       
  4285 		 tinyMCE.getInstanceById(editor_id).select();
       
  4286 
       
  4287 	if (tinyMCE.selectedInstance)
       
  4288 		return tinyMCE.selectedInstance.getHTML();
       
  4289 
       
  4290 	return null;
       
  4291 };
       
  4292 
       
  4293 TinyMCE_Engine.prototype._fixListElements = function(d) {
       
  4294 	var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np;
       
  4295 
       
  4296 	for (x=0; x<a.length; x++) {
       
  4297 		nl = d.getElementsByTagName(a[x]);
       
  4298 
       
  4299 		for (i=0; i<nl.length; i++) {
       
  4300 			n = nl[i];
       
  4301 			p = n.parentNode;
       
  4302 
       
  4303 			if (r.test(p.nodeName)) {
       
  4304 				np = tinyMCE.prevNode(n, 'LI');
       
  4305 
       
  4306 				if (!np) {
       
  4307 					np = d.createElement('li');
       
  4308 					np.innerHTML = '&nbsp;';
       
  4309 					np.appendChild(n);
       
  4310 					p.insertBefore(np, p.firstChild);
       
  4311 				} else
       
  4312 					np.appendChild(n);
       
  4313 			}
       
  4314 		}
       
  4315 	}
       
  4316 };
       
  4317 
       
  4318 TinyMCE_Engine.prototype._fixTables = function(d) {
       
  4319 	var nl, i, n, p, np, x, t;
       
  4320 
       
  4321 	nl = d.getElementsByTagName('table');
       
  4322 	for (i=0; i<nl.length; i++) {
       
  4323 		n = nl[i];
       
  4324 
       
  4325 		if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) {
       
  4326 			np = p.cloneNode(false);
       
  4327 			np.removeAttribute('id');
       
  4328 
       
  4329 			t = n;
       
  4330 
       
  4331 			while ((n = n.nextSibling))
       
  4332 				np.appendChild(n);
       
  4333 
       
  4334 			tinyMCE.insertAfter(np, p);
       
  4335 			tinyMCE.insertAfter(t, p);
       
  4336 		}
       
  4337 	}
       
  4338 };
       
  4339 
       
  4340 TinyMCE_Engine.prototype._cleanupHTML = function(inst, doc, config, elm, visual, on_save, on_submit, inn) {
       
  4341 	var h, d, t1, t2, t3, t4, t5, c, s, nb;
       
  4342 
       
  4343 	if (!tinyMCE.getParam('cleanup'))
       
  4344 		return elm.innerHTML;
       
  4345 
       
  4346 	on_save = typeof(on_save) == 'undefined' ? false : on_save;
       
  4347 
       
  4348 	c = inst.cleanup;
       
  4349 	s = inst.settings;
       
  4350 	d = c.settings.debug;
       
  4351 
       
  4352 	if (d)
       
  4353 		t1 = new Date().getTime();
       
  4354 
       
  4355 	if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  4356 		tinyMCE.convertFontsToSpans(doc);
       
  4357 
       
  4358 	if (tinyMCE.getParam("fix_list_elements"))
       
  4359 		tinyMCE._fixListElements(doc);
       
  4360 
       
  4361 	if (tinyMCE.getParam("fix_table_elements"))
       
  4362 		tinyMCE._fixTables(doc);
       
  4363 
       
  4364 	// Call custom cleanup code
       
  4365 	tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);
       
  4366 
       
  4367 	if (d)
       
  4368 		t2 = new Date().getTime();
       
  4369 
       
  4370 	c.settings.on_save = on_save;
       
  4371 	//for (var i=0; i<100; i++)
       
  4372 
       
  4373 	c.idCount = 0;
       
  4374 	c.serializationId++;
       
  4375 	c.serializedNodes = new Array();
       
  4376 	c.sourceIndex = -1;
       
  4377 
       
  4378 	if (s.cleanup_serializer == "xml")
       
  4379 		h = c.serializeNodeAsXML(elm, inn);
       
  4380 	else
       
  4381 		h = c.serializeNodeAsHTML(elm, inn);
       
  4382 
       
  4383 	if (d)
       
  4384 		t3 = new Date().getTime();
       
  4385 
       
  4386 	// Post processing
       
  4387 	nb = tinyMCE.getParam('entity_encoding') == 'numeric' ? '&#160;' : '&nbsp;';
       
  4388 	h = h.replace(/<\/?(body|head|html)[^>]*>/gi, '');
       
  4389 	h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), '');
       
  4390 	h = h.replace(/<p><hr \/><\/p>/g, '<hr />');
       
  4391 	h = h.replace(/<p>(&nbsp;|&#160;)<\/p><hr \/><p>(&nbsp;|&#160;)<\/p>/g, '<hr />');
       
  4392 	h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>' + nb + '</td>');
       
  4393 	h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
       
  4394 	h = h.replace(/<br \/>$/, ''); // Remove last BR for Gecko
       
  4395 	h = h.replace(/<br \/><\/p>/g, '</p>'); // Remove last BR in P tags for Gecko
       
  4396 	h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*(&nbsp;|&#160;)\s*<\/p>/g, '<p>' + nb + '</p>');
       
  4397 	h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
       
  4398 	h = h.replace(/<p>\s*<br \/>\s*&nbsp;\s*<\/p>/g, '<p>' + nb + '</p>');
       
  4399 	h = h.replace(new RegExp('<a>(.*?)<\\/a>', 'g'), '$1');
       
  4400 	h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>' + nb + '</p>');
       
  4401 
       
  4402 	// Clean body
       
  4403 	if (/^\s*(<br \/>|<p>&nbsp;<\/p>|<p>&#160;<\/p>|<p><\/p>)\s*$/.test(h))
       
  4404 		h = '';
       
  4405 
       
  4406 	// If preformatted
       
  4407 	if (s.preformatted) {
       
  4408 		h = h.replace(/^<pre>/, '');
       
  4409 		h = h.replace(/<\/pre>$/, '');
       
  4410 		h = '<pre>' + h + '</pre>';
       
  4411 	}
       
  4412 
       
  4413 	// Gecko specific processing
       
  4414 	if (tinyMCE.isGecko) {
       
  4415 		h = h.replace(/<o:p _moz-userdefined="" \/>/g, '');
       
  4416 		h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>' + nb + '</td>');
       
  4417 	}
       
  4418 
       
  4419 	if (s.force_br_newlines)
       
  4420 		h = h.replace(/<p>(&nbsp;|&#160;)<\/p>/g, '<br />');
       
  4421 
       
  4422 	// Call custom cleanup code
       
  4423 	h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h);
       
  4424 
       
  4425 	// Remove internal classes
       
  4426 	if (on_save) {
       
  4427 		h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), '');
       
  4428 		h = h.replace(new RegExp(' ?class=""', 'g'), '');
       
  4429 	}
       
  4430 
       
  4431 	if (s.remove_linebreaks && !c.settings.indent)
       
  4432 		h = h.replace(/\n|\r/g, ' ');
       
  4433 
       
  4434 	if (d)
       
  4435 		t4 = new Date().getTime();
       
  4436 
       
  4437 	if (on_save && c.settings.indent)
       
  4438 		h = c.formatHTML(h);
       
  4439 
       
  4440 	// If encoding (not recommended option)
       
  4441 	if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
       
  4442 		h = c.xmlEncode(h);
       
  4443 
       
  4444 	if (d)
       
  4445 		t5 = new Date().getTime();
       
  4446 
       
  4447 	if (c.settings.debug)
       
  4448 		tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
       
  4449 
       
  4450 	return h;
       
  4451 };
       
  4452 
       
  4453 function TinyMCE_Cleanup() {
       
  4454 	this.isIE = (navigator.appName == "Microsoft Internet Explorer");
       
  4455 	this.rules = tinyMCE.clearArray(new Array());
       
  4456 
       
  4457 	// Default config
       
  4458 	this.settings = {
       
  4459 		indent_elements : 'head,table,tbody,thead,tfoot,form,tr,ul,ol,blockquote,object',
       
  4460 		newline_before_elements : 'h1,h2,h3,h4,h5,h6,pre,address,div,ul,ol,li,meta,option,area,title,link,base,script,td',
       
  4461 		newline_after_elements : 'br,hr,p,pre,address,div,ul,ol,meta,option,area,link,base,script',
       
  4462 		newline_before_after_elements : 'html,head,body,table,thead,tbody,tfoot,tr,form,ul,ol,blockquote,p,object,param,hr,div',
       
  4463 		indent_char : '\t',
       
  4464 		indent_levels : 1,
       
  4465 		entity_encoding : 'raw',
       
  4466 		valid_elements : '*[*]',
       
  4467 		entities : '',
       
  4468 		url_converter : '',
       
  4469 		invalid_elements : '',
       
  4470 		verify_html : false
       
  4471 	};
       
  4472 
       
  4473 	this.vElements = tinyMCE.clearArray(new Array());
       
  4474 	this.vElementsRe = '';
       
  4475 	this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|AREA)$/;
       
  4476 	this.codeElementsRe = /^(SCRIPT|STYLE)$/;
       
  4477 	this.serializationId = 0;
       
  4478 	this.mceAttribs = {
       
  4479 		href : 'mce_href',
       
  4480 		src : 'mce_src',
       
  4481 		type : 'mce_type'
       
  4482 	};
       
  4483 }
       
  4484 
       
  4485 TinyMCE_Cleanup.prototype = {
       
  4486 	init : function(s) {
       
  4487 		var n, a, i, ir, or, st;
       
  4488 
       
  4489 		for (n in s)
       
  4490 			this.settings[n] = s[n];
       
  4491 
       
  4492 		// Setup code formating
       
  4493 		s = this.settings;
       
  4494 
       
  4495 		// Setup regexps
       
  4496 		this.inRe = this._arrayToRe(s.indent_elements.split(','), '', '^<(', ')[^>]*');
       
  4497 		this.ouRe = this._arrayToRe(s.indent_elements.split(','), '', '^<\\/(', ')[^>]*');
       
  4498 		this.nlBeforeRe = this._arrayToRe(s.newline_before_elements.split(','), 'gi', '<(',  ')([^>]*)>');
       
  4499 		this.nlAfterRe = this._arrayToRe(s.newline_after_elements.split(','), 'gi', '<(',  ')([^>]*)>');
       
  4500 		this.nlBeforeAfterRe = this._arrayToRe(s.newline_before_after_elements.split(','), 'gi', '<(\\/?)(', ')([^>]*)>');
       
  4501 		this.serializedNodes = [];
       
  4502 
       
  4503 		if (s.invalid_elements != '')
       
  4504 			this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$');
       
  4505 		else
       
  4506 			this.iveRe = null;
       
  4507 
       
  4508 		// Setup separator
       
  4509 		st = '';
       
  4510 		for (i=0; i<s.indent_levels; i++)
       
  4511 			st += s.indent_char;
       
  4512 
       
  4513 		this.inStr = st;
       
  4514 
       
  4515 		// If verify_html if false force *[*]
       
  4516 		if (!s.verify_html) {
       
  4517 			s.valid_elements = '*[*]';
       
  4518 			s.extended_valid_elements = '';
       
  4519 		}
       
  4520 
       
  4521 		this.fillStr = s.entity_encoding == "named" ? "&nbsp;" : "&#160;";
       
  4522 		this.idCount = 0;
       
  4523 		this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g');
       
  4524 		this.xmlEncodeAposRe = new RegExp('[\u007F-\uFFFF<>&"\']', 'g');
       
  4525 	},
       
  4526 
       
  4527 	addRuleStr : function(s) {
       
  4528 		var r = this.parseRuleStr(s);
       
  4529 		var n;
       
  4530 
       
  4531 		for (n in r) {
       
  4532 			if (r[n])
       
  4533 				this.rules[n] = r[n];
       
  4534 		}
       
  4535 
       
  4536 		this.vElements = tinyMCE.clearArray(new Array());
       
  4537 
       
  4538 		for (n in this.rules) {
       
  4539 			if (this.rules[n])
       
  4540 				this.vElements[this.vElements.length] = this.rules[n].tag;
       
  4541 		}
       
  4542 
       
  4543 		this.vElementsRe = this._arrayToRe(this.vElements, '');
       
  4544 	},
       
  4545 
       
  4546 	isValid : function(n) {
       
  4547 		this._setupRules(); // Will initialize cleanup rules
       
  4548 
       
  4549 		// Empty is true since it removes formatting
       
  4550 		if (!n)
       
  4551 			return true;
       
  4552 
       
  4553 		// Clean the name up a bit
       
  4554 		n = n.replace(/[^a-z0-9]+/gi, '').toUpperCase();
       
  4555 
       
  4556 		return !tinyMCE.getParam('cleanup') || this.vElementsRe.test(n);
       
  4557 	},
       
  4558 
       
  4559 	addChildRemoveRuleStr : function(s) {
       
  4560 		var x, y, p, i, t, tn, ta, cl, r;
       
  4561 
       
  4562 		if (!s)
       
  4563 			return;
       
  4564 
       
  4565 		ta = s.split(',');
       
  4566 		for (x=0; x<ta.length; x++) {
       
  4567 			s = ta[x];
       
  4568 
       
  4569 			// Split tag/children
       
  4570 			p = this.split(/\[|\]/, s);
       
  4571 			if (p == null || p.length < 1)
       
  4572 				t = s.toUpperCase();
       
  4573 			else
       
  4574 				t = p[0].toUpperCase();
       
  4575 
       
  4576 			// Handle all tag names
       
  4577 			tn = this.split('/', t);
       
  4578 			for (y=0; y<tn.length; y++) {
       
  4579 				r = "^(";
       
  4580 
       
  4581 				// Build regex
       
  4582 				cl = this.split(/\|/, p[1]);
       
  4583 				for (i=0; i<cl.length; i++) {
       
  4584 					if (cl[i] == '%istrict')
       
  4585 						r += tinyMCE.inlineStrict;
       
  4586 					else if (cl[i] == '%itrans')
       
  4587 						r += tinyMCE.inlineTransitional;
       
  4588 					else if (cl[i] == '%istrict_na')
       
  4589 						r += tinyMCE.inlineStrict.substring(2);
       
  4590 					else if (cl[i] == '%itrans_na')
       
  4591 						r += tinyMCE.inlineTransitional.substring(2);
       
  4592 					else if (cl[i] == '%btrans')
       
  4593 						r += tinyMCE.blockElms;
       
  4594 					else if (cl[i] == '%strict')
       
  4595 						r += tinyMCE.blockStrict;
       
  4596 					else
       
  4597 						r += (cl[i].charAt(0) != '#' ? cl[i].toUpperCase() : cl[i]);
       
  4598 
       
  4599 					r += (i != cl.length - 1 ? '|' : '');
       
  4600 				}
       
  4601 
       
  4602 				r += ')$';
       
  4603 //tinyMCE.debug(t + "=" + r);
       
  4604 				if (this.childRules == null)
       
  4605 					this.childRules = tinyMCE.clearArray(new Array());
       
  4606 
       
  4607 				this.childRules[tn[y]] = new RegExp(r);
       
  4608 
       
  4609 				if (p.length > 1)
       
  4610 					this.childRules[tn[y]].wrapTag = p[2];
       
  4611 			}
       
  4612 		}
       
  4613 	},
       
  4614 
       
  4615 	parseRuleStr : function(s) {
       
  4616 		var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray(new Array()), dv;
       
  4617 
       
  4618 		if (s == null || s.length == 0)
       
  4619 			return or;
       
  4620 
       
  4621 		ta = s.split(',');
       
  4622 		for (x=0; x<ta.length; x++) {
       
  4623 			s = ta[x];
       
  4624 			if (s.length == 0)
       
  4625 				continue;
       
  4626 
       
  4627 			// Split tag/attrs
       
  4628 			p = this.split(/\[|\]/, s);
       
  4629 			if (p == null || p.length < 1)
       
  4630 				t = s.toUpperCase();
       
  4631 			else
       
  4632 				t = p[0].toUpperCase();
       
  4633 
       
  4634 			// Handle all tag names
       
  4635 			tn = this.split('/', t);
       
  4636 			for (y=0; y<tn.length; y++) {
       
  4637 				r = {};
       
  4638 
       
  4639 				r.tag = tn[y];
       
  4640 				r.forceAttribs = null;
       
  4641 				r.defaultAttribs = null;
       
  4642 				r.validAttribValues = null;
       
  4643 
       
  4644 				// Handle prefixes
       
  4645 				px = r.tag.charAt(0);
       
  4646 				r.forceOpen = px == '+';
       
  4647 				r.removeEmpty = px == '-';
       
  4648 				r.fill = px == '#';
       
  4649 				r.tag = r.tag.replace(/\+|-|#/g, '');
       
  4650 				r.oTagName = tn[0].replace(/\+|-|#/g, '').toLowerCase();
       
  4651 				r.isWild = new RegExp('\\*|\\?|\\+', 'g').test(r.tag);
       
  4652 				r.validRe = new RegExp(this._wildcardToRe('^' + r.tag + '$'));
       
  4653 
       
  4654 				// Setup valid attributes
       
  4655 				if (p.length > 1) {
       
  4656 					r.vAttribsRe = '^(';
       
  4657 					a = this.split(/\|/, p[1]);
       
  4658 
       
  4659 					for (i=0; i<a.length; i++) {
       
  4660 						t = a[i];
       
  4661 
       
  4662 						if (t.charAt(0) == '!') {
       
  4663 							a[i] = t = t.substring(1);
       
  4664 
       
  4665 							if (!r.reqAttribsRe)
       
  4666 								r.reqAttribsRe = '\\s+(' + t;
       
  4667 							else
       
  4668 								r.reqAttribsRe += '|' + t;
       
  4669 						}
       
  4670 
       
  4671 						av = new RegExp('(=|:|<)(.*?)$').exec(t);
       
  4672 						t = t.replace(new RegExp('(=|:|<).*?$'), '');
       
  4673 						if (av && av.length > 0) {
       
  4674 							if (av[0].charAt(0) == ':') {
       
  4675 								if (!r.forceAttribs)
       
  4676 									r.forceAttribs = tinyMCE.clearArray(new Array());
       
  4677 
       
  4678 								r.forceAttribs[t.toLowerCase()] = av[0].substring(1);
       
  4679 							} else if (av[0].charAt(0) == '=') {
       
  4680 								if (!r.defaultAttribs)
       
  4681 									r.defaultAttribs = tinyMCE.clearArray(new Array());
       
  4682 
       
  4683 								dv = av[0].substring(1);
       
  4684 
       
  4685 								r.defaultAttribs[t.toLowerCase()] = dv == "" ? "mce_empty" : dv;
       
  4686 							} else if (av[0].charAt(0) == '<') {
       
  4687 								if (!r.validAttribValues)
       
  4688 									r.validAttribValues = tinyMCE.clearArray(new Array());
       
  4689 
       
  4690 								r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), 'i');
       
  4691 							}
       
  4692 						}
       
  4693 
       
  4694 						r.vAttribsRe += '' + t.toLowerCase() + (i != a.length - 1 ? '|' : '');
       
  4695 
       
  4696 						a[i] = t.toLowerCase();
       
  4697 					}
       
  4698 
       
  4699 					if (r.reqAttribsRe)
       
  4700 						r.reqAttribsRe = new RegExp(r.reqAttribsRe + ')=\"', 'g');
       
  4701 
       
  4702 					r.vAttribsRe += ')$';
       
  4703 					r.vAttribsRe = this._wildcardToRe(r.vAttribsRe);
       
  4704 					r.vAttribsReIsWild = new RegExp('\\*|\\?|\\+', 'g').test(r.vAttribsRe);
       
  4705 					r.vAttribsRe = new RegExp(r.vAttribsRe);
       
  4706 					r.vAttribs = a.reverse();
       
  4707 
       
  4708 					//tinyMCE.debug(r.tag, r.oTagName, r.vAttribsRe, r.vAttribsReWC);
       
  4709 				} else {
       
  4710 					r.vAttribsRe = '';
       
  4711 					r.vAttribs = tinyMCE.clearArray(new Array());
       
  4712 					r.vAttribsReIsWild = false;
       
  4713 				}
       
  4714 
       
  4715 				or[r.tag] = r;
       
  4716 			}
       
  4717 		}
       
  4718 
       
  4719 		return or;
       
  4720 	},
       
  4721 
       
  4722 	serializeNodeAsXML : function(n) {
       
  4723 		var s, b;
       
  4724 
       
  4725 		if (!this.xmlDoc) {
       
  4726 			if (this.isIE) {
       
  4727 				try {this.xmlDoc = new ActiveXObject('MSXML2.DOMDocument');} catch (e) {}
       
  4728 
       
  4729 				if (!this.xmlDoc)
       
  4730 					try {this.xmlDoc = new ActiveXObject('Microsoft.XmlDom');} catch (e) {}
       
  4731 			} else
       
  4732 				this.xmlDoc = document.implementation.createDocument('', '', null);
       
  4733 
       
  4734 			if (!this.xmlDoc)
       
  4735 				alert("Error XML Parser could not be found.");
       
  4736 		}
       
  4737 
       
  4738 		if (this.xmlDoc.firstChild)
       
  4739 			this.xmlDoc.removeChild(this.xmlDoc.firstChild);
       
  4740 
       
  4741 		b = this.xmlDoc.createElement("html");
       
  4742 		b = this.xmlDoc.appendChild(b);
       
  4743 
       
  4744 		this._convertToXML(n, b);
       
  4745 
       
  4746 		if (this.isIE)
       
  4747 			return this.xmlDoc.xml;
       
  4748 		else
       
  4749 			return new XMLSerializer().serializeToString(this.xmlDoc);
       
  4750 	},
       
  4751 
       
  4752 	_convertToXML : function(n, xn) {
       
  4753 		var xd, el, i, l, cn, at, no, hc = false;
       
  4754 
       
  4755 		if (tinyMCE.isRealIE && this._isDuplicate(n))
       
  4756 			return;
       
  4757 
       
  4758 		xd = this.xmlDoc;
       
  4759 
       
  4760 		switch (n.nodeType) {
       
  4761 			case 1: // Element
       
  4762 				hc = n.hasChildNodes();
       
  4763 
       
  4764 				el = xd.createElement(n.nodeName.toLowerCase());
       
  4765 
       
  4766 				at = n.attributes;
       
  4767 				for (i=at.length-1; i>-1; i--) {
       
  4768 					no = at[i];
       
  4769 
       
  4770 					if (no.specified && no.nodeValue)
       
  4771 						el.setAttribute(no.nodeName.toLowerCase(), no.nodeValue);
       
  4772 				}
       
  4773 
       
  4774 				if (!hc && !this.closeElementsRe.test(n.nodeName))
       
  4775 					el.appendChild(xd.createTextNode(""));
       
  4776 
       
  4777 				xn = xn.appendChild(el);
       
  4778 				break;
       
  4779 
       
  4780 			case 3: // Text
       
  4781 				xn.appendChild(xd.createTextNode(n.nodeValue));
       
  4782 				return;
       
  4783 
       
  4784 			case 8: // Comment
       
  4785 				xn.appendChild(xd.createComment(n.nodeValue));
       
  4786 				return;
       
  4787 		}
       
  4788 
       
  4789 		if (hc) {
       
  4790 			cn = n.childNodes;
       
  4791 
       
  4792 			for (i=0, l=cn.length; i<l; i++)
       
  4793 				this._convertToXML(cn[i], xn);
       
  4794 		}
       
  4795 	},
       
  4796 
       
  4797 	serializeNodeAsHTML : function(n, inn) {
       
  4798 		var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn;
       
  4799 
       
  4800 		this._setupRules(); // Will initialize cleanup rules
       
  4801 
       
  4802 		if (tinyMCE.isRealIE && this._isDuplicate(n))
       
  4803 			return '';
       
  4804 
       
  4805 		// Skip non valid child elements
       
  4806 		if (n.parentNode && this.childRules != null) {
       
  4807 			cr = this.childRules[n.parentNode.nodeName];
       
  4808 
       
  4809 			if (typeof(cr) != "undefined" && !cr.test(n.nodeName)) {
       
  4810 				st = true;
       
  4811 				t = null;
       
  4812 			}
       
  4813 		}
       
  4814 
       
  4815 		switch (n.nodeType) {
       
  4816 			case 1: // Element
       
  4817 				hc = n.hasChildNodes();
       
  4818 
       
  4819 				if (st)
       
  4820 					break;
       
  4821 
       
  4822 				// MSIE sometimes produces <//tag>
       
  4823 				if ((tinyMCE.isRealIE) && n.nodeName.indexOf('/') != -1)
       
  4824 					break;
       
  4825 
       
  4826 				nn = n.nodeName;
       
  4827 
       
  4828 				// Convert fonts to spans
       
  4829 				if (this.settings.convert_fonts_to_spans) {
       
  4830 					// On get content FONT -> SPAN
       
  4831 					if (this.settings.on_save && nn == 'FONT')
       
  4832 						nn = 'SPAN';
       
  4833 
       
  4834 					// On insert content SPAN -> FONT
       
  4835 					if (!this.settings.on_save && nn == 'SPAN')
       
  4836 						nn = 'FONT';
       
  4837 				}
       
  4838 
       
  4839 				if (this.vElementsRe.test(nn) && (!this.iveRe || !this.iveRe.test(nn)) && !inn) {
       
  4840 					va = true;
       
  4841 
       
  4842 					r = this.rules[nn];
       
  4843 					if (!r) {
       
  4844 						at = this.rules;
       
  4845 						for (no in at) {
       
  4846 							if (at[no] && at[no].validRe.test(nn)) {
       
  4847 								r = at[no];
       
  4848 								break;
       
  4849 							}
       
  4850 						}
       
  4851 					}
       
  4852 
       
  4853 					en = r.isWild ? nn.toLowerCase() : r.oTagName;
       
  4854 					f = r.fill;
       
  4855 
       
  4856 					if (r.removeEmpty && !hc)
       
  4857 						return "";
       
  4858 
       
  4859 					t = '<' + en;
       
  4860 
       
  4861 					if (r.vAttribsReIsWild) {
       
  4862 						// Serialize wildcard attributes
       
  4863 						at = n.attributes;
       
  4864 						for (i=at.length-1; i>-1; i--) {
       
  4865 							no = at[i];
       
  4866 							if (no.specified && r.vAttribsRe.test(no.nodeName))
       
  4867 								t += this._serializeAttribute(n, r, no.nodeName);
       
  4868 						}
       
  4869 					} else {
       
  4870 						// Serialize specific attributes
       
  4871 						for (i=r.vAttribs.length-1; i>-1; i--)
       
  4872 							t += this._serializeAttribute(n, r, r.vAttribs[i]);
       
  4873 					}
       
  4874 
       
  4875 					// Serialize mce_ atts
       
  4876 					if (!this.settings.on_save) {
       
  4877 						at = this.mceAttribs;
       
  4878 
       
  4879 						for (no in at) {
       
  4880 							if (at[no])
       
  4881 								t += this._serializeAttribute(n, r, at[no]);
       
  4882 						}
       
  4883 					}
       
  4884 
       
  4885 					// Check for required attribs
       
  4886 					if (r.reqAttribsRe && !t.match(r.reqAttribsRe))
       
  4887 						t = null;
       
  4888 
       
  4889 					// Close these
       
  4890 					if (t != null && this.closeElementsRe.test(nn))
       
  4891 						return t + ' />';
       
  4892 
       
  4893 					if (t != null)
       
  4894 						h += t + '>';
       
  4895 
       
  4896 					if (this.isIE && this.codeElementsRe.test(nn))
       
  4897 						h += n.innerHTML;
       
  4898 				}
       
  4899 			break;
       
  4900 
       
  4901 			case 3: // Text
       
  4902 				if (st)
       
  4903 					break;
       
  4904 
       
  4905 				if (n.parentNode && this.codeElementsRe.test(n.parentNode.nodeName))
       
  4906 					return this.isIE ? '' : n.nodeValue;
       
  4907 
       
  4908 				return this.xmlEncode(n.nodeValue);
       
  4909 
       
  4910 			case 8: // Comment
       
  4911 				if (st)
       
  4912 					break;
       
  4913 
       
  4914 				return "<!--" + this._trimComment(n.nodeValue) + "-->";
       
  4915 		}
       
  4916 
       
  4917 		if (hc) {
       
  4918 			cn = n.childNodes;
       
  4919 
       
  4920 			for (i=0, l=cn.length; i<l; i++)
       
  4921 				h += this.serializeNodeAsHTML(cn[i]);
       
  4922 		}
       
  4923 
       
  4924 		// Fill empty nodes
       
  4925 		if (f && !hc)
       
  4926 			h += this.fillStr;
       
  4927 
       
  4928 		// End element
       
  4929 		if (t != null && va)
       
  4930 			h += '</' + en + '>';
       
  4931 
       
  4932 		return h;
       
  4933 	},
       
  4934 
       
  4935 	_serializeAttribute : function(n, r, an) {
       
  4936 		var av = '', t, os = this.settings.on_save;
       
  4937 
       
  4938 		if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0))
       
  4939 			return '';
       
  4940 
       
  4941 		if (os && this.mceAttribs[an])
       
  4942 			av = this._getAttrib(n, this.mceAttribs[an]);
       
  4943 
       
  4944 		if (av.length == 0)
       
  4945 			av = this._getAttrib(n, an);
       
  4946 
       
  4947 		if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) {
       
  4948 			av = t;
       
  4949 
       
  4950 			if (av == "mce_empty")
       
  4951 				return " " + an + '=""';
       
  4952 		}
       
  4953 
       
  4954 		if (r.forceAttribs && (t = r.forceAttribs[an]))
       
  4955 			av = t;
       
  4956 
       
  4957 		if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an))
       
  4958 			av = this._urlConverter(this, n, av);
       
  4959 
       
  4960 		if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av))
       
  4961 			return "";
       
  4962 
       
  4963 		if (av.length != 0 && av == "{$uid}")
       
  4964 			av = "uid_" + (this.idCount++);
       
  4965 
       
  4966 		if (av.length != 0) {
       
  4967 			if (an.indexOf('on') != 0)
       
  4968 				av = this.xmlEncode(av, 1);
       
  4969 
       
  4970 			return " " + an + "=" + '"' + av + '"';
       
  4971 		}
       
  4972 
       
  4973 		return "";
       
  4974 	},
       
  4975 
       
  4976 	formatHTML : function(h) {
       
  4977 		var s = this.settings, p = '', i = 0, li = 0, o = '', l;
       
  4978 
       
  4979 		// Replace BR in pre elements to \n
       
  4980 		h = h.replace(/<pre([^>]*)>(.*?)<\/pre>/gi, function (a, b, c) {
       
  4981 			c = c.replace(/<br\s*\/>/gi, '\n');
       
  4982 			return '<pre' + b + '>' + c + '</pre>';
       
  4983 		});
       
  4984 
       
  4985 		h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :)
       
  4986 		h = '\n' + h;
       
  4987 		h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting
       
  4988 		h = h.replace(this.nlBeforeRe, '\n<$1$2>');
       
  4989 		h = h.replace(this.nlAfterRe, '<$1$2>\n');
       
  4990 		h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n');
       
  4991 		h += '\n';
       
  4992 
       
  4993 		//tinyMCE.debug(h);
       
  4994 
       
  4995 		while ((i = h.indexOf('\n', i + 1)) != -1) {
       
  4996 			if ((l = h.substring(li + 1, i)).length != 0) {
       
  4997 				if (this.ouRe.test(l) && p.length >= s.indent_levels)
       
  4998 					p = p.substring(s.indent_levels);
       
  4999 
       
  5000 				o += p + l + '\n';
       
  5001 	
       
  5002 				if (this.inRe.test(l))
       
  5003 					p += this.inStr;
       
  5004 			}
       
  5005 
       
  5006 			li = i;
       
  5007 		}
       
  5008 
       
  5009 		//tinyMCE.debug(h);
       
  5010 
       
  5011 		return o;
       
  5012 	},
       
  5013 
       
  5014 	xmlEncode : function(s, skip_apos) {
       
  5015 		var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe;
       
  5016 
       
  5017 		this._setupEntities(); // Will intialize lookup table
       
  5018 
       
  5019 		switch (this.settings.entity_encoding) {
       
  5020 			case "raw":
       
  5021 				return tinyMCE.xmlEncode(s, skip_apos);
       
  5022 
       
  5023 			case "named":
       
  5024 				return s.replace(re, function (c, b) {
       
  5025 					b = cl.entities[c.charCodeAt(0)];
       
  5026 
       
  5027 					return b ? '&' + b + ';' : c;
       
  5028 				});
       
  5029 
       
  5030 			case "numeric":
       
  5031 				return s.replace(re, function (c, b) {
       
  5032 					return b ? '&#' + c.charCodeAt(0) + ';' : c;
       
  5033 				});
       
  5034 		}
       
  5035 
       
  5036 		return s;
       
  5037 	},
       
  5038 
       
  5039 	split : function(re, s) {
       
  5040 		var c = s.split(re);
       
  5041 		var i, l, o = new Array();
       
  5042 
       
  5043 		for (i=0, l=c.length; i<l; i++) {
       
  5044 			if (c[i] != '')
       
  5045 				o[i] = c[i];
       
  5046 		}
       
  5047 
       
  5048 		return o;
       
  5049 	},
       
  5050 
       
  5051 	_trimComment : function(s) {
       
  5052 		// Remove mce_src, mce_href
       
  5053 		s = s.replace(new RegExp('\\smce_src=\"[^\"]*\"', 'gi'), "");
       
  5054 		s = s.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), "");
       
  5055 
       
  5056 		return s;
       
  5057 	},
       
  5058 
       
  5059 	_getAttrib : function(e, n, d) {
       
  5060 		var v, ex, nn;
       
  5061 
       
  5062 		if (typeof(d) == "undefined")
       
  5063 			d = "";
       
  5064 
       
  5065 		if (!e || e.nodeType != 1)
       
  5066 			return d;
       
  5067 
       
  5068 		try {
       
  5069 			v = e.getAttribute(n, 0);
       
  5070 		} catch (ex) {
       
  5071 			// IE 7 may cast exception on invalid attributes
       
  5072 			v = e.getAttribute(n, 2);
       
  5073 		}
       
  5074 
       
  5075 		if (n == "class" && !v)
       
  5076 			v = e.className;
       
  5077 
       
  5078 		if (this.isIE) {
       
  5079 			if (n == "http-equiv")
       
  5080 				v = e.httpEquiv;
       
  5081 
       
  5082 			nn = e.nodeName;
       
  5083 
       
  5084 			// Skip the default values that IE returns
       
  5085 			if (nn == "FORM" && n == "enctype" && v == "application/x-www-form-urlencoded")
       
  5086 				v = "";
       
  5087 
       
  5088 			if (nn == "INPUT" && n == "size" && v == "20")
       
  5089 				v = "";
       
  5090 
       
  5091 			if (nn == "INPUT" && n == "maxlength" && v == "2147483647")
       
  5092 				v = "";
       
  5093 		}
       
  5094 
       
  5095 		if (n == 'style' && v) {
       
  5096 			if (!tinyMCE.isOpera)
       
  5097 				v = e.style.cssText;
       
  5098 
       
  5099 			v = tinyMCE.serializeStyle(tinyMCE.parseStyle(v));
       
  5100 		}
       
  5101 
       
  5102 		if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v != "")
       
  5103 			v = tinyMCE.cleanupEventStr(v);
       
  5104 
       
  5105 		return (v && v != "") ? '' + v : d;
       
  5106 	},
       
  5107 
       
  5108 	_urlConverter : function(c, n, v) {
       
  5109 		if (!c.settings.on_save)
       
  5110 			return tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, v);
       
  5111 		else if (tinyMCE.getParam('convert_urls')) {
       
  5112 			if (!this.urlConverter)
       
  5113 				this.urlConverter = eval(tinyMCE.settings.urlconverter_callback);
       
  5114 
       
  5115 			return this.urlConverter(v, n, true);
       
  5116 		}
       
  5117 
       
  5118 		return v;
       
  5119 	},
       
  5120 
       
  5121 	_arrayToRe : function(a, op, be, af) {
       
  5122 		var i, r;
       
  5123 
       
  5124 		op = typeof(op) == "undefined" ? "gi" : op;
       
  5125 		be = typeof(be) == "undefined" ? "^(" : be;
       
  5126 		af = typeof(af) == "undefined" ? ")$" : af;
       
  5127 
       
  5128 		r = be;
       
  5129 
       
  5130 		for (i=0; i<a.length; i++)
       
  5131 			r += this._wildcardToRe(a[i]) + (i != a.length-1 ? "|" : "");
       
  5132 
       
  5133 		r += af;
       
  5134 
       
  5135 		return new RegExp(r, op);
       
  5136 	},
       
  5137 
       
  5138 	_wildcardToRe : function(s) {
       
  5139 		s = s.replace(/\?/g, '(\\S?)');
       
  5140 		s = s.replace(/\+/g, '(\\S+)');
       
  5141 		s = s.replace(/\*/g, '(\\S*)');
       
  5142 
       
  5143 		return s;
       
  5144 	},
       
  5145 
       
  5146 	_setupEntities : function() {
       
  5147 		var n, a, i, s = this.settings;
       
  5148 
       
  5149 		// Setup entities
       
  5150 		if (!this.entitiesDone) {
       
  5151 			if (s.entity_encoding == "named") {
       
  5152 				n = tinyMCE.clearArray(new Array());
       
  5153 				a = this.split(',', s.entities);
       
  5154 				for (i=0; i<a.length; i+=2)
       
  5155 					n[a[i]] = a[i+1];
       
  5156 
       
  5157 				this.entities = n;
       
  5158 			}
       
  5159 
       
  5160 			this.entitiesDone = true;
       
  5161 		}
       
  5162 	},
       
  5163 
       
  5164 	_setupRules : function() {
       
  5165 		var s = this.settings;
       
  5166 
       
  5167 		// Setup default rule
       
  5168 		if (!this.rulesDone) {
       
  5169 			this.addRuleStr(s.valid_elements);
       
  5170 			this.addRuleStr(s.extended_valid_elements);
       
  5171 			this.addChildRemoveRuleStr(s.valid_child_elements);
       
  5172 
       
  5173 			this.rulesDone = true;
       
  5174 		}
       
  5175 	},
       
  5176 
       
  5177 	_isDuplicate : function(n) {
       
  5178 		var i;
       
  5179 
       
  5180 		if (!this.settings.fix_content_duplication)
       
  5181 			return false;
       
  5182 
       
  5183 		if (tinyMCE.isRealIE && n.nodeType == 1) {
       
  5184 			// Mark elements
       
  5185 			if (n.mce_serialized == this.serializationId)
       
  5186 				return true;
       
  5187 
       
  5188 			n.setAttribute('mce_serialized', this.serializationId);
       
  5189 		} else {
       
  5190 			// Search lookup table for text nodes  and comments
       
  5191 			for (i=0; i<this.serializedNodes.length; i++) {
       
  5192 				if (this.serializedNodes[i] == n)
       
  5193 					return true;
       
  5194 			}
       
  5195 
       
  5196 			this.serializedNodes[this.serializedNodes.length] = n;
       
  5197 		}
       
  5198 
       
  5199 		return false;
       
  5200 	}
       
  5201 
       
  5202 	};
       
  5203 
       
  5204 /* file:jscripts/tiny_mce/classes/TinyMCE_DOMUtils.class.js */
       
  5205 
       
  5206 TinyMCE_Engine.prototype.createTagHTML = function(tn, a, h) {
       
  5207 	var o = '', f = tinyMCE.xmlEncode;
       
  5208 
       
  5209 	o = '<' + tn;
       
  5210 
       
  5211 	if (a) {
       
  5212 		for (n in a) {
       
  5213 			if (typeof(a[n]) != 'function' && a[n] != null)
       
  5214 				o += ' ' + f(n) + '="' + f('' + a[n]) + '"';
       
  5215 		}
       
  5216 	}
       
  5217 
       
  5218 	o += !h ? ' />' : '>' + h + '</' + tn + '>';
       
  5219 
       
  5220 	return o;
       
  5221 };
       
  5222 
       
  5223 TinyMCE_Engine.prototype.createTag = function(d, tn, a, h) {
       
  5224 	var o = d.createElement(tn);
       
  5225 
       
  5226 	if (a) {
       
  5227 		for (n in a) {
       
  5228 			if (typeof(a[n]) != 'function' && a[n] != null)
       
  5229 				tinyMCE.setAttrib(o, n, a[n]);
       
  5230 		}
       
  5231 	}
       
  5232 
       
  5233 	if (h)
       
  5234 		o.innerHTML = h;
       
  5235 
       
  5236 	return o;
       
  5237 };
       
  5238 
       
  5239 TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) {
       
  5240 	return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
       
  5241 };
       
  5242 
       
  5243 TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) {
       
  5244 	var i, nl = n.getElementsByTagName(e), o = new Array();
       
  5245 
       
  5246 	for (i=0; i<nl.length; i++) {
       
  5247 		if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
       
  5248 			o[o.length] = nl[i];
       
  5249 	}
       
  5250 
       
  5251 	return o;
       
  5252 };
       
  5253 
       
  5254 TinyMCE_Engine.prototype.isBlockElement = function(n) {
       
  5255 	return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
       
  5256 };
       
  5257 
       
  5258 TinyMCE_Engine.prototype.getParentBlockElement = function(n, r) {
       
  5259 	return this.getParentNode(n, function(n) {
       
  5260 		return tinyMCE.isBlockElement(n);
       
  5261 	}, r);
       
  5262 
       
  5263 	return null;
       
  5264 };
       
  5265 
       
  5266 TinyMCE_Engine.prototype.insertAfter = function(n, r){
       
  5267 	if (r.nextSibling)
       
  5268 		r.parentNode.insertBefore(n, r.nextSibling);
       
  5269 	else
       
  5270 		r.parentNode.appendChild(n);
       
  5271 };
       
  5272 
       
  5273 TinyMCE_Engine.prototype.setInnerHTML = function(e, h) {
       
  5274 	var i, nl, n;
       
  5275 
       
  5276 	// Convert all strong/em to b/i in Gecko
       
  5277 	if (tinyMCE.isGecko) {
       
  5278 		h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>');
       
  5279 		h = h.replace(/<em([^>]*)>/gi, '<i$1>');
       
  5280 		h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>');
       
  5281 		h = h.replace(/<strong([^>]*)>/gi, '<b$1>');
       
  5282 		h = h.replace(/<\/strong>/gi, '</b>');
       
  5283 		h = h.replace(/<\/em>/gi, '</i>');
       
  5284 	}
       
  5285 
       
  5286 	if (tinyMCE.isRealIE) {
       
  5287 		// Since MSIE handles invalid HTML better that valid XHTML we
       
  5288 		// need to make some things invalid. <hr /> gets converted to <hr>.
       
  5289 		h = h.replace(/\s\/>/g, '>');
       
  5290 
       
  5291 		// Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
       
  5292 		h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
       
  5293 		h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
       
  5294 		h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
       
  5295 
       
  5296 		// Remove first comment
       
  5297 		e.innerHTML = tinyMCE.uniqueTag + h;
       
  5298 		e.firstChild.removeNode(true);
       
  5299 
       
  5300 		// Remove weird auto generated empty paragraphs unless it's supposed to be there
       
  5301 		nl = e.getElementsByTagName("p");
       
  5302 		for (i=nl.length-1; i>=0; i--) {
       
  5303 			n = nl[i];
       
  5304 
       
  5305 			if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
       
  5306 				n.parentNode.removeChild(n);
       
  5307 		}
       
  5308 	} else {
       
  5309 		h = this.fixGeckoBaseHREFBug(1, e, h);
       
  5310 		e.innerHTML = h;
       
  5311 		this.fixGeckoBaseHREFBug(2, e, h);
       
  5312 	}
       
  5313 };
       
  5314 
       
  5315 TinyMCE_Engine.prototype.getOuterHTML = function(e) {
       
  5316 	if (tinyMCE.isIE)
       
  5317 		return e.outerHTML;
       
  5318 
       
  5319 	var d = e.ownerDocument.createElement("body");
       
  5320 	d.appendChild(e.cloneNode(true));
       
  5321 	return d.innerHTML;
       
  5322 };
       
  5323 
       
  5324 TinyMCE_Engine.prototype.setOuterHTML = function(e, h, d) {
       
  5325 	var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
       
  5326 
       
  5327 	if (tinyMCE.isIE && e.nodeType == 1)
       
  5328 		e.outerHTML = h;
       
  5329 	else {
       
  5330 		t = d.createElement("body");
       
  5331 		t.innerHTML = h;
       
  5332 
       
  5333 		for (i=0, nl=t.childNodes; i<nl.length; i++)
       
  5334 			e.parentNode.insertBefore(nl[i].cloneNode(true), e);
       
  5335 
       
  5336 		e.parentNode.removeChild(e);
       
  5337 	}
       
  5338 };
       
  5339 
       
  5340 TinyMCE_Engine.prototype._getElementById = function(id, d) {
       
  5341 	var e, i, j, f;
       
  5342 
       
  5343 	if (typeof(d) == "undefined")
       
  5344 		d = document;
       
  5345 
       
  5346 	e = d.getElementById(id);
       
  5347 	if (!e) {
       
  5348 		f = d.forms;
       
  5349 
       
  5350 		for (i=0; i<f.length; i++) {
       
  5351 			for (j=0; j<f[i].elements.length; j++) {
       
  5352 				if (f[i].elements[j].name == id) {
       
  5353 					e = f[i].elements[j];
       
  5354 					break;
       
  5355 				}
       
  5356 			}
       
  5357 		}
       
  5358 	}
       
  5359 
       
  5360 	return e;
       
  5361 };
       
  5362 
       
  5363 TinyMCE_Engine.prototype.getNodeTree = function(n, na, t, nn) {
       
  5364 	return this.selectNodes(n, function(n) {
       
  5365 		return (!t || n.nodeType == t) && (!nn || n.nodeName == nn);
       
  5366 	}, na ? na : new Array());
       
  5367 };
       
  5368 
       
  5369 TinyMCE_Engine.prototype.getParentElement = function(n, na, f, r) {
       
  5370 	var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v;
       
  5371 
       
  5372 	// Compatiblity with old scripts where f param was a attribute string
       
  5373 	if (f && typeof(f) == 'string')
       
  5374 		return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) != '';});
       
  5375 
       
  5376 	return this.getParentNode(n, function(n) {
       
  5377 		return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n));
       
  5378 	}, r);
       
  5379 };
       
  5380 
       
  5381 TinyMCE_Engine.prototype.getParentNode = function(n, f, r) {
       
  5382 	while (n) {
       
  5383 		if (n == r)
       
  5384 			return null;
       
  5385 
       
  5386 		if (f(n))
       
  5387 			return n;
       
  5388 
       
  5389 		n = n.parentNode;
       
  5390 	}
       
  5391 
       
  5392 	return null;
       
  5393 };
       
  5394 
       
  5395 TinyMCE_Engine.prototype.getAttrib = function(elm, name, dv) {
       
  5396 	var v;
       
  5397 
       
  5398 	if (typeof(dv) == "undefined")
       
  5399 		dv = "";
       
  5400 
       
  5401 	// Not a element
       
  5402 	if (!elm || elm.nodeType != 1)
       
  5403 		return dv;
       
  5404 
       
  5405 	try {
       
  5406 		v = elm.getAttribute(name, 0);
       
  5407 	} catch (ex) {
       
  5408 		// IE 7 may cast exception on invalid attributes
       
  5409 		v = elm.getAttribute(name, 2);
       
  5410 	}
       
  5411 
       
  5412 	// Try className for class attrib
       
  5413 	if (name == "class" && !v)
       
  5414 		v = elm.className;
       
  5415 
       
  5416 	// Workaround for a issue with Firefox 1.5rc2+
       
  5417 	if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "")
       
  5418 		v = elm.src;
       
  5419 
       
  5420 	// Workaround for a issue with Firefox 1.5rc2+
       
  5421 	if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")
       
  5422 		v = elm.href;
       
  5423 
       
  5424 	if (name == "http-equiv" && tinyMCE.isIE)
       
  5425 		v = elm.httpEquiv;
       
  5426 
       
  5427 	if (name == "style" && !tinyMCE.isOpera)
       
  5428 		v = elm.style.cssText;
       
  5429 
       
  5430 	return (v && v != "") ? v : dv;
       
  5431 };
       
  5432 
       
  5433 TinyMCE_Engine.prototype.setAttrib = function(el, name, va, fix) {
       
  5434 	if (typeof(va) == "number" && va != null)
       
  5435 		va = "" + va;
       
  5436 
       
  5437 	if (fix) {
       
  5438 		if (va == null)
       
  5439 			va = "";
       
  5440 
       
  5441 		va = va.replace(/[^0-9%]/g, '');
       
  5442 	}
       
  5443 
       
  5444 	if (name == "style")
       
  5445 		el.style.cssText = va;
       
  5446 
       
  5447 	if (name == "class")
       
  5448 		el.className = va;
       
  5449 
       
  5450 	if (va != null && va != "" && va != -1)
       
  5451 		el.setAttribute(name, va);
       
  5452 	else
       
  5453 		el.removeAttribute(name);
       
  5454 };
       
  5455 
       
  5456 TinyMCE_Engine.prototype.setStyleAttrib = function(e, n, v) {
       
  5457 	e.style[n] = v;
       
  5458 
       
  5459 	// Style attrib deleted in IE
       
  5460 	if (tinyMCE.isIE && v == null || v == '') {
       
  5461 		v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText));
       
  5462 		e.style.cssText = v;
       
  5463 		e.setAttribute("style", v);
       
  5464 	}
       
  5465 };
       
  5466 
       
  5467 TinyMCE_Engine.prototype.switchClass = function(ei, c) {
       
  5468 	var e;
       
  5469 
       
  5470 	if (tinyMCE.switchClassCache[ei])
       
  5471 		e = tinyMCE.switchClassCache[ei];
       
  5472 	else
       
  5473 		e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);
       
  5474 
       
  5475 	if (e) {
       
  5476 		// Keep tile mode
       
  5477 		if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
       
  5478 			c = 'mceTiledButton ' + c;
       
  5479 
       
  5480 		e.className = c;
       
  5481 	}
       
  5482 };
       
  5483 
       
  5484 TinyMCE_Engine.prototype.getAbsPosition = function(n, cn) {
       
  5485 	var l = 0, t = 0;
       
  5486 
       
  5487 	while (n && n != cn) {
       
  5488 		l += n.offsetLeft;
       
  5489 		t += n.offsetTop;
       
  5490 		n = n.offsetParent;
       
  5491 	}
       
  5492 
       
  5493 	return {absLeft : l, absTop : t};
       
  5494 };
       
  5495 
       
  5496 TinyMCE_Engine.prototype.prevNode = function(e, n) {
       
  5497 	var a = n.split(','), i;
       
  5498 
       
  5499 	while ((e = e.previousSibling) != null) {
       
  5500 		for (i=0; i<a.length; i++) {
       
  5501 			if (e.nodeName == a[i])
       
  5502 				return e;
       
  5503 		}
       
  5504 	}
       
  5505 
       
  5506 	return null;
       
  5507 };
       
  5508 
       
  5509 TinyMCE_Engine.prototype.nextNode = function(e, n) {
       
  5510 	var a = n.split(','), i;
       
  5511 
       
  5512 	while ((e = e.nextSibling) != null) {
       
  5513 		for (i=0; i<a.length; i++) {
       
  5514 			if (e.nodeName == a[i])
       
  5515 				return e;
       
  5516 		}
       
  5517 	}
       
  5518 
       
  5519 	return null;
       
  5520 };
       
  5521 
       
  5522 TinyMCE_Engine.prototype.selectElements = function(n, na, f) {
       
  5523 	var i, a = [], nl, x;
       
  5524 
       
  5525 	for (x=0, na = na.split(','); x<na.length; x++)
       
  5526 		for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++)
       
  5527 			(!f || f(nl[i])) && a.push(nl[i]);
       
  5528 
       
  5529 	return a;
       
  5530 };
       
  5531 
       
  5532 TinyMCE_Engine.prototype.selectNodes = function(n, f, a) {
       
  5533 	var i;
       
  5534 
       
  5535 	if (!a)
       
  5536 		a = new Array();
       
  5537 
       
  5538 	if (f(n))
       
  5539 		a[a.length] = n;
       
  5540 
       
  5541 	if (n.hasChildNodes()) {
       
  5542 		for (i=0; i<n.childNodes.length; i++)
       
  5543 			tinyMCE.selectNodes(n.childNodes[i], f, a);
       
  5544 	}
       
  5545 
       
  5546 	return a;
       
  5547 };
       
  5548 
       
  5549 TinyMCE_Engine.prototype.addCSSClass = function(e, c, b) {
       
  5550 	var o = this.removeCSSClass(e, c);
       
  5551 	return e.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
       
  5552 };
       
  5553 
       
  5554 TinyMCE_Engine.prototype.removeCSSClass = function(e, c) {
       
  5555 	c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
       
  5556 	return e.className = c != ' ' ? c : '';
       
  5557 };
       
  5558 
       
  5559 TinyMCE_Engine.prototype.hasCSSClass = function(n, c) {
       
  5560 	return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
       
  5561 };
       
  5562 
       
  5563 TinyMCE_Engine.prototype.renameElement = function(e, n, d) {
       
  5564 	var ne, i, ar;
       
  5565 
       
  5566 	d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d;
       
  5567 
       
  5568 	if (e) {
       
  5569 		ne = d.createElement(n);
       
  5570 
       
  5571 		ar = e.attributes;
       
  5572 		for (i=ar.length-1; i>-1; i--) {
       
  5573 			if (ar[i].specified && ar[i].nodeValue)
       
  5574 				ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
       
  5575 		}
       
  5576 
       
  5577 		ar = e.childNodes;
       
  5578 		for (i=0; i<ar.length; i++)
       
  5579 			ne.appendChild(ar[i].cloneNode(true));
       
  5580 
       
  5581 		e.parentNode.replaceChild(ne, e);
       
  5582 	}
       
  5583 };
       
  5584 
       
  5585 TinyMCE_Engine.prototype.getViewPort = function(w) {
       
  5586 	var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement;
       
  5587 
       
  5588 	return {
       
  5589 		left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft),
       
  5590 		top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop),
       
  5591 		width : w.innerWidth || (m ? de.clientWidth : b.clientWidth),
       
  5592 		height : w.innerHeight || (m ? de.clientHeight : b.clientHeight)
       
  5593 	};
       
  5594 };
       
  5595 
       
  5596 TinyMCE_Engine.prototype.getStyle = function(n, na, d) {
       
  5597 	if (!n)
       
  5598 		return false;
       
  5599 
       
  5600 	// Gecko
       
  5601 	if (tinyMCE.isGecko && n.ownerDocument.defaultView) {
       
  5602 		try {
       
  5603 			return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na);
       
  5604 		} catch (n) {
       
  5605 			// Old safari might fail
       
  5606 			return null;
       
  5607 		}
       
  5608 	}
       
  5609 
       
  5610 	// Camelcase it, if needed
       
  5611 	na = na.replace(/-(\D)/g, function(a, b){
       
  5612 		return b.toUpperCase();
       
  5613 	});
       
  5614 
       
  5615 	// IE & Opera
       
  5616 	if (n.currentStyle)
       
  5617 		return n.currentStyle[na];
       
  5618 
       
  5619 	return false;
       
  5620 };
       
  5621 
       
  5622 /* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */
       
  5623 
       
  5624 TinyMCE_Engine.prototype.parseURL = function(url_str) {
       
  5625 	var urlParts = new Array();
       
  5626 
       
  5627 	if (url_str) {
       
  5628 		var pos, lastPos;
       
  5629 
       
  5630 		// Parse protocol part
       
  5631 		pos = url_str.indexOf('://');
       
  5632 		if (pos != -1) {
       
  5633 			urlParts['protocol'] = url_str.substring(0, pos);
       
  5634 			lastPos = pos + 3;
       
  5635 		}
       
  5636 
       
  5637 		// Find port or path start
       
  5638 		for (var i=lastPos; i<url_str.length; i++) {
       
  5639 			var chr = url_str.charAt(i);
       
  5640 
       
  5641 			if (chr == ':')
       
  5642 				break;
       
  5643 
       
  5644 			if (chr == '/')
       
  5645 				break;
       
  5646 		}
       
  5647 		pos = i;
       
  5648 
       
  5649 		// Get host
       
  5650 		urlParts['host'] = url_str.substring(lastPos, pos);
       
  5651 
       
  5652 		// Get port
       
  5653 		urlParts['port'] = "";
       
  5654 		lastPos = pos;
       
  5655 		if (url_str.charAt(pos) == ':') {
       
  5656 			pos = url_str.indexOf('/', lastPos);
       
  5657 			urlParts['port'] = url_str.substring(lastPos+1, pos);
       
  5658 		}
       
  5659 
       
  5660 		// Get path
       
  5661 		lastPos = pos;
       
  5662 		pos = url_str.indexOf('?', lastPos);
       
  5663 
       
  5664 		if (pos == -1)
       
  5665 			pos = url_str.indexOf('#', lastPos);
       
  5666 
       
  5667 		if (pos == -1)
       
  5668 			pos = url_str.length;
       
  5669 
       
  5670 		urlParts['path'] = url_str.substring(lastPos, pos);
       
  5671 
       
  5672 		// Get query
       
  5673 		lastPos = pos;
       
  5674 		if (url_str.charAt(pos) == '?') {
       
  5675 			pos = url_str.indexOf('#');
       
  5676 			pos = (pos == -1) ? url_str.length : pos;
       
  5677 			urlParts['query'] = url_str.substring(lastPos+1, pos);
       
  5678 		}
       
  5679 
       
  5680 		// Get anchor
       
  5681 		lastPos = pos;
       
  5682 		if (url_str.charAt(pos) == '#') {
       
  5683 			pos = url_str.length;
       
  5684 			urlParts['anchor'] = url_str.substring(lastPos+1, pos);
       
  5685 		}
       
  5686 	}
       
  5687 
       
  5688 	return urlParts;
       
  5689 };
       
  5690 
       
  5691 TinyMCE_Engine.prototype.serializeURL = function(up) {
       
  5692 	var o = "";
       
  5693 
       
  5694 	if (up['protocol'])
       
  5695 		o += up['protocol'] + "://";
       
  5696 
       
  5697 	if (up['host'])
       
  5698 		o += up['host'];
       
  5699 
       
  5700 	if (up['port'])
       
  5701 		o += ":" + up['port'];
       
  5702 
       
  5703 	if (up['path'])
       
  5704 		o += up['path'];
       
  5705 
       
  5706 	if (up['query'])
       
  5707 		o += "?" + up['query'];
       
  5708 
       
  5709 	if (up['anchor'])
       
  5710 		o += "#" + up['anchor'];
       
  5711 
       
  5712 	return o;
       
  5713 };
       
  5714 
       
  5715 TinyMCE_Engine.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {
       
  5716 	var baseURL = this.parseURL(base_url);
       
  5717 	var targetURL = this.parseURL(url_to_relative);
       
  5718 	var strTok1;
       
  5719 	var strTok2;
       
  5720 	var breakPoint = 0;
       
  5721 	var outPath = "";
       
  5722 	var forceSlash = false;
       
  5723 
       
  5724 	if (targetURL.path == "")
       
  5725 		targetURL.path = "/";
       
  5726 	else
       
  5727 		forceSlash = true;
       
  5728 
       
  5729 	// Crop away last path part
       
  5730 	base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));
       
  5731 	strTok1 = base_url.split('/');
       
  5732 	strTok2 = targetURL.path.split('/');
       
  5733 
       
  5734 	if (strTok1.length >= strTok2.length) {
       
  5735 		for (var i=0; i<strTok1.length; i++) {
       
  5736 			if (i >= strTok2.length || strTok1[i] != strTok2[i]) {
       
  5737 				breakPoint = i + 1;
       
  5738 				break;
       
  5739 			}
       
  5740 		}
       
  5741 	}
       
  5742 
       
  5743 	if (strTok1.length < strTok2.length) {
       
  5744 		for (var i=0; i<strTok2.length; i++) {
       
  5745 			if (i >= strTok1.length || strTok1[i] != strTok2[i]) {
       
  5746 				breakPoint = i + 1;
       
  5747 				break;
       
  5748 			}
       
  5749 		}
       
  5750 	}
       
  5751 
       
  5752 	if (breakPoint == 1)
       
  5753 		return targetURL.path;
       
  5754 
       
  5755 	for (var i=0; i<(strTok1.length-(breakPoint-1)); i++)
       
  5756 		outPath += "../";
       
  5757 
       
  5758 	for (var i=breakPoint-1; i<strTok2.length; i++) {
       
  5759 		if (i != (breakPoint-1))
       
  5760 			outPath += "/" + strTok2[i];
       
  5761 		else
       
  5762 			outPath += strTok2[i];
       
  5763 	}
       
  5764 
       
  5765 	targetURL.protocol = null;
       
  5766 	targetURL.host = null;
       
  5767 	targetURL.port = null;
       
  5768 	targetURL.path = outPath == "" && forceSlash ? "/" : outPath;
       
  5769 
       
  5770 	// Remove document prefix from local anchors
       
  5771 	var fileName = baseURL.path;
       
  5772 	var pos;
       
  5773 
       
  5774 	if ((pos = fileName.lastIndexOf('/')) != -1)
       
  5775 		fileName = fileName.substring(pos + 1);
       
  5776 
       
  5777 	// Is local anchor
       
  5778 	if (fileName == targetURL.path && targetURL.anchor != "")
       
  5779 		targetURL.path = "";
       
  5780 
       
  5781 	// If empty and not local anchor force filename or slash
       
  5782 	if (targetURL.path == "" && !targetURL.anchor)
       
  5783 		targetURL.path = fileName != "" ? fileName : "/";
       
  5784 
       
  5785 	return this.serializeURL(targetURL);
       
  5786 };
       
  5787 
       
  5788 TinyMCE_Engine.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {
       
  5789 	var baseURL = this.parseURL(base_url), baseURLParts, relURLParts;
       
  5790 	var relURL = this.parseURL(relative_url);
       
  5791 
       
  5792 	if (relative_url == "" || relative_url.indexOf('://') != -1 || /^(mailto:|javascript:|#|\/)/.test(relative_url))
       
  5793 		return relative_url;
       
  5794 
       
  5795 	// Split parts
       
  5796 	baseURLParts = baseURL['path'].split('/');
       
  5797 	relURLParts = relURL['path'].split('/');
       
  5798 
       
  5799 	// Remove empty chunks
       
  5800 	var newBaseURLParts = new Array();
       
  5801 	for (var i=baseURLParts.length-1; i>=0; i--) {
       
  5802 		if (baseURLParts[i].length == 0)
       
  5803 			continue;
       
  5804 
       
  5805 		newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
       
  5806 	}
       
  5807 	baseURLParts = newBaseURLParts.reverse();
       
  5808 
       
  5809 	// Merge relURLParts chunks
       
  5810 	var newRelURLParts = new Array();
       
  5811 	var numBack = 0;
       
  5812 	for (var i=relURLParts.length-1; i>=0; i--) {
       
  5813 		if (relURLParts[i].length == 0 || relURLParts[i] == ".")
       
  5814 			continue;
       
  5815 
       
  5816 		if (relURLParts[i] == '..') {
       
  5817 			numBack++;
       
  5818 			continue;
       
  5819 		}
       
  5820 
       
  5821 		if (numBack > 0) {
       
  5822 			numBack--;
       
  5823 			continue;
       
  5824 		}
       
  5825 
       
  5826 		newRelURLParts[newRelURLParts.length] = relURLParts[i];
       
  5827 	}
       
  5828 
       
  5829 	relURLParts = newRelURLParts.reverse();
       
  5830 
       
  5831 	// Remove end from absolute path
       
  5832 	var len = baseURLParts.length-numBack;
       
  5833 	var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
       
  5834 	var start = "", end = "";
       
  5835 
       
  5836 	// Build output URL
       
  5837 	relURL.protocol = baseURL.protocol;
       
  5838 	relURL.host = baseURL.host;
       
  5839 	relURL.port = baseURL.port;
       
  5840 
       
  5841 	// Re-add trailing slash if it's removed
       
  5842 	if (relURL.path.charAt(relURL.path.length-1) == "/")
       
  5843 		absPath += "/";
       
  5844 
       
  5845 	relURL.path = absPath;
       
  5846 
       
  5847 	return this.serializeURL(relURL);
       
  5848 };
       
  5849 
       
  5850 TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) {
       
  5851 	var prot = document.location.protocol;
       
  5852 	var host = document.location.hostname;
       
  5853 	var port = document.location.port;
       
  5854 
       
  5855 	// Pass through file protocol
       
  5856 	if (prot == "file:")
       
  5857 		return url;
       
  5858 
       
  5859 	// Something is wrong, remove weirdness
       
  5860 	url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
       
  5861 
       
  5862 	// Mailto link or anchor (Pass through)
       
  5863 	if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
       
  5864 		return url;
       
  5865 
       
  5866 	// Fix relative/Mozilla
       
  5867 	if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
       
  5868 		return tinyMCE.settings['base_href'] + url;
       
  5869 
       
  5870 	// Handle relative URLs
       
  5871 	if (on_save && tinyMCE.getParam('relative_urls')) {
       
  5872 		var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
       
  5873 		if (curl.charAt(0) == '/')
       
  5874 			curl = tinyMCE.settings['document_base_prefix'] + curl;
       
  5875 
       
  5876 		var urlParts = tinyMCE.parseURL(curl);
       
  5877 		var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
       
  5878 
       
  5879 		// Force relative
       
  5880 		if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
       
  5881 			return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
       
  5882 	}
       
  5883 
       
  5884 	// Handle absolute URLs
       
  5885 	if (!tinyMCE.getParam('relative_urls')) {
       
  5886 		var urlParts = tinyMCE.parseURL(url);
       
  5887 		var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
       
  5888 
       
  5889 		// Force absolute URLs from relative URLs
       
  5890 		url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
       
  5891 
       
  5892 		// If anchor and path is the same page
       
  5893 		if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
       
  5894 			return "#" + urlParts['anchor'];
       
  5895 	}
       
  5896 
       
  5897 	// Remove current domain
       
  5898 	if (tinyMCE.getParam('remove_script_host')) {
       
  5899 		var start = "", portPart = "";
       
  5900 
       
  5901 		if (port != "")
       
  5902 			portPart = ":" + port;
       
  5903 
       
  5904 		start = prot + "//" + host + portPart + "/";
       
  5905 
       
  5906 		if (url.indexOf(start) == 0)
       
  5907 			url = url.substring(start.length-1);
       
  5908 	}
       
  5909 
       
  5910 	return url;
       
  5911 };
       
  5912 
       
  5913 TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) {
       
  5914 	var i, elms, src, href, mhref, msrc;
       
  5915 
       
  5916 	// Convert all image URL:s to absolute URL
       
  5917 	elms = body.getElementsByTagName("img");
       
  5918 	for (i=0; i<elms.length; i++) {
       
  5919 		src = tinyMCE.getAttrib(elms[i], 'src');
       
  5920 
       
  5921 		msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
       
  5922 		if (msrc != "")
       
  5923 			src = msrc;
       
  5924 
       
  5925 		if (src != "") {
       
  5926 			src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src);
       
  5927 			elms[i].setAttribute("src", src);
       
  5928 		}
       
  5929 	}
       
  5930 
       
  5931 	// Convert all link URL:s to absolute URL
       
  5932 	elms = body.getElementsByTagName("a");
       
  5933 	for (i=0; i<elms.length; i++) {
       
  5934 		href = tinyMCE.getAttrib(elms[i], 'href');
       
  5935 
       
  5936 		mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
       
  5937 		if (mhref != "")
       
  5938 			href = mhref;
       
  5939 
       
  5940 		if (href && href != "") {
       
  5941 			href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], href);
       
  5942 			elms[i].setAttribute("href", href);
       
  5943 		}
       
  5944 	}
       
  5945 };
       
  5946 
       
  5947 /* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */
       
  5948 
       
  5949 TinyMCE_Engine.prototype.clearArray = function(a) {
       
  5950 	var n;
       
  5951 
       
  5952 	for (n in a)
       
  5953 		a[n] = null;
       
  5954 
       
  5955 	return a;
       
  5956 };
       
  5957 
       
  5958 TinyMCE_Engine.prototype.explode = function(d, s) {
       
  5959 	var ar = s.split(d), oar = new Array(), i;
       
  5960 
       
  5961 	for (i = 0; i<ar.length; i++) {
       
  5962 		if (ar[i] != "")
       
  5963 			oar[oar.length] = ar[i];
       
  5964 	}
       
  5965 
       
  5966 	return oar;
       
  5967 };
       
  5968 
       
  5969 /* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */
       
  5970 
       
  5971 TinyMCE_Engine.prototype._setEventsEnabled = function(node, state) {
       
  5972 	var evs, x, y, elms, i, event;
       
  5973 	var events = ['onfocus','onblur','onclick','ondblclick',
       
  5974 				'onmousedown','onmouseup','onmouseover','onmousemove',
       
  5975 				'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup'];
       
  5976 
       
  5977 	evs = tinyMCE.settings['event_elements'].split(',');
       
  5978 	for (y=0; y<evs.length; y++){
       
  5979 		elms = node.getElementsByTagName(evs[y]);
       
  5980 		for (i=0; i<elms.length; i++) {
       
  5981 			event = "";
       
  5982 
       
  5983 			for (x=0; x<events.length; x++) {
       
  5984 				if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {
       
  5985 					event = tinyMCE.cleanupEventStr("" + event);
       
  5986 
       
  5987 					if (!state)
       
  5988 						event = "return true;" + event;
       
  5989 					else
       
  5990 						event = event.replace(/^return true;/gi, '');
       
  5991 
       
  5992 					elms[i].removeAttribute(events[x]);
       
  5993 					elms[i].setAttribute(events[x], event);
       
  5994 				}
       
  5995 			}
       
  5996 		}
       
  5997 	}
       
  5998 };
       
  5999 
       
  6000 TinyMCE_Engine.prototype._eventPatch = function(editor_id) {
       
  6001 	var n, inst, win, e;
       
  6002 
       
  6003 	// Remove odd, error
       
  6004 	if (typeof(tinyMCE) == "undefined")
       
  6005 		return true;
       
  6006 
       
  6007 	try {
       
  6008 		// Try selected instance first
       
  6009 		if (tinyMCE.selectedInstance) {
       
  6010 			win = tinyMCE.selectedInstance.getWin();
       
  6011 
       
  6012 			if (win && win.event) {
       
  6013 				e = win.event;
       
  6014 
       
  6015 				if (!e.target)
       
  6016 					e.target = e.srcElement;
       
  6017 
       
  6018 				TinyMCE_Engine.prototype.handleEvent(e);
       
  6019 				return;
       
  6020 			}
       
  6021 		}
       
  6022 
       
  6023 		// Search for it
       
  6024 		for (n in tinyMCE.instances) {
       
  6025 			inst = tinyMCE.instances[n];
       
  6026 
       
  6027 			if (!tinyMCE.isInstance(inst))
       
  6028 				continue;
       
  6029 
       
  6030 			inst.select();
       
  6031 			win = inst.getWin();
       
  6032 
       
  6033 			if (win && win.event) {
       
  6034 				e = win.event;
       
  6035 
       
  6036 				if (!e.target)
       
  6037 					e.target = e.srcElement;
       
  6038 
       
  6039 				TinyMCE_Engine.prototype.handleEvent(e);
       
  6040 				return;
       
  6041 			}
       
  6042 		}
       
  6043 	} catch (ex) {
       
  6044 		// Ignore error if iframe is pointing to external URL
       
  6045 	}
       
  6046 };
       
  6047 
       
  6048 TinyMCE_Engine.prototype.findEvent = function(e) {
       
  6049 	var n, inst;
       
  6050 
       
  6051 	if (e)
       
  6052 		return e;
       
  6053 
       
  6054 	for (n in tinyMCE.instances) {
       
  6055 		inst = tinyMCE.instances[n];
       
  6056 
       
  6057 		if (tinyMCE.isInstance(inst) && inst.getWin().event)
       
  6058 			return inst.getWin().event;
       
  6059 	}
       
  6060 
       
  6061 	return null;
       
  6062 };
       
  6063 
       
  6064 TinyMCE_Engine.prototype.unloadHandler = function() {
       
  6065 	tinyMCE.triggerSave(true, true);
       
  6066 };
       
  6067 
       
  6068 TinyMCE_Engine.prototype.addEventHandlers = function(inst) {
       
  6069 	this.setEventHandlers(inst, 1);
       
  6070 };
       
  6071 
       
  6072 TinyMCE_Engine.prototype.setEventHandlers = function(inst, s) {
       
  6073 	var doc = inst.getDoc(), ie, ot, i, f = s ? tinyMCE.addEvent : tinyMCE.removeEvent;
       
  6074 
       
  6075 	ie = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'controlselect', 'dblclick'];
       
  6076 	ot = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'focus', 'blur', 'dragdrop'];
       
  6077 
       
  6078 	inst.switchSettings();
       
  6079 
       
  6080 	if (tinyMCE.isIE) {
       
  6081 		for (i=0; i<ie.length; i++)
       
  6082 			f(doc, ie[i], TinyMCE_Engine.prototype._eventPatch);
       
  6083 	} else {
       
  6084 		for (i=0; i<ot.length; i++)
       
  6085 			f(doc, ot[i], tinyMCE.handleEvent);
       
  6086 
       
  6087 		// Force designmode
       
  6088 		try {
       
  6089 			doc.designMode = "On";
       
  6090 		} catch (e) {
       
  6091 			// Ignore
       
  6092 		}
       
  6093 	}
       
  6094 };
       
  6095 
       
  6096 TinyMCE_Engine.prototype.onMouseMove = function() {
       
  6097 	var inst, lh;
       
  6098 
       
  6099 	// Fix for IE7 bug where it's not restoring hover on anchors correctly
       
  6100 	if (tinyMCE.lastHover) {
       
  6101 		lh = tinyMCE.lastHover;
       
  6102 
       
  6103 		// Call out on menus and refresh class on normal buttons
       
  6104 		if (lh.className.indexOf('mceMenu') != -1)
       
  6105 			tinyMCE._menuButtonEvent('out', lh);
       
  6106 		else
       
  6107 			lh.className = lh.className;
       
  6108 
       
  6109 		tinyMCE.lastHover = null;
       
  6110 	}
       
  6111 
       
  6112 	if (!tinyMCE.hasMouseMoved) {
       
  6113 		inst = tinyMCE.selectedInstance;
       
  6114 
       
  6115 		// Workaround for bug #1437457 (Odd MSIE bug)
       
  6116 		if (inst.isFocused) {
       
  6117 			inst.undoBookmark = inst.selection.getBookmark();
       
  6118 			tinyMCE.hasMouseMoved = true;
       
  6119 		}
       
  6120 	}
       
  6121 
       
  6122 //	tinyMCE.cancelEvent(inst.getWin().event);
       
  6123 //	return false;
       
  6124 };
       
  6125 
       
  6126 TinyMCE_Engine.prototype.cancelEvent = function(e) {
       
  6127 	if (!e)
       
  6128 		return false;
       
  6129 
       
  6130 	if (tinyMCE.isIE) {
       
  6131 		e.returnValue = false;
       
  6132 		e.cancelBubble = true;
       
  6133 	} else {
       
  6134 		e.preventDefault();
       
  6135 		e.stopPropagation && e.stopPropagation();
       
  6136 	}
       
  6137 
       
  6138 	return false;
       
  6139 };
       
  6140 
       
  6141 TinyMCE_Engine.prototype.addEvent = function(o, n, h) {
       
  6142 	// Add cleanup for all non unload events
       
  6143 	if (n != 'unload') {
       
  6144 		function clean() {
       
  6145 			var ex;
       
  6146 
       
  6147 			try {
       
  6148 				tinyMCE.removeEvent(o, n, h);
       
  6149 				tinyMCE.removeEvent(window, 'unload', clean);
       
  6150 				o = n = h = null;
       
  6151 			} catch (ex) {
       
  6152 				// IE may produce access denied exception on unload
       
  6153 			}
       
  6154 		}
       
  6155 
       
  6156 		// Add memory cleaner
       
  6157 		tinyMCE.addEvent(window, 'unload', clean);
       
  6158 	}
       
  6159 
       
  6160 	if (o.attachEvent)
       
  6161 		o.attachEvent("on" + n, h);
       
  6162 	else
       
  6163 		o.addEventListener(n, h, false);
       
  6164 };
       
  6165 
       
  6166 TinyMCE_Engine.prototype.removeEvent = function(o, n, h) {
       
  6167 	if (o.detachEvent)
       
  6168 		o.detachEvent("on" + n, h);
       
  6169 	else
       
  6170 		o.removeEventListener(n, h, false);
       
  6171 };
       
  6172 
       
  6173 TinyMCE_Engine.prototype.addSelectAccessibility = function(e, s, w) {
       
  6174 	// Add event handlers 
       
  6175 	if (!s._isAccessible) {
       
  6176 		s.onkeydown = tinyMCE.accessibleEventHandler;
       
  6177 		s.onblur = tinyMCE.accessibleEventHandler;
       
  6178 		s._isAccessible = true;
       
  6179 		s._win = w;
       
  6180 	}
       
  6181 
       
  6182 	return false;
       
  6183 };
       
  6184 
       
  6185 TinyMCE_Engine.prototype.accessibleEventHandler = function(e) {
       
  6186 	var win = this._win;
       
  6187 	e = tinyMCE.isIE ? win.event : e;
       
  6188 	var elm = tinyMCE.isIE ? e.srcElement : e.target;
       
  6189 
       
  6190 	// Unpiggyback onchange on blur
       
  6191 	if (e.type == "blur") {
       
  6192 		if (elm.oldonchange) {
       
  6193 			elm.onchange = elm.oldonchange;
       
  6194 			elm.oldonchange = null;
       
  6195 		}
       
  6196 
       
  6197 		return true;
       
  6198 	}
       
  6199 
       
  6200 	// Piggyback onchange
       
  6201 	if (elm.nodeName == "SELECT" && !elm.oldonchange) {
       
  6202 		elm.oldonchange = elm.onchange;
       
  6203 		elm.onchange = null;
       
  6204 	}
       
  6205 
       
  6206 	// Execute onchange and remove piggyback
       
  6207 	if (e.keyCode == 13 || e.keyCode == 32) {
       
  6208 		elm.onchange = elm.oldonchange;
       
  6209 		elm.onchange();
       
  6210 		elm.oldonchange = null;
       
  6211 
       
  6212 		tinyMCE.cancelEvent(e);
       
  6213 		return false;
       
  6214 	}
       
  6215 
       
  6216 	return true;
       
  6217 };
       
  6218 
       
  6219 TinyMCE_Engine.prototype._resetIframeHeight = function() {
       
  6220 	var ife;
       
  6221 
       
  6222 	if (tinyMCE.isRealIE) {
       
  6223 		ife = tinyMCE.selectedInstance.iframeElement;
       
  6224 
       
  6225 /*		if (ife._oldWidth) {
       
  6226 			ife.style.width = ife._oldWidth;
       
  6227 			ife.width = ife._oldWidth;
       
  6228 		}*/
       
  6229 
       
  6230 		if (ife._oldHeight) {
       
  6231 			ife.style.height = ife._oldHeight;
       
  6232 			ife.height = ife._oldHeight;
       
  6233 		}
       
  6234 	}
       
  6235 };
       
  6236 
       
  6237 /* file:jscripts/tiny_mce/classes/TinyMCE_Selection.class.js */
       
  6238 
       
  6239 function TinyMCE_Selection(inst) {
       
  6240 	this.instance = inst;
       
  6241 };
       
  6242 
       
  6243 TinyMCE_Selection.prototype = {
       
  6244 	getSelectedHTML : function() {
       
  6245 		var inst = this.instance;
       
  6246 		var e, r = this.getRng(), h;
       
  6247 
       
  6248 		if (!r)
       
  6249 			return null;
       
  6250 
       
  6251 		e = document.createElement("body");
       
  6252 
       
  6253 		if (r.cloneContents)
       
  6254 			e.appendChild(r.cloneContents());
       
  6255 		else if (typeof(r.item) != 'undefined' || typeof(r.htmlText) != 'undefined')
       
  6256 			e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;
       
  6257 		else
       
  6258 			e.innerHTML = r.toString(); // Failed, use text for now
       
  6259 
       
  6260 		h = tinyMCE._cleanupHTML(inst, inst.contentDocument, inst.settings, e, e, false, true, false);
       
  6261 
       
  6262 		// When editing always use fonts internaly
       
  6263 		//if (tinyMCE.getParam("convert_fonts_to_spans"))
       
  6264 		//	tinyMCE.convertSpansToFonts(inst.getDoc());
       
  6265 
       
  6266 		return h;
       
  6267 	},
       
  6268 
       
  6269 	getSelectedText : function() {
       
  6270 		var inst = this.instance;
       
  6271 		var d, r, s, t;
       
  6272 
       
  6273 		if (tinyMCE.isIE) {
       
  6274 			d = inst.getDoc();
       
  6275 
       
  6276 			if (d.selection.type == "Text") {
       
  6277 				r = d.selection.createRange();
       
  6278 				t = r.text;
       
  6279 			} else
       
  6280 				t = '';
       
  6281 		} else {
       
  6282 			s = this.getSel();
       
  6283 
       
  6284 			if (s && s.toString)
       
  6285 				t = s.toString();
       
  6286 			else
       
  6287 				t = '';
       
  6288 		}
       
  6289 
       
  6290 		return t;
       
  6291 	},
       
  6292 
       
  6293 	getBookmark : function(simple) {
       
  6294 		var inst = this.instance;
       
  6295 		var rng = this.getRng();
       
  6296 		var doc = inst.getDoc(), b = inst.getBody();
       
  6297 		var sp, le, s, e, nl, i, si, ei, w;
       
  6298 		var trng, sx, sy, xx = -999999999, vp = inst.getViewPort();
       
  6299 
       
  6300 		sx = vp.left;
       
  6301 		sy = vp.top;
       
  6302 
       
  6303 		if (tinyMCE.isSafari || tinyMCE.isOpera || simple)
       
  6304 			return {rng : rng, scrollX : sx, scrollY : sy};
       
  6305 
       
  6306 		if (tinyMCE.isIE) {
       
  6307 			if (rng.item) {
       
  6308 				e = rng.item(0);
       
  6309 
       
  6310 				nl = b.getElementsByTagName(e.nodeName);
       
  6311 				for (i=0; i<nl.length; i++) {
       
  6312 					if (e == nl[i]) {
       
  6313 						sp = i;
       
  6314 						break;
       
  6315 					}
       
  6316 				}
       
  6317 
       
  6318 				return {
       
  6319 					tag : e.nodeName,
       
  6320 					index : sp,
       
  6321 					scrollX : sx,
       
  6322 					scrollY : sy
       
  6323 				};
  2191 				};
  6324 			} else {
  2192 			} else {
  6325 				trng = doc.body.createTextRange();
  2193 				Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);
  6326 				trng.moveToElementText(inst.getBody());
  2194 
  6327 				trng.collapse(true);
  2195 				if (isIE || isWebKit) {
  6328 				bp = Math.abs(trng.move('character', xx));
  2196 					t = setInterval(function() {
  6329 
  2197 						if (/loaded|complete/.test(document.readyState)) {
  6330 				trng = rng.duplicate();
  2198 							clearInterval(t);
  6331 				trng.collapse(true);
  2199 							Event._pageInit();
  6332 				sp = Math.abs(trng.move('character', xx));
  2200 						}
  6333 
  2201 					}, 10);
  6334 				trng = rng.duplicate();
  2202 				}
  6335 				trng.collapse(false);
  2203 			}
  6336 				le = Math.abs(trng.move('character', xx)) - sp;
  2204 		}
       
  2205 
       
  2206 		});
       
  2207 
       
  2208 	// Shorten name
       
  2209 	Event = tinymce.dom.Event;
       
  2210 
       
  2211 	// Dispatch DOM content loaded event for IE and Safari
       
  2212 	Event._wait();
       
  2213 	tinymce.addUnload(Event._unload);
       
  2214 })();
       
  2215 
       
  2216 /* file:jscripts/tiny_mce/classes/dom/Element.js */
       
  2217 
       
  2218 (function() {
       
  2219 	var each = tinymce.each;
       
  2220 
       
  2221 	tinymce.create('tinymce.dom.Element', {
       
  2222 		Element : function(id, s) {
       
  2223 			var t = this, dom, el;
       
  2224 
       
  2225 			s = s || {};
       
  2226 			t.id = id;
       
  2227 			t.dom = dom = s.dom || tinymce.DOM;
       
  2228 			t.settings = s;
       
  2229 
       
  2230 			// Only IE leaks DOM references, this is a lot faster
       
  2231 			if (!tinymce.isIE)
       
  2232 				el = t.dom.get(t.id);
       
  2233 
       
  2234 			each([
       
  2235 				'getPos',
       
  2236 				'getRect',
       
  2237 				'getParent',
       
  2238 				'add',
       
  2239 				'setStyle',
       
  2240 				'getStyle',
       
  2241 				'setStyles',
       
  2242 				'setAttrib',
       
  2243 				'setAttribs',
       
  2244 				'getAttrib',
       
  2245 				'addClass',
       
  2246 				'removeClass',
       
  2247 				'hasClass',
       
  2248 				'getOuterHTML',
       
  2249 				'setOuterHTML',
       
  2250 				'remove',
       
  2251 				'show',
       
  2252 				'hide',
       
  2253 				'isHidden',
       
  2254 				'setHTML',
       
  2255 				'get'
       
  2256 			], function(k) {
       
  2257 				t[k] = function() {
       
  2258 					var a = arguments, o;
       
  2259 
       
  2260 					// Opera fails
       
  2261 					if (tinymce.isOpera) {
       
  2262 						a = [id];
       
  2263 
       
  2264 						each(arguments, function(v) {
       
  2265 							a.push(v);
       
  2266 						});
       
  2267 					} else
       
  2268 						Array.prototype.unshift.call(a, el || id);
       
  2269 
       
  2270 					o = dom[k].apply(dom, a);
       
  2271 					t.update(k);
       
  2272 
       
  2273 					return o;
       
  2274 				};
       
  2275 			});
       
  2276 		},
       
  2277 
       
  2278 		on : function(n, f, s) {
       
  2279 			return tinymce.dom.Event.add(this.id, n, f, s);
       
  2280 		},
       
  2281 
       
  2282 		getXY : function() {
       
  2283 			return {
       
  2284 				x : parseInt(this.getStyle('left')),
       
  2285 				y : parseInt(this.getStyle('top'))
       
  2286 			};
       
  2287 		},
       
  2288 
       
  2289 		getSize : function() {
       
  2290 			var n = this.dom.get(this.id);
       
  2291 
       
  2292 			return {
       
  2293 				w : parseInt(this.getStyle('width') || n.clientWidth),
       
  2294 				h : parseInt(this.getStyle('height') || n.clientHeight)
       
  2295 			};
       
  2296 		},
       
  2297 
       
  2298 		moveTo : function(x, y) {
       
  2299 			this.setStyles({left : x, top : y});
       
  2300 		},
       
  2301 
       
  2302 		moveBy : function(x, y) {
       
  2303 			var p = this.getXY();
       
  2304 
       
  2305 			this.moveTo(p.x + x, p.y + y);
       
  2306 		},
       
  2307 
       
  2308 		resizeTo : function(w, h) {
       
  2309 			this.setStyles({width : w, height : h});
       
  2310 		},
       
  2311 
       
  2312 		resizeBy : function(w, h) {
       
  2313 			var s = this.getSize();
       
  2314 
       
  2315 			this.resizeTo(s.w + w, s.h + h);
       
  2316 		},
       
  2317 
       
  2318 		update : function(k) {
       
  2319 			var t = this, b, dom = t.dom;
       
  2320 
       
  2321 			if (tinymce.isIE6 && t.settings.blocker) {
       
  2322 				k = k || '';
       
  2323 
       
  2324 				// Ignore getters
       
  2325 				if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0)
       
  2326 					return;
       
  2327 
       
  2328 				// Remove blocker on remove
       
  2329 				if (k == 'remove') {
       
  2330 					dom.remove(t.blocker);
       
  2331 					return;
       
  2332 				}
       
  2333 
       
  2334 				if (!t.blocker) {
       
  2335 					t.blocker = dom.uniqueId();
       
  2336 					b = dom.add(t.settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'});
       
  2337 					dom.setStyle(b, 'opacity', 0);
       
  2338 				} else
       
  2339 					b = dom.get(t.blocker);
       
  2340 
       
  2341 				dom.setStyle(b, 'left', t.getStyle('left', 1));
       
  2342 				dom.setStyle(b, 'top', t.getStyle('top', 1));
       
  2343 				dom.setStyle(b, 'width', t.getStyle('width', 1));
       
  2344 				dom.setStyle(b, 'height', t.getStyle('height', 1));
       
  2345 				dom.setStyle(b, 'display', t.getStyle('display', 1));
       
  2346 				dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);
       
  2347 			}
       
  2348 		}
       
  2349 
       
  2350 		});
       
  2351 })();
       
  2352 
       
  2353 /* file:jscripts/tiny_mce/classes/dom/Selection.js */
       
  2354 
       
  2355 (function() {
       
  2356 	// Shorten names
       
  2357 	var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;
       
  2358 
       
  2359 	tinymce.create('tinymce.dom.Selection', {
       
  2360 		Selection : function(dom, win, serializer) {
       
  2361 			var t = this;
       
  2362 
       
  2363 			t.dom = dom;
       
  2364 			t.win = win;
       
  2365 			t.serializer = serializer;
       
  2366 
       
  2367 			// Prevent leaks
       
  2368 			tinymce.addUnload(function() {
       
  2369 				t.win = null;
       
  2370 			});
       
  2371 		},
       
  2372 
       
  2373 		getContent : function(s) {
       
  2374 			var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;
       
  2375 
       
  2376 			s = s || {};
       
  2377 			wb = wa = '';
       
  2378 			s.get = true;
       
  2379 			s.format = s.format || 'html';
       
  2380 
       
  2381 			if (s.format == 'text')
       
  2382 				return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));
       
  2383 
       
  2384 			if (r.cloneContents) {
       
  2385 				n = r.cloneContents();
       
  2386 
       
  2387 				if (n)
       
  2388 					e.appendChild(n);
       
  2389 			} else if (is(r.item) || is(r.htmlText))
       
  2390 				e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;
       
  2391 			else
       
  2392 				e.innerHTML = r.toString();
       
  2393 
       
  2394 			// Keep whitespace before and after
       
  2395 			if (/^\s/.test(e.innerHTML))
       
  2396 				wb = ' ';
       
  2397 
       
  2398 			if (/\s+$/.test(e.innerHTML))
       
  2399 				wa = ' ';
       
  2400 
       
  2401 			return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;
       
  2402 		},
       
  2403 
       
  2404 		setContent : function(h, s) {
       
  2405 			var t = this, r = t.getRng(), d;
       
  2406 
       
  2407 			s = s || {format : 'html'};
       
  2408 			s.set = true;
       
  2409 			h = t.dom.processHTML(h);
       
  2410 
       
  2411 			if (r.insertNode) {
       
  2412 				d = t.win.document;
       
  2413 
       
  2414 				// Use insert HTML if it exists (places cursor after content)
       
  2415 				if (d.queryCommandEnabled('InsertHTML'))
       
  2416 					return d.execCommand('InsertHTML', false, h);
       
  2417 
       
  2418 				r.deleteContents();
       
  2419 				r.insertNode(t.getRng().createContextualFragment(h));
       
  2420 			} else {
       
  2421 				if (r.item)
       
  2422 					r.item(0).outerHTML = h;
       
  2423 				else
       
  2424 					r.pasteHTML(h);
       
  2425 			}
       
  2426 		},
       
  2427 
       
  2428 		getStart : function() {
       
  2429 			var t = this, r = t.getRng(), e;
       
  2430 
       
  2431 			if (isIE) {
       
  2432 				if (r.item)
       
  2433 					return r.item(0);
       
  2434 
       
  2435 				r = r.duplicate();
       
  2436 				r.collapse(1);
       
  2437 				e = r.parentElement();
       
  2438 
       
  2439 				if (e.nodeName == 'BODY')
       
  2440 					return e.firstChild;
       
  2441 
       
  2442 				return e;
       
  2443 			} else {
       
  2444 				e = r.startContainer;
       
  2445 
       
  2446 				if (e.nodeName == 'BODY')
       
  2447 					return e.firstChild;
       
  2448 
       
  2449 				return t.dom.getParent(e, function(n) {return n.nodeType == 1;});
       
  2450 			}
       
  2451 		},
       
  2452 
       
  2453 		getEnd : function() {
       
  2454 			var t = this, r = t.getRng(), e;
       
  2455 
       
  2456 			if (isIE) {
       
  2457 				if (r.item)
       
  2458 					return r.item(0);
       
  2459 
       
  2460 				r = r.duplicate();
       
  2461 				r.collapse(0);
       
  2462 				e = r.parentElement();
       
  2463 
       
  2464 				if (e.nodeName == 'BODY')
       
  2465 					return e.lastChild;
       
  2466 
       
  2467 				return e;
       
  2468 			} else {
       
  2469 				e = r.endContainer;
       
  2470 
       
  2471 				if (e.nodeName == 'BODY')
       
  2472 					return e.lastChild;
       
  2473 
       
  2474 				return t.dom.getParent(e, function(n) {return n.nodeType == 1;});
       
  2475 			}
       
  2476 		},
       
  2477 
       
  2478 		getBookmark : function(si) {
       
  2479 			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();
       
  2480 
       
  2481 			sx = vp.x;
       
  2482 			sy = vp.y;
       
  2483 
       
  2484 			// Simple bookmark fast but not as persistent
       
  2485 			if (si == 'simple')
       
  2486 				return {rng : r, scrollX : sx, scrollY : sy};
       
  2487 
       
  2488 			// Handle IE
       
  2489 			if (isIE) {
       
  2490 				// Control selection
       
  2491 				if (r.item) {
       
  2492 					e = r.item(0);
       
  2493 
       
  2494 					each(t.dom.select(e.nodeName), function(n, i) {
       
  2495 						if (e == n) {
       
  2496 							sp = i;
       
  2497 							return false;
       
  2498 						}
       
  2499 					});
       
  2500 
       
  2501 					return {
       
  2502 						tag : e.nodeName,
       
  2503 						index : sp,
       
  2504 						scrollX : sx,
       
  2505 						scrollY : sy
       
  2506 					};
       
  2507 				}
       
  2508 
       
  2509 				// Text selection
       
  2510 				tr = t.dom.doc.body.createTextRange();
       
  2511 				tr.moveToElementText(ro);
       
  2512 				tr.collapse(true);
       
  2513 				bp = Math.abs(tr.move('character', c));
       
  2514 
       
  2515 				tr = r.duplicate();
       
  2516 				tr.collapse(true);
       
  2517 				sp = Math.abs(tr.move('character', c));
       
  2518 
       
  2519 				tr = r.duplicate();
       
  2520 				tr.collapse(false);
       
  2521 				le = Math.abs(tr.move('character', c)) - sp;
  6337 
  2522 
  6338 				return {
  2523 				return {
  6339 					start : sp - bp,
  2524 					start : sp - bp,
  6340 					length : le,
  2525 					length : le,
  6341 					scrollX : sx,
  2526 					scrollX : sx,
  6342 					scrollY : sy
  2527 					scrollY : sy
  6343 				};
  2528 				};
  6344 			}
  2529 			}
  6345 		}
  2530 
  6346 
  2531 			// Handle W3C
  6347 		if (tinyMCE.isGecko) {
  2532 			e = t.getNode();
  6348 			s = this.getSel();
  2533 			s = t.getSel();
  6349 			e = this.getFocusElement();
       
  6350 
  2534 
  6351 			if (!s)
  2535 			if (!s)
  6352 				return null;
  2536 				return null;
  6353 
  2537 
       
  2538 			// Image selection
  6354 			if (e && e.nodeName == 'IMG') {
  2539 			if (e && e.nodeName == 'IMG') {
  6355 				/*nl = b.getElementsByTagName('IMG');
       
  6356 				for (i=0; i<nl.length; i++) {
       
  6357 					if (e == nl[i]) {
       
  6358 						sp = i;
       
  6359 						break;
       
  6360 					}
       
  6361 				}*/
       
  6362 
       
  6363 				return {
  2540 				return {
  6364 					start : -1,
       
  6365 					end : -1,
       
  6366 					index : sp,
       
  6367 					scrollX : sx,
  2541 					scrollX : sx,
  6368 					scrollY : sy
  2542 					scrollY : sy
  6369 				};
  2543 				};
  6370 			}
  2544 			}
  6371 
  2545 
       
  2546 			// Text selection
       
  2547 
       
  2548 			function getPos(r, sn, en) {
       
  2549 				var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
       
  2550 
       
  2551 				while ((n = w.nextNode()) != null) {
       
  2552 					if (n == sn)
       
  2553 						d.start = p;
       
  2554 
       
  2555 					if (n == en) {
       
  2556 						d.end = p;
       
  2557 						return d;
       
  2558 					}
       
  2559 
       
  2560 					p += n.nodeValue ? n.nodeValue.length : 0;
       
  2561 				}
       
  2562 
       
  2563 				return null;
       
  2564 			};
       
  2565 
  6372 			// Caret or selection
  2566 			// Caret or selection
  6373 			if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) {
  2567 			if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) {
  6374 				e = this._getPosText(b, s.anchorNode, s.focusNode);
  2568 				e = getPos(ro, s.anchorNode, s.focusNode);
  6375 
  2569 
  6376 				if (!e)
  2570 				if (!e)
  6377 					return {scrollX : sx, scrollY : sy};
  2571 					return {scrollX : sx, scrollY : sy};
  6378 
  2572 
  6379 				return {
  2573 				return {
  6381 					end : e.end + s.focusOffset,
  2575 					end : e.end + s.focusOffset,
  6382 					scrollX : sx,
  2576 					scrollX : sx,
  6383 					scrollY : sy
  2577 					scrollY : sy
  6384 				};
  2578 				};
  6385 			} else {
  2579 			} else {
  6386 				e = this._getPosText(b, rng.startContainer, rng.endContainer);
  2580 				e = getPos(ro, r.startContainer, r.endContainer);
  6387 
  2581 
  6388 				if (!e)
  2582 				if (!e)
  6389 					return {scrollX : sx, scrollY : sy};
  2583 					return {scrollX : sx, scrollY : sy};
  6390 
  2584 
  6391 				return {
  2585 				return {
  6392 					start : e.start + rng.startOffset,
  2586 					start : e.start + r.startOffset,
  6393 					end : e.end + rng.endOffset,
  2587 					end : e.end + r.endOffset,
  6394 					scrollX : sx,
  2588 					scrollX : sx,
  6395 					scrollY : sy
  2589 					scrollY : sy
  6396 				};
  2590 				};
  6397 			}
  2591 			}
       
  2592 		},
       
  2593 
       
  2594 		moveToBookmark : function(b) {
       
  2595 			var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd;
       
  2596 
       
  2597 			function getPos(r, sp, ep) {
       
  2598 				var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
       
  2599 
       
  2600 				while ((n = w.nextNode()) != null) {
       
  2601 					p += n.nodeValue ? n.nodeValue.length : 0;
       
  2602 
       
  2603 					if (p >= sp && !d.startNode) {
       
  2604 						d.startNode = n;
       
  2605 						d.startOffset = sp - (p - n.nodeValue.length);
       
  2606 					}
       
  2607 
       
  2608 					if (p >= ep) {
       
  2609 						d.endNode = n;
       
  2610 						d.endOffset = ep - (p - n.nodeValue.length);
       
  2611 
       
  2612 						return d;
       
  2613 					}
       
  2614 				}
       
  2615 
       
  2616 				return null;
       
  2617 			};
       
  2618 
       
  2619 			if (!b)
       
  2620 				return false;
       
  2621 
       
  2622 			t.win.scrollTo(b.scrollX, b.scrollY);
       
  2623 
       
  2624 			// Handle explorer
       
  2625 			if (isIE) {
       
  2626 				// Handle simple
       
  2627 				if (r = b.rng) {
       
  2628 					try {
       
  2629 						r.select();
       
  2630 					} catch (ex) {
       
  2631 						// Ignore
       
  2632 					}
       
  2633 
       
  2634 					return true;
       
  2635 				}
       
  2636 
       
  2637 				t.win.focus();
       
  2638 
       
  2639 				// Handle control bookmark
       
  2640 				if (b.tag) {
       
  2641 					r = ro.createControlRange();
       
  2642 
       
  2643 					each(t.dom.select(b.tag), function(n, i) {
       
  2644 						if (i == b.index)
       
  2645 							r.addElement(n);
       
  2646 					});
       
  2647 				} else {
       
  2648 					// Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs
       
  2649 					try {
       
  2650 						// Incorrect bookmark
       
  2651 						if (b.start < 0)
       
  2652 							return true;
       
  2653 
       
  2654 						r = s.createRange();
       
  2655 						r.moveToElementText(ro);
       
  2656 						r.collapse(true);
       
  2657 						r.moveStart('character', b.start);
       
  2658 						r.moveEnd('character', b.length);
       
  2659 					} catch (ex2) {
       
  2660 						return true;
       
  2661 					}
       
  2662 				}
       
  2663 
       
  2664 				r.select();
       
  2665 
       
  2666 				return true;
       
  2667 			}
       
  2668 
       
  2669 			// Handle W3C
       
  2670 			if (!s)
       
  2671 				return false;
       
  2672 
       
  2673 			// Handle simple
       
  2674 			if (b.rng) {
       
  2675 				s.removeAllRanges();
       
  2676 				s.addRange(b.rng);
       
  2677 			} else {
       
  2678 				if (is(b.start) && is(b.end)) {
       
  2679 					try {
       
  2680 						sd = getPos(ro, b.start, b.end);
       
  2681 						if (sd) {
       
  2682 							r = t.dom.doc.createRange();
       
  2683 							r.setStart(sd.startNode, sd.startOffset);
       
  2684 							r.setEnd(sd.endNode, sd.endOffset);
       
  2685 							s.removeAllRanges();
       
  2686 							s.addRange(r);
       
  2687 						}
       
  2688 
       
  2689 						if (!tinymce.isOpera)
       
  2690 							t.win.focus();
       
  2691 					} catch (ex) {
       
  2692 						// Ignore
       
  2693 					}
       
  2694 				}
       
  2695 			}
       
  2696 		},
       
  2697 
       
  2698 		select : function(n, c) {
       
  2699 			var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;
       
  2700 
       
  2701 			function first(n) {
       
  2702 				return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;
       
  2703 			};
       
  2704 
       
  2705 			function last(n) {
       
  2706 				var c, o, w;
       
  2707 
       
  2708 				if (!n)
       
  2709 					return null;
       
  2710 
       
  2711 				w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);
       
  2712 				while (c = w.nextNode())
       
  2713 					o = c;
       
  2714 
       
  2715 				return o;
       
  2716 			};
       
  2717 
       
  2718 			if (isIE) {
       
  2719 				try {
       
  2720 					b = d.body;
       
  2721 
       
  2722 					if (/^(IMG|TABLE)$/.test(n.nodeName)) {
       
  2723 						r = b.createControlRange();
       
  2724 						r.addElement(n);
       
  2725 					} else {
       
  2726 						r = b.createTextRange();
       
  2727 						r.moveToElementText(n);
       
  2728 					}
       
  2729 
       
  2730 					r.select();
       
  2731 				} catch (ex) {
       
  2732 					// Throws illigal agrument in IE some times
       
  2733 				}
       
  2734 			} else {
       
  2735 				if (c) {
       
  2736 					fn = first(n);
       
  2737 					ln = last(n);
       
  2738 
       
  2739 					if (fn && ln) {
       
  2740 						//console.debug(fn, ln);
       
  2741 						r = d.createRange();
       
  2742 						r.setStart(fn, 0);
       
  2743 						r.setEnd(ln, ln.nodeValue.length);
       
  2744 					} else
       
  2745 						r.selectNode(n);
       
  2746 				} else
       
  2747 					r.selectNode(n);
       
  2748 
       
  2749 				t.setRng(r);
       
  2750 			}
       
  2751 
       
  2752 			return n;
       
  2753 		},
       
  2754 
       
  2755 		isCollapsed : function() {
       
  2756 			var t = this, r = t.getRng();
       
  2757 
       
  2758 			if (!r || r.item)
       
  2759 				return false;
       
  2760 
       
  2761 			return r.boundingWidth == 0 || t.getSel().isCollapsed;
       
  2762 		},
       
  2763 
       
  2764 		collapse : function(b) {
       
  2765 			var t = this, r = t.getRng(), n;
       
  2766 
       
  2767 			// Control range on IE
       
  2768 			if (r.item) {
       
  2769 				n = r.item(0);
       
  2770 				r = this.win.document.body.createTextRange();
       
  2771 				r.moveToElementText(n);
       
  2772 			}
       
  2773 
       
  2774 			r.collapse(!!b);
       
  2775 			t.setRng(r);
       
  2776 		},
       
  2777 
       
  2778 		getSel : function() {
       
  2779 			var t = this, w = this.win;
       
  2780 
       
  2781 			return w.getSelection ? w.getSelection() : w.document.selection;
       
  2782 		},
       
  2783 
       
  2784 		getRng : function() {
       
  2785 			var t = this, s = t.getSel(), r;
       
  2786 
       
  2787 			if (!s)
       
  2788 				return null;
       
  2789 
       
  2790 			try {
       
  2791 				r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());
       
  2792 			} catch (ex) {
       
  2793 				// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
       
  2794 				// So lets create just an empty range for now to keep it happy
       
  2795 				r = this.win.document.body.createTextRange();
       
  2796 			}
       
  2797 
       
  2798 			return r;
       
  2799 		},
       
  2800 
       
  2801 		setRng : function(r) {
       
  2802 			var s;
       
  2803 
       
  2804 			if (!isIE) {
       
  2805 				s = this.getSel();
       
  2806 				s.removeAllRanges();
       
  2807 				s.addRange(r);
       
  2808 			} else
       
  2809 				r.select();
       
  2810 		},
       
  2811 
       
  2812 		setNode : function(n) {
       
  2813 			var t = this;
       
  2814 
       
  2815 			t.setContent(t.dom.getOuterHTML(n));
       
  2816 
       
  2817 			return n;
       
  2818 		},
       
  2819 
       
  2820 		getNode : function() {
       
  2821 			var t = this, r = t.getRng(), s = t.getSel(), e;
       
  2822 
       
  2823 			if (!isIE) {
       
  2824 				// Range maybe lost after the editor is made visible again
       
  2825 				if (!r)
       
  2826 					return t.dom.getRoot();
       
  2827 
       
  2828 				e = r.commonAncestorContainer;
       
  2829 
       
  2830 				// Handle selection a image or other control like element such as anchors
       
  2831 				if (!r.collapsed) {
       
  2832 					if (r.startContainer == r.endContainer || (tinymce.isWebKit && r.startContainer == r.endContainer.parentNode)) {
       
  2833 						if (r.startOffset - r.endOffset < 2 || tinymce.isWebKit) {
       
  2834 							if (r.startContainer.hasChildNodes())
       
  2835 								e = r.startContainer.childNodes[r.startOffset];
       
  2836 						}
       
  2837 					}
       
  2838 				}
       
  2839 
       
  2840 				return t.dom.getParent(e, function(n) {
       
  2841 					return n.nodeType == 1;
       
  2842 				});
       
  2843 			}
       
  2844 
       
  2845 			return r.item ? r.item(0) : r.parentElement();
  6398 		}
  2846 		}
  6399 
  2847 
  6400 		return null;
  2848 		});
       
  2849 })();
       
  2850 
       
  2851 /* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */
       
  2852 
       
  2853 (function() {
       
  2854 	tinymce.create('tinymce.dom.XMLWriter', {
       
  2855 		node : null,
       
  2856 
       
  2857 		XMLWriter : function(s) {
       
  2858 			// Get XML document
       
  2859 			function getXML() {
       
  2860 				var i = document.implementation;
       
  2861 
       
  2862 				if (!i || !i.createDocument) {
       
  2863 					// Try IE objects
       
  2864 					try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {}
       
  2865 					try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {}
       
  2866 				} else
       
  2867 					return i.createDocument('', '', null);
       
  2868 			};
       
  2869 
       
  2870 			this.doc = getXML();
       
  2871 			this.reset();
       
  2872 		},
       
  2873 
       
  2874 		reset : function() {
       
  2875 			var t = this, d = t.doc;
       
  2876 
       
  2877 			if (d.firstChild)
       
  2878 				d.removeChild(d.firstChild);
       
  2879 
       
  2880 			t.node = d.appendChild(d.createElement("html"));
       
  2881 		},
       
  2882 
       
  2883 		writeStartElement : function(n) {
       
  2884 			var t = this;
       
  2885 
       
  2886 			t.node = t.node.appendChild(t.doc.createElement(n));
       
  2887 		},
       
  2888 
       
  2889 		writeAttribute : function(n, v) {
       
  2890 			// Since Opera doesn't escape > into &gt; we need to do it our self
       
  2891 			if (tinymce.isOpera)
       
  2892 				v = v.replace(/>/g, '|>');
       
  2893 
       
  2894 			this.node.setAttribute(n, v);
       
  2895 		},
       
  2896 
       
  2897 		writeEndElement : function() {
       
  2898 			this.node = this.node.parentNode;
       
  2899 		},
       
  2900 
       
  2901 		writeFullEndElement : function() {
       
  2902 			var t = this, n = t.node;
       
  2903 
       
  2904 			n.appendChild(t.doc.createTextNode(""));
       
  2905 			t.node = n.parentNode;
       
  2906 		},
       
  2907 
       
  2908 		writeText : function(v) {
       
  2909 			// Since Opera doesn't escape > into &gt; we need to do it our self
       
  2910 			if (tinymce.isOpera)
       
  2911 				v = v.replace(/>/g, '|>');
       
  2912 
       
  2913 			this.node.appendChild(this.doc.createTextNode(v));
       
  2914 		},
       
  2915 
       
  2916 		writeCDATA : function(v) {
       
  2917 			this.node.appendChild(this.doc.createCDATA(v));
       
  2918 		},
       
  2919 
       
  2920 		writeComment : function(v) {
       
  2921 			this.node.appendChild(this.doc.createComment(v));
       
  2922 		},
       
  2923 
       
  2924 		getContent : function() {
       
  2925 			var h;
       
  2926 
       
  2927 			h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);
       
  2928 			h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>/g, '');
       
  2929 			h = h.replace(/ ?\/>/g, ' />');
       
  2930 
       
  2931 			// Since Opera doesn't escape > into &gt; we need to do it our self
       
  2932 			if (tinymce.isOpera)
       
  2933 				h = h.replace(/\|>/g, '&gt;');
       
  2934 
       
  2935 			return h;
       
  2936 		}
       
  2937 
       
  2938 		});
       
  2939 })();
       
  2940 
       
  2941 /* file:jscripts/tiny_mce/classes/dom/Serializer.js */
       
  2942 
       
  2943 (function() {
       
  2944 	// Shorten names
       
  2945 	var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE;
       
  2946 
       
  2947 	// Returns only attribites that have values not all attributes in IE
       
  2948 	function getIEAtts(n) {
       
  2949 		var o = [];
       
  2950 
       
  2951 		// Object will throw exception in IE
       
  2952 		if (n.nodeName == 'OBJECT')
       
  2953 			return n.attributes;
       
  2954 
       
  2955 		n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) {
       
  2956 			o.push({specified : 1, nodeName : b});
       
  2957 		});
       
  2958 
       
  2959 		return o;
       
  2960 	};
       
  2961 
       
  2962 	function wildcardToRE(s) {
       
  2963 		return s.replace(/([?+*])/g, '.$1');
       
  2964 	};
       
  2965 
       
  2966 	tinymce.create('tinymce.dom.Serializer', {
       
  2967 		Serializer : function(s) {
       
  2968 			var t = this;
       
  2969 
       
  2970 			t.key = 0;
       
  2971 			t.onPreProcess = new Dispatcher(t);
       
  2972 			t.onPostProcess = new Dispatcher(t);
       
  2973 			t.writer = new tinymce.dom.XMLWriter();
       
  2974 
       
  2975 			// Default settings
       
  2976 			t.settings = s = extend({
       
  2977 				dom : tinymce.DOM,
       
  2978 				valid_nodes : 0,
       
  2979 				node_filter : 0,
       
  2980 				attr_filter : 0,
       
  2981 				invalid_attrs : /^(mce_|_moz_$)/,
       
  2982 				closed : /(br|hr|input|meta|img|link|param)/,
       
  2983 				entity_encoding : 'named',
       
  2984 				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',
       
  2985 				valid_elements : '*[*]',
       
  2986 				extended_valid_elements : 0,
       
  2987 				valid_child_elements : 0,
       
  2988 				invalid_elements : 0,
       
  2989 				fix_table_elements : 0,
       
  2990 				fix_list_elements : true,
       
  2991 				fix_content_duplication : true,
       
  2992 				convert_fonts_to_spans : false,
       
  2993 				font_size_classes : 0,
       
  2994 				font_size_style_values : 0,
       
  2995 				apply_source_formatting : 0,
       
  2996 				indent_mode : 'simple',
       
  2997 				indent_char : '\t',
       
  2998 				indent_levels : 1,
       
  2999 				remove_linebreaks : 1
       
  3000 			}, s);
       
  3001 
       
  3002 			t.dom = s.dom;
       
  3003 
       
  3004 			if (s.fix_list_elements) {
       
  3005 				t.onPreProcess.add(function(se, o) {
       
  3006 					var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np;
       
  3007 
       
  3008 					function prevNode(e, n) {
       
  3009 						var a = n.split(','), i;
       
  3010 
       
  3011 						while ((e = e.previousSibling) != null) {
       
  3012 							for (i=0; i<a.length; i++) {
       
  3013 								if (e.nodeName == a[i])
       
  3014 									return e;
       
  3015 							}
       
  3016 						}
       
  3017 
       
  3018 						return null;
       
  3019 					};
       
  3020 
       
  3021 					for (x=0; x<a.length; x++) {
       
  3022 						nl = t.dom.select(a[x], o.node);
       
  3023 
       
  3024 						for (i=0; i<nl.length; i++) {
       
  3025 							n = nl[i];
       
  3026 							p = n.parentNode;
       
  3027 
       
  3028 							if (r.test(p.nodeName)) {
       
  3029 								np = prevNode(n, 'LI');
       
  3030 
       
  3031 								if (!np) {
       
  3032 									np = t.dom.create('li');
       
  3033 									np.innerHTML = '&nbsp;';
       
  3034 									np.appendChild(n);
       
  3035 									p.insertBefore(np, p.firstChild);
       
  3036 								} else
       
  3037 									np.appendChild(n);
       
  3038 							}
       
  3039 						}
       
  3040 					}
       
  3041 				});
       
  3042 			}
       
  3043 
       
  3044 			if (s.fix_table_elements) {
       
  3045 				t.onPreProcess.add(function(se, o) {
       
  3046 					var ta = [], d = t.dom.doc;
       
  3047 
       
  3048 					// Build list of HTML chunks and replace tables with comment placeholders
       
  3049 					each(t.dom.select('table', o.node), function(e) {
       
  3050 						var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), p = [], i, h;
       
  3051 
       
  3052 						if (pa) {
       
  3053 							t.dom.getParent(e, function(n) {
       
  3054 								if (n != e)
       
  3055 									p.push(n.nodeName);
       
  3056 							});
       
  3057 
       
  3058 							h = '';
       
  3059 
       
  3060 							for (i = 0; i < p.length; i++)
       
  3061 								h += '</' + p[i]+ '>';
       
  3062 
       
  3063 							h += t.dom.getOuterHTML(e);
       
  3064 
       
  3065 							for (i = p.length - 1; i >= 0; i--)
       
  3066 								h += '<' + p[i]+ '>';
       
  3067 
       
  3068 							ta.push(h);
       
  3069 							e.parentNode.replaceChild(d.createComment('mcetable:' + (ta.length - 1)), e);
       
  3070 						}
       
  3071 					});
       
  3072 
       
  3073 					// Replace table placeholders with end parents + table + start parents HTML code
       
  3074 					t.dom.setHTML(o.node, o.node.innerHTML.replace(/<!--mcetable:([0-9]+)-->/g, function(a, b) {
       
  3075 						return ta[parseInt(b)];
       
  3076 					}));
       
  3077 				});
       
  3078 			}
       
  3079 		},
       
  3080 
       
  3081 		encode : function(o) {
       
  3082 			var t = this, s = t.settings, l;
       
  3083 
       
  3084 			if (s.entity_encoding.indexOf('named') != -1) {
       
  3085 				t.setEntities(s.entities);
       
  3086 				l = t.entityLookup;
       
  3087 
       
  3088 				if (o.format == 'html') {
       
  3089 					o.content = o.content.replace(t.entitiesRE, function(a) {
       
  3090 						var v;
       
  3091 
       
  3092 						if (v = l[a])
       
  3093 							a = '&' + v + ';';
       
  3094 
       
  3095 						return a;
       
  3096 					});
       
  3097 				}
       
  3098 			}
       
  3099 
       
  3100 			if (s.entity_encoding.indexOf('numeric') != -1) {
       
  3101 				if (o.format == 'html') {
       
  3102 					o.content = o.content.replace(/[\u007E-\uFFFF]/g, function(a) {
       
  3103 						return '&#' + a.charCodeAt(0) + ';';
       
  3104 					});
       
  3105 				}
       
  3106 			}
       
  3107 		},
       
  3108 
       
  3109 		setEntities : function(s) {
       
  3110 			var a, i, l = {}, re = '', v;
       
  3111 
       
  3112 			// No need to setup more than once
       
  3113 			if (this.entityLookup)
       
  3114 				return;
       
  3115 
       
  3116 			// Build regex and lookup array
       
  3117 			a = s.split(',');
       
  3118 			for (i = 0; i < a.length; i += 2) {
       
  3119 				v = a[i];
       
  3120 
       
  3121 				// Don't add default &amp; &quot; etc.
       
  3122 				if (v == 34 || v == 38 || v == 60 || v == 62)
       
  3123 					continue;
       
  3124 
       
  3125 				l[String.fromCharCode(a[i])] = a[i + 1];
       
  3126 
       
  3127 				v = parseInt(a[i]).toString(16);
       
  3128 				re += '\\u' + '0000'.substring(v.length) + v;
       
  3129 			}
       
  3130 
       
  3131 			this.entitiesRE = new RegExp('[' + re + ']', 'g');
       
  3132 			this.entityLookup = l;
       
  3133 		},
       
  3134 
       
  3135 		setValidChildRules : function(s) {
       
  3136 			this.childRules = null;
       
  3137 			this.addValidChildRules(s);
       
  3138 		},
       
  3139 
       
  3140 		addValidChildRules : function(s) {
       
  3141 			var t = this, inst, intr, bloc;
       
  3142 
       
  3143 			if (!s)
       
  3144 				return;
       
  3145 
       
  3146 			inst = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment';
       
  3147 			intr = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment';
       
  3148 			bloc = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';
       
  3149 
       
  3150 			each(s.split(','), function(s) {
       
  3151 				var p = s.split(/\[|\]/), re;
       
  3152 
       
  3153 				s = '';
       
  3154 				each(p[1].split('|'), function(v) {
       
  3155 					if (s)
       
  3156 						s += '|';
       
  3157 
       
  3158 					switch (v) {
       
  3159 						case '%itrans':
       
  3160 							v = intr;
       
  3161 							break;
       
  3162 
       
  3163 						case '%itrans_na':
       
  3164 							v = intr.substring(2);
       
  3165 							break;
       
  3166 
       
  3167 						case '%istrict':
       
  3168 							v = inst;
       
  3169 							break;
       
  3170 
       
  3171 						case '%istrict_na':
       
  3172 							v = inst.substring(2);
       
  3173 							break;
       
  3174 
       
  3175 						case '%btrans':
       
  3176 							v = bloc;
       
  3177 							break;
       
  3178 
       
  3179 						case '%bstrict':
       
  3180 							v = bloc;
       
  3181 							break;
       
  3182 					}
       
  3183 
       
  3184 					s += v;
       
  3185 				});
       
  3186 				re = new RegExp('^(' + s.toLowerCase() + ')$', 'i');
       
  3187 
       
  3188 				each(p[0].split('/'), function(s) {
       
  3189 					t.childRules = t.childRules || {};
       
  3190 					t.childRules[s] = re;
       
  3191 				});
       
  3192 			});
       
  3193 
       
  3194 			// Build regex
       
  3195 			s = '';
       
  3196 			each(t.childRules, function(v, k) {
       
  3197 				if (s)
       
  3198 					s += '|';
       
  3199 
       
  3200 				s += k;
       
  3201 			});
       
  3202 
       
  3203 			t.parentElementsRE = new RegExp('^(' + s.toLowerCase() + ')$', 'i');
       
  3204 
       
  3205 			/*console.debug(t.parentElementsRE.toString());
       
  3206 			each(t.childRules, function(v) {
       
  3207 				console.debug(v.toString());
       
  3208 			});*/
       
  3209 		},
       
  3210 
       
  3211 		setRules : function(s) {
       
  3212 			var t = this;
       
  3213 
       
  3214 			t._setup();
       
  3215 			t.rules = {};
       
  3216 			t.wildRules = [];
       
  3217 			t.validElements = {};
       
  3218 
       
  3219 			return t.addRules(s);
       
  3220 		},
       
  3221 
       
  3222 		addRules : function(s) {
       
  3223 			var t = this, dr;
       
  3224 
       
  3225 			if (!s)
       
  3226 				return;
       
  3227 
       
  3228 			t._setup();
       
  3229 
       
  3230 			each(s.split(','), function(s) {
       
  3231 				var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = [];
       
  3232 
       
  3233 				// Extend with default rules
       
  3234 				if (dr)
       
  3235 					at = tinymce.extend([], dr.attribs);
       
  3236 
       
  3237 				// Parse attributes
       
  3238 				if (p.length > 1) {
       
  3239 					each(p[1].split('|'), function(s) {
       
  3240 						var ar = {}, i;
       
  3241 
       
  3242 						at = at || [];
       
  3243 
       
  3244 						// Parse attribute rule
       
  3245 						s = s.replace(/::/g, '~');
       
  3246 						s = /^([!\-])?([\w*.?~]+|)([=:<])?(.+)?$/.exec(s);
       
  3247 						s[2] = s[2].replace(/~/g, ':');
       
  3248 
       
  3249 						// Add required attributes
       
  3250 						if (s[1] == '!') {
       
  3251 							ra = ra || [];
       
  3252 							ra.push(s[2]);
       
  3253 						}
       
  3254 
       
  3255 						// Remove inherited attributes
       
  3256 						if (s[1] == '-') {
       
  3257 							for (i = 0; i <at.length; i++) {
       
  3258 								if (at[i].name == s[2]) {
       
  3259 									at.splice(i, 1);
       
  3260 									return;
       
  3261 								}
       
  3262 							}
       
  3263 						}
       
  3264 
       
  3265 						switch (s[3]) {
       
  3266 							// Add default attrib values
       
  3267 							case '=':
       
  3268 								ar.defaultVal = s[4] || '';
       
  3269 								break;
       
  3270 
       
  3271 							// Add forced attrib values
       
  3272 							case ':':
       
  3273 								ar.forcedVal = s[4];
       
  3274 								break;
       
  3275 
       
  3276 							// Add validation values
       
  3277 							case '<':
       
  3278 								ar.validVals = s[4].split('?');
       
  3279 								break;
       
  3280 						}
       
  3281 
       
  3282 						if (/[*.?]/.test(s[2])) {
       
  3283 							wat = wat || [];
       
  3284 							ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$');
       
  3285 							wat.push(ar);
       
  3286 						} else {
       
  3287 							ar.name = s[2];
       
  3288 							at.push(ar);
       
  3289 						}
       
  3290 
       
  3291 						va.push(s[2]);
       
  3292 					});
       
  3293 				}
       
  3294 
       
  3295 				// Handle element names
       
  3296 				each(tn, function(s, i) {
       
  3297 					var pr = s.charAt(0), x = 1, ru = {};
       
  3298 
       
  3299 					// Extend with default rule data
       
  3300 					if (dr) {
       
  3301 						if (dr.noEmpty)
       
  3302 							ru.noEmpty = dr.noEmpty;
       
  3303 
       
  3304 						if (dr.fullEnd)
       
  3305 							ru.fullEnd = dr.fullEnd;
       
  3306 
       
  3307 						if (dr.padd)
       
  3308 							ru.padd = dr.padd;
       
  3309 					}
       
  3310 
       
  3311 					// Handle prefixes
       
  3312 					switch (pr) {
       
  3313 						case '-':
       
  3314 							ru.noEmpty = true;
       
  3315 							break;
       
  3316 
       
  3317 						case '+':
       
  3318 							ru.fullEnd = true;
       
  3319 							break;
       
  3320 
       
  3321 						case '#':
       
  3322 							ru.padd = true;
       
  3323 							break;
       
  3324 
       
  3325 						default:
       
  3326 							x = 0;
       
  3327 					}
       
  3328 
       
  3329 					tn[i] = s = s.substring(x);
       
  3330 					t.validElements[s] = 1;
       
  3331 
       
  3332 					// Add element name or element regex
       
  3333 					if (/[*.?]/.test(tn[0])) {
       
  3334 						ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$');
       
  3335 						t.wildRules = t.wildRules || {};
       
  3336 						t.wildRules.push(ru);
       
  3337 					} else {
       
  3338 						ru.name = tn[0];
       
  3339 
       
  3340 						// Store away default rule
       
  3341 						if (tn[0] == '@')
       
  3342 							dr = ru;
       
  3343 
       
  3344 						t.rules[s] = ru;
       
  3345 					}
       
  3346 
       
  3347 					ru.attribs = at;
       
  3348 
       
  3349 					if (ra)
       
  3350 						ru.requiredAttribs = ra;
       
  3351 
       
  3352 					if (wat) {
       
  3353 						// Build valid attributes regexp
       
  3354 						s = '';
       
  3355 						each(va, function(v) {
       
  3356 							if (s)
       
  3357 								s += '|';
       
  3358 
       
  3359 							s += '(' + wildcardToRE(v) + ')';
       
  3360 						});
       
  3361 						ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$');
       
  3362 						ru.wildAttribs = wat;
       
  3363 					}
       
  3364 				});
       
  3365 			});
       
  3366 
       
  3367 			// Build valid elements regexp
       
  3368 			s = '';
       
  3369 			each(t.validElements, function(v, k) {
       
  3370 				if (s)
       
  3371 					s += '|';
       
  3372 
       
  3373 				if (k != '@')
       
  3374 				s += k;
       
  3375 			});
       
  3376 			t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$');
       
  3377 
       
  3378 			//console.debug(t.validElementsRE.toString());
       
  3379 			//console.dir(t.rules);
       
  3380 			//console.dir(t.wildRules);
       
  3381 		},
       
  3382 
       
  3383 		findRule : function(n) {
       
  3384 			var t = this, rl = t.rules, i, r;
       
  3385 
       
  3386 			t._setup();
       
  3387 
       
  3388 			// Exact match
       
  3389 			r = rl[n];
       
  3390 			if (r)
       
  3391 				return r;
       
  3392 
       
  3393 			// Try wildcards
       
  3394 			rl = t.wildRules;
       
  3395 			for (i = 0; i < rl.length; i++) {
       
  3396 				if (rl[i].nameRE.test(n))
       
  3397 					return rl[i];
       
  3398 			}
       
  3399 
       
  3400 			return null;
       
  3401 		},
       
  3402 
       
  3403 		findAttribRule : function(ru, n) {
       
  3404 			var i, wa = ru.wildAttribs;
       
  3405 
       
  3406 			for (i = 0; i < wa.length; i++) {
       
  3407 				if (wa[i].nameRE.test(n))
       
  3408 					return wa[i];
       
  3409 			}
       
  3410 
       
  3411 			return null;
       
  3412 		},
       
  3413 
       
  3414 		serialize : function(n, o) {
       
  3415 			var h, t = this;
       
  3416 
       
  3417 			t._setup();
       
  3418 			o = o || {};
       
  3419 			o.format = o.format || 'html';
       
  3420 			t.processObj = o;
       
  3421 			n = n.cloneNode(true);
       
  3422 			t.key = '' + (parseInt(t.key) + 1);
       
  3423 
       
  3424 			// Pre process
       
  3425 			if (!o.no_events) {
       
  3426 				o.node = n;
       
  3427 				t.onPreProcess.dispatch(t, o);
       
  3428 			}
       
  3429 
       
  3430 			// Serialize HTML DOM into a string
       
  3431 			t.writer.reset();
       
  3432 			t._serializeNode(n, o.getInner);
       
  3433 
       
  3434 			// Post process
       
  3435 			o.content = t.writer.getContent();
       
  3436 
       
  3437 			if (!o.no_events)
       
  3438 				t.onPostProcess.dispatch(t, o);
       
  3439 
       
  3440 			t.encode(o);
       
  3441 			t.indent(o);
       
  3442 			t._postProcess(o);
       
  3443 
       
  3444 			o.node = null;
       
  3445 
       
  3446 			return tinymce.trim(o.content);
       
  3447 		},
       
  3448 
       
  3449 		indent : function(o) {
       
  3450 			var t = this, s = t.settings, h = o.content, sc = [], p;
       
  3451 
       
  3452 			// Remove whitespace to normalize browsers
       
  3453 			if (o.format == 'html') {
       
  3454 				// Protect some elements
       
  3455 				p = t._protect({
       
  3456 					content : h,
       
  3457 					patterns : [
       
  3458 						/<script[^>]*>(.*?)<\/script>/g,
       
  3459 						/<style[^>]*>(.*?)<\/style>/g,
       
  3460 						/<pre[^>]*>(.*?)<\/pre>/g
       
  3461 					]
       
  3462 				});
       
  3463 
       
  3464 				h = p.content;
       
  3465 
       
  3466 				// Since Gecko and Safari keeps whitespace in the DOM we need to
       
  3467 				// remove it inorder to match other browsers. But I think Gecko and Safari is right.
       
  3468 				if (s.remove_linebreaks) {
       
  3469 					h = h.replace(/(<[^>]+>)\s+/g, '$1 ');
       
  3470 					h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');
       
  3471 					h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start
       
  3472 					h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start
       
  3473 					h = h.replace(/\s+<\/(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end
       
  3474 				}
       
  3475 
       
  3476 				// Simple indentation
       
  3477 				if (s.apply_source_formatting && s.indent_mode == 'simple') {
       
  3478 					// Add line breaks before and after block elements
       
  3479 					h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');
       
  3480 					h = h.replace(/<(p|h[1-6]|div|title|style|pre|script|td|li)(|[^>]+)>/g, '\n<$1$2>');
       
  3481 					h = h.replace(/<\/(p|h[1-6]|div|title|style|pre|script|td|li)>/g, '</$1>\n');
       
  3482 					h = h.replace(/\n\n/g, '\n');
       
  3483 				}
       
  3484 
       
  3485 				h = t._unprotect(h, p);
       
  3486 			}
       
  3487 
       
  3488 			o.content = h;
       
  3489 		},
       
  3490 
       
  3491 		// Internal functions
       
  3492 
       
  3493 		_serializeNode : function(n, inn) {
       
  3494 			var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;
       
  3495 
       
  3496 			if (!s.node_filter || s.node_filter(n)) {
       
  3497 				switch (n.nodeType) {
       
  3498 					case 1: // Element
       
  3499 						if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))
       
  3500 							return;
       
  3501 
       
  3502 						iv = false;
       
  3503 						hc = n.hasChildNodes();
       
  3504 
       
  3505 						nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase();
       
  3506 
       
  3507 						// Add correct prefix on IE
       
  3508 						if (isIE) {
       
  3509 							if (n.scopeName !== 'HTML')
       
  3510 								nn = n.scopeName + ':' + nn;
       
  3511 						}
       
  3512 
       
  3513 						// Remove mce prefix on IE needed for the abbr element
       
  3514 						if (nn.indexOf('mce:') === 0)
       
  3515 							nn = nn.substring(4);
       
  3516 
       
  3517 						// Check if valid
       
  3518 						if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
       
  3519 							iv = true;
       
  3520 							break;
       
  3521 						}
       
  3522 
       
  3523 						if (isIE) {
       
  3524 							// Fix IE content duplication (DOM can have multiple copies of the same node)
       
  3525 							if (s.fix_content_duplication) {
       
  3526 								if (n.mce_serialized == t.key)
       
  3527 									return;
       
  3528 
       
  3529 								n.mce_serialized = t.key;
       
  3530 							}
       
  3531 
       
  3532 							// IE sometimes adds a / infront of the node name
       
  3533 							if (nn.charAt(0) == '/')
       
  3534 								nn = nn.substring(1);
       
  3535 						}
       
  3536 
       
  3537 						// Check if valid child
       
  3538 						if (t.childRules) {
       
  3539 							if (t.parentElementsRE.test(t.elementName)) {
       
  3540 								if (!t.childRules[t.elementName].test(nn)) {
       
  3541 									iv = true;
       
  3542 									break;
       
  3543 								}
       
  3544 							}
       
  3545 
       
  3546 							t.elementName = nn;
       
  3547 						}
       
  3548 
       
  3549 						ru = t.findRule(nn);
       
  3550 						nn = ru.name || nn;
       
  3551 
       
  3552 						// Skip empty nodes or empty node name in IE
       
  3553 						if ((!hc && ru.noEmpty) || (isIE && !nn)) {
       
  3554 							iv = true;
       
  3555 							break;
       
  3556 						}
       
  3557 
       
  3558 						// Check required
       
  3559 						if (ru.requiredAttribs) {
       
  3560 							a = ru.requiredAttribs;
       
  3561 
       
  3562 							for (i = a.length - 1; i >= 0; i--) {
       
  3563 								if (this.dom.getAttrib(n, a[i]) !== '')
       
  3564 									break;
       
  3565 							}
       
  3566 
       
  3567 							// None of the required was there
       
  3568 							if (i == -1) {
       
  3569 								iv = true;
       
  3570 								break;
       
  3571 							}
       
  3572 						}
       
  3573 
       
  3574 						w.writeStartElement(nn);
       
  3575 
       
  3576 						// Add ordered attributes
       
  3577 						if (ru.attribs) {
       
  3578 							for (i=0, at = ru.attribs, l = at.length; i<l; i++) {
       
  3579 								a = at[i];
       
  3580 								v = t._getAttrib(n, a);
       
  3581 
       
  3582 								if (v !== null)
       
  3583 									w.writeAttribute(a.name, v);
       
  3584 							}
       
  3585 						}
       
  3586 
       
  3587 						// Add wild attributes
       
  3588 						if (ru.validAttribsRE) {
       
  3589 							at = isIE ? getIEAtts(n) : n.attributes;
       
  3590 							for (i=at.length-1; i>-1; i--) {
       
  3591 								no = at[i];
       
  3592 
       
  3593 								if (no.specified) {
       
  3594 									a = no.nodeName.toLowerCase();
       
  3595 
       
  3596 									if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a))
       
  3597 										continue;
       
  3598 
       
  3599 									ar = t.findAttribRule(ru, a);
       
  3600 									v = t._getAttrib(n, ar, a);
       
  3601 
       
  3602 									if (v !== null)
       
  3603 										w.writeAttribute(a, v);
       
  3604 								}
       
  3605 							}
       
  3606 						}
       
  3607 
       
  3608 						// Padd empty nodes with a &nbsp;
       
  3609 						if (!hc && ru.padd)
       
  3610 							w.writeText('\u00a0');
       
  3611 
       
  3612 						break;
       
  3613 
       
  3614 					case 3: // Text
       
  3615 						// Check if valid child
       
  3616 						if (t.childRules && t.parentElementsRE.test(t.elementName)) {
       
  3617 							if (!t.childRules[t.elementName].test(n.nodeName))
       
  3618 								return;
       
  3619 						}
       
  3620 
       
  3621 						return w.writeText(n.nodeValue);
       
  3622 
       
  3623 					case 4: // CDATA
       
  3624 						return w.writeCDATA(n.nodeValue);
       
  3625 
       
  3626 					case 8: // Comment
       
  3627 						return w.writeComment(n.nodeValue);
       
  3628 				}
       
  3629 			} else if (n.nodeType == 1)
       
  3630 				hc = n.hasChildNodes();
       
  3631 
       
  3632 			if (hc) {
       
  3633 				cn = n.firstChild;
       
  3634 
       
  3635 				while (cn) {
       
  3636 					t._serializeNode(cn);
       
  3637 					t.elementName = nn;
       
  3638 					cn = cn.nextSibling;
       
  3639 				}
       
  3640 			}
       
  3641 
       
  3642 			// Write element end
       
  3643 			if (!iv) {
       
  3644 				if (hc || !s.closed.test(nn))
       
  3645 					w.writeFullEndElement();
       
  3646 				else
       
  3647 					w.writeEndElement();
       
  3648 			}
       
  3649 		},
       
  3650 
       
  3651 		_protect : function(o) {
       
  3652 			o.items = o.items || [];
       
  3653 
       
  3654 			function enc(s) {
       
  3655 				return s.replace(/[\r\n]/g, function(c) {
       
  3656 					if (c === '\n')
       
  3657 						return '\\n';
       
  3658 
       
  3659 					return '\\r';
       
  3660 				});
       
  3661 			};
       
  3662 
       
  3663 			function dec(s) {
       
  3664 				return s.replace(/\\[rn]/g, function(c) {
       
  3665 					if (c === '\\n')
       
  3666 						return '\n';
       
  3667 
       
  3668 					return '\r';
       
  3669 				});
       
  3670 			};
       
  3671 
       
  3672 			each(o.patterns, function(p) {
       
  3673 				o.content = dec(enc(o.content).replace(p, function(a) {
       
  3674 					o.items.push(dec(a));
       
  3675 					return '<!--mce:' + (o.items.length - 1) + '-->';
       
  3676 				}));
       
  3677 			});
       
  3678 
       
  3679 			return o;
       
  3680 		},
       
  3681 
       
  3682 		_unprotect : function(h, o) {
       
  3683 			h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) {
       
  3684 				return o.items[parseInt(b)];
       
  3685 			});
       
  3686 
       
  3687 			o.items = [];
       
  3688 
       
  3689 			return h;
       
  3690 		},
       
  3691 
       
  3692 		_postProcess : function(o) {
       
  3693 			var s = this.settings, h;
       
  3694 
       
  3695 			if (o.format == 'html') {
       
  3696 				h = o.content;
       
  3697 
       
  3698 				// Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor
       
  3699 				if (o.set)
       
  3700 					h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');
       
  3701 				else
       
  3702 					h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');
       
  3703 
       
  3704 				o.content = h;
       
  3705 			}
       
  3706 		},
       
  3707 
       
  3708 		_setup : function() {
       
  3709 			var t = this, s = this.settings;
       
  3710 
       
  3711 			if (t.done)
       
  3712 				return;
       
  3713 
       
  3714 			t.done = 1;
       
  3715 
       
  3716 			t.setRules(s.valid_elements);
       
  3717 			t.addRules(s.extended_valid_elements);
       
  3718 			t.addValidChildRules(s.valid_child_elements);
       
  3719 
       
  3720 			if (s.invalid_elements)
       
  3721 				t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(',', '|').toLowerCase()) + ')$');
       
  3722 
       
  3723 			if (s.attrib_value_filter)
       
  3724 				t.attribValueFilter = s.attribValueFilter;
       
  3725 		},
       
  3726 
       
  3727 		_getAttrib : function(n, a, na) {
       
  3728 			var i, v;
       
  3729 
       
  3730 			na = na || a.name;
       
  3731 
       
  3732 			if (a.forcedVal && (v = a.forcedVal)) {
       
  3733 				if (v === '{$uid}')
       
  3734 					return this.dom.uniqueId();
       
  3735 
       
  3736 				return v;
       
  3737 			}
       
  3738 
       
  3739 			v = this.dom.getAttrib(n, na);
       
  3740 
       
  3741 			switch (na) {
       
  3742 				case 'rowspan':
       
  3743 				case 'colspan':
       
  3744 					// Whats the point? Remove usless attribute value
       
  3745 					if (v == '1')
       
  3746 						v = '';
       
  3747 
       
  3748 					break;
       
  3749 			}
       
  3750 
       
  3751 			if (this.attribValueFilter)
       
  3752 				v = this.attribValueFilter(na, v, n);
       
  3753 
       
  3754 			if (a.validVals) {
       
  3755 				for (i = a.validVals.length - 1; i >= 0; i--) {
       
  3756 					if (v == a.validVals[i])
       
  3757 						break;
       
  3758 				}
       
  3759 
       
  3760 				if (i == -1)
       
  3761 					return null;
       
  3762 			}
       
  3763 
       
  3764 			if (v === '' && typeof(a.defaultVal) != 'undefined') {
       
  3765 				v = a.defaultVal;
       
  3766 
       
  3767 				if (v === '{$uid}')
       
  3768 					return this.dom.uniqueId();
       
  3769 
       
  3770 				return v;
       
  3771 			} else {
       
  3772 				// Remove internal mceItemXX classes when content is extracted from editor
       
  3773 				if (na == 'class' && this.processObj.get)
       
  3774 					v = v.replace(/\bmceItem\w+\b/g, '');
       
  3775 			}
       
  3776 
       
  3777 			if (v === '')
       
  3778 				return null;
       
  3779 
       
  3780 
       
  3781 			return v;
       
  3782 		}
       
  3783 
       
  3784 		});
       
  3785 })();
       
  3786 
       
  3787 /* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */
       
  3788 
       
  3789 (function() {
       
  3790 	var each = tinymce.each;
       
  3791 
       
  3792 	tinymce.create('tinymce.dom.ScriptLoader', {
       
  3793 		ScriptLoader : function(s) {
       
  3794 			this.settings = s || {};
       
  3795 			this.queue = [];
       
  3796 			this.lookup = {};
       
  3797 		},
       
  3798 
       
  3799 		markDone : function(u) {
       
  3800 			this.lookup[u] = {state : 2, url : u};
       
  3801 		},
       
  3802 
       
  3803 		add : function(u, cb, s, pr) {
       
  3804 			var t = this, lo = t.lookup, o;
       
  3805 
       
  3806 			if (o = lo[u]) {
       
  3807 				// Is loaded fire callback
       
  3808 				if (cb && o.state == 2)
       
  3809 					cb.call(s || this);
       
  3810 
       
  3811 				return o;
       
  3812 			}
       
  3813 
       
  3814 			o = {state : 0, url : u, func : cb, scope : s || this};
       
  3815 
       
  3816 			if (pr)
       
  3817 				t.queue.unshift(o);
       
  3818 			else
       
  3819 				t.queue.push(o);
       
  3820 
       
  3821 			lo[u] = o;
       
  3822 
       
  3823 			return o;
       
  3824 		},
       
  3825 
       
  3826 		load : function(u, cb, s) {
       
  3827 			var o;
       
  3828 
       
  3829 			if (!tinymce.is(u, 'string')) {
       
  3830 				o = [];
       
  3831 
       
  3832 				each(u, function(u) {
       
  3833 					o.push({state : 0, url : u});
       
  3834 				});
       
  3835 
       
  3836 				this.loadScripts(o, cb, s);
       
  3837 			} else
       
  3838 				this.loadScripts([{state : 0, url : u}], cb, s);
       
  3839 		},
       
  3840 
       
  3841 		loadQueue : function(cb, s) {
       
  3842 			var t = this;
       
  3843 
       
  3844 			if (!t.queueLoading) {
       
  3845 				t.queueLoading = 1;
       
  3846 				t.queueCallbacks = [];
       
  3847 
       
  3848 				t.loadScripts(t.queue, function() {
       
  3849 					t.queueLoading = 0;
       
  3850 
       
  3851 					if (cb)
       
  3852 						cb.call(s || t);
       
  3853 
       
  3854 					each(t.queueCallbacks, function(o) {
       
  3855 						o.func.call(o.scope);
       
  3856 					});
       
  3857 				});
       
  3858 			} else if (cb)
       
  3859 				t.queueCallbacks.push({func : cb, scope : s || t});
       
  3860 		},
       
  3861 
       
  3862 		eval : function(co) {
       
  3863 			var w = window;
       
  3864 
       
  3865 			// Evaluate script
       
  3866 			if (!w.execScript) {
       
  3867 				try {
       
  3868 					eval.call(w, co);
       
  3869 				} catch (ex) {
       
  3870 					eval(co, w); // Firefox 3.0a8
       
  3871 				}
       
  3872 			} else
       
  3873 				w.execScript(co); // IE
       
  3874 		},
       
  3875 
       
  3876 		loadScripts : function(sc, cb, s) {
       
  3877 			var t = this, lo = t.lookup;
       
  3878 
       
  3879 			function done(o) {
       
  3880 				o.state = 2; // Has been loaded
       
  3881 
       
  3882 				// Run callback
       
  3883 				if (o.func)
       
  3884 					o.func.call(o.scope || t);
       
  3885 			};
       
  3886 
       
  3887 			function allDone() {
       
  3888 				var l;
       
  3889 
       
  3890 				// Check if all files are loaded
       
  3891 				l = sc.length;
       
  3892 				each(sc, function(o) {
       
  3893 					o = lo[o.url];
       
  3894 
       
  3895 					if (o.state === 2) {// It has finished loading
       
  3896 						done(o);
       
  3897 						l--;
       
  3898 					} else
       
  3899 						load(o);
       
  3900 				});
       
  3901 
       
  3902 				// They are all loaded
       
  3903 				if (l === 0 && cb) {
       
  3904 					cb.call(s || t);
       
  3905 					cb = 0;
       
  3906 				}
       
  3907 			};
       
  3908 
       
  3909 			function load(o) {
       
  3910 				if (o.state > 0)
       
  3911 					return;
       
  3912 
       
  3913 				o.state = 1; // Is loading
       
  3914 
       
  3915 				tinymce.util.XHR.send({
       
  3916 					url : o.url,
       
  3917 					error : t.settings.error,
       
  3918 					success : function(co) {
       
  3919 						t.eval(co);
       
  3920 						done(o);
       
  3921 						allDone();
       
  3922 					}
       
  3923 				});
       
  3924 			};
       
  3925 
       
  3926 			each(sc, function(o) {
       
  3927 				var u = o.url;
       
  3928 
       
  3929 				// Add to queue if needed
       
  3930 				if (!lo[u]) {
       
  3931 					lo[u] = o;
       
  3932 					t.queue.push(o);
       
  3933 				} else
       
  3934 					o = lo[u];
       
  3935 
       
  3936 				// Is already loading or has been loaded
       
  3937 				if (o.state > 0)
       
  3938 					return;
       
  3939 
       
  3940 				if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) {
       
  3941 					var ix, ol = '';
       
  3942 
       
  3943 					// Add onload events
       
  3944 					if (cb || o.func) {
       
  3945 						o.state = 1; // Is loading
       
  3946 
       
  3947 						ix = tinymce.dom.ScriptLoader._addOnLoad(function() {
       
  3948 							done(o);
       
  3949 							allDone();
       
  3950 						});
       
  3951 
       
  3952 						if (tinymce.isIE)
       
  3953 							ol = ' onreadystatechange="';
       
  3954 						else
       
  3955 							ol = ' onload="';
       
  3956 
       
  3957 						ol += 'tinymce.dom.ScriptLoader._onLoad(this,\'' + u + '\',' + ix + ');"';
       
  3958 					}
       
  3959 
       
  3960 					document.write('<script type="text/javascript" src="' + u + '"' + ol + '></script>');
       
  3961 
       
  3962 					if (!o.func)
       
  3963 						done(o);
       
  3964 				} else
       
  3965 					load(o);
       
  3966 			});
       
  3967 
       
  3968 			allDone();
       
  3969 		},
       
  3970 
       
  3971 		// Static methods
       
  3972 		'static' : {
       
  3973 			_addOnLoad : function(f) {
       
  3974 				var t = this;
       
  3975 
       
  3976 				t._funcs = t._funcs || [];
       
  3977 				t._funcs.push(f);
       
  3978 
       
  3979 				return t._funcs.length - 1;
       
  3980 			},
       
  3981 
       
  3982 			_onLoad : function(e, u, ix) {
       
  3983 				if (!tinymce.isIE || e.readyState == 'complete')
       
  3984 					this._funcs[ix].call(this);
       
  3985 			}
       
  3986 		}
       
  3987 
       
  3988 		});
       
  3989 
       
  3990 	// Global script loader
       
  3991 	tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
       
  3992 })();
       
  3993 
       
  3994 /* file:jscripts/tiny_mce/classes/ui/Control.js */
       
  3995 
       
  3996 (function() {
       
  3997 	// Shorten class names
       
  3998 	var DOM = tinymce.DOM, is = tinymce.is;
       
  3999 
       
  4000 	tinymce.create('tinymce.ui.Control', {
       
  4001 		Control : function(id, s) {
       
  4002 			this.id = id;
       
  4003 			this.settings = s = s || {};
       
  4004 			this.rendered = false;
       
  4005 			this.onRender = new tinymce.util.Dispatcher(this);
       
  4006 			this.classPrefix = '';
       
  4007 			this.scope = s.scope || this;
       
  4008 			this.disabled = 0;
       
  4009 			this.active = 0;
       
  4010 		},
       
  4011 
       
  4012 		setDisabled : function(s) {
       
  4013 			var e;
       
  4014 
       
  4015 			if (s != this.disabled) {
       
  4016 				e = DOM.get(this.id);
       
  4017 
       
  4018 				// Add accessibility title for unavailable actions
       
  4019 				if (e && this.settings.unavailable_prefix) {
       
  4020 					if (s) {
       
  4021 						this.prevTitle = e.title;
       
  4022 						e.title = this.settings.unavailable_prefix + ": " + e.title;
       
  4023 					} else
       
  4024 						e.title = this.prevTitle;
       
  4025 				}
       
  4026 
       
  4027 				this.setState('Disabled', s);
       
  4028 				this.setState('Enabled', !s);
       
  4029 				this.disabled = s;
       
  4030 			}
       
  4031 		},
       
  4032 
       
  4033 		isDisabled : function() {
       
  4034 			return this.disabled;
       
  4035 		},
       
  4036 
       
  4037 		setActive : function(s) {
       
  4038 			if (s != this.active) {
       
  4039 				this.setState('Active', s);
       
  4040 				this.active = s;
       
  4041 			}
       
  4042 		},
       
  4043 
       
  4044 		isActive : function() {
       
  4045 			return this.active;
       
  4046 		},
       
  4047 
       
  4048 		setState : function(c, s) {
       
  4049 			var n = DOM.get(this.id);
       
  4050 
       
  4051 			c = this.classPrefix + c;
       
  4052 
       
  4053 			if (s)
       
  4054 				DOM.addClass(n, c);
       
  4055 			else
       
  4056 				DOM.removeClass(n, c);
       
  4057 		},
       
  4058 
       
  4059 		isRendered : function() {
       
  4060 			return this.rendered;
       
  4061 		},
       
  4062 
       
  4063 		renderHTML : function() {
       
  4064 		},
       
  4065 
       
  4066 		renderTo : function(n) {
       
  4067 			n.innerHTML = this.renderHTML();
       
  4068 		},
       
  4069 
       
  4070 		postRender : function() {
       
  4071 			var t = this, b;
       
  4072 
       
  4073 			// Set pending states
       
  4074 			if (is(t.disabled)) {
       
  4075 				b = t.disabled;
       
  4076 				t.disabled = -1;
       
  4077 				t.setDisabled(b);
       
  4078 			}
       
  4079 
       
  4080 			if (is(t.active)) {
       
  4081 				b = t.active;
       
  4082 				t.active = -1;
       
  4083 				t.setActive(b);
       
  4084 			}
       
  4085 		},
       
  4086 
       
  4087 		destroy : function() {
       
  4088 			DOM.remove(this.id);
       
  4089 		}
       
  4090 
       
  4091 		});
       
  4092 })();
       
  4093 /* file:jscripts/tiny_mce/classes/ui/Container.js */
       
  4094 
       
  4095 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
       
  4096 	Container : function(id, s) {
       
  4097 		this.parent(id, s);
       
  4098 		this.controls = [];
       
  4099 		this.lookup = {};
  6401 	},
  4100 	},
  6402 
  4101 
  6403 	moveToBookmark : function(bookmark) {
  4102 	add : function(c) {
  6404 		var inst = this.instance;
  4103 		this.lookup[c.id] = c;
  6405 		var rng, nl, i, ex, b = inst.getBody(), sd;
  4104 		this.controls.push(c);
  6406 		var doc = inst.getDoc();
  4105 
  6407 		var win = inst.getWin();
  4106 		return c;
  6408 		var sel = this.getSel();
  4107 	},
  6409 
  4108 
  6410 		if (!bookmark)
  4109 	get : function(n) {
       
  4110 		return this.lookup[n];
       
  4111 	}
       
  4112 
       
  4113 	});
       
  4114 
       
  4115 
       
  4116 /* file:jscripts/tiny_mce/classes/ui/Separator.js */
       
  4117 
       
  4118 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
       
  4119 	renderHTML : function() {
       
  4120 		return tinymce.DOM.createHTML('span', {'class' : 'mceSeparator'});
       
  4121 	}
       
  4122 
       
  4123 	});
       
  4124 
       
  4125 /* file:jscripts/tiny_mce/classes/ui/MenuItem.js */
       
  4126 
       
  4127 (function() {
       
  4128 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
       
  4129 
       
  4130 	tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {
       
  4131 		MenuItem : function(id, s) {
       
  4132 			this.parent(id, s);
       
  4133 			this.classPrefix = 'mceMenuItem';
       
  4134 		},
       
  4135 
       
  4136 		setSelected : function(s) {
       
  4137 			this.setState('Selected', s);
       
  4138 			this.selected = s;
       
  4139 		},
       
  4140 
       
  4141 		isSelected : function() {
       
  4142 			return this.selected;
       
  4143 		},
       
  4144 
       
  4145 		postRender : function() {
       
  4146 			var t = this;
       
  4147 			
       
  4148 			t.parent();
       
  4149 
       
  4150 			// Set pending state
       
  4151 			if (is(t.selected))
       
  4152 				t.setSelected(t.selected);
       
  4153 		}
       
  4154 
       
  4155 		});
       
  4156 })();
       
  4157 
       
  4158 /* file:jscripts/tiny_mce/classes/ui/Menu.js */
       
  4159 
       
  4160 (function() {
       
  4161 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
       
  4162 
       
  4163 	tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {
       
  4164 		Menu : function(id, s) {
       
  4165 			var t = this;
       
  4166 
       
  4167 			t.parent(id, s);
       
  4168 			t.items = {};
       
  4169 			t.collapsed = false;
       
  4170 			t.menuCount = 0;
       
  4171 			t.onAddItem = new tinymce.util.Dispatcher(this);
       
  4172 		},
       
  4173 
       
  4174 		expand : function(d) {
       
  4175 			var t = this;
       
  4176 
       
  4177 			if (d) {
       
  4178 				walk(t, function(o) {
       
  4179 					if (o.expand)
       
  4180 						o.expand();
       
  4181 				}, 'items', t);
       
  4182 			}
       
  4183 
       
  4184 			t.collapsed = false;
       
  4185 		},
       
  4186 
       
  4187 		collapse : function(d) {
       
  4188 			var t = this;
       
  4189 
       
  4190 			if (d) {
       
  4191 				walk(t, function(o) {
       
  4192 					if (o.collapse)
       
  4193 						o.collapse();
       
  4194 				}, 'items', t);
       
  4195 			}
       
  4196 
       
  4197 			t.collapsed = true;
       
  4198 		},
       
  4199 
       
  4200 		isCollapsed : function() {
       
  4201 			return this.collapsed;
       
  4202 		},
       
  4203 
       
  4204 		add : function(o) {
       
  4205 			if (!o.settings)
       
  4206 				o = new tinymce.ui.MenuItem(o.id || DOM.uniqueId(), o);
       
  4207 
       
  4208 			this.onAddItem.dispatch(this, o);
       
  4209 
       
  4210 			return this.items[o.id] = o;
       
  4211 		},
       
  4212 
       
  4213 		addSeparator : function() {
       
  4214 			return this.add({separator : true});
       
  4215 		},
       
  4216 
       
  4217 		addMenu : function(o) {
       
  4218 			if (!o.collapse)
       
  4219 				o = this.createMenu(o);
       
  4220 
       
  4221 			this.menuCount++;
       
  4222 
       
  4223 			return this.add(o);
       
  4224 		},
       
  4225 
       
  4226 		hasMenus : function() {
       
  4227 			return this.menuCount !== 0;
       
  4228 		},
       
  4229 
       
  4230 		remove : function(o) {
       
  4231 			delete this.items[o.id];
       
  4232 		},
       
  4233 
       
  4234 		removeAll : function() {
       
  4235 			var t = this;
       
  4236 
       
  4237 			walk(t, function(o) {
       
  4238 				if (o.removeAll)
       
  4239 					o.removeAll();
       
  4240 
       
  4241 				o.destroy();
       
  4242 			}, 'items', t);
       
  4243 
       
  4244 			t.items = {};
       
  4245 		},
       
  4246 
       
  4247 		createMenu : function(o) {
       
  4248 			var m = new tinymce.ui.Menu(o.id || DOM.uniqueId(), o);
       
  4249 
       
  4250 			m.onAddItem.add(this.onAddItem.dispatch, this.onAddItem);
       
  4251 
       
  4252 			return m;
       
  4253 		}
       
  4254 
       
  4255 		});
       
  4256 })();
       
  4257 /* file:jscripts/tiny_mce/classes/ui/DropMenu.js */
       
  4258 
       
  4259 (function() {
       
  4260 	var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;
       
  4261 
       
  4262 	tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {
       
  4263 		DropMenu : function(id, s) {
       
  4264 			s = s || {};
       
  4265 			s.container = s.container || document.body;
       
  4266 			s.offset_x = s.offset_x || 0;
       
  4267 			s.offset_y = s.offset_y || 0;
       
  4268 			s.vp_offset_x = s.vp_offset_x || 0;
       
  4269 			s.vp_offset_y = s.vp_offset_y || 0;
       
  4270 			this.parent(id, s);
       
  4271 			this.onHideMenu = new tinymce.util.Dispatcher(this);
       
  4272 			this.classPrefix = 'mceMenu';
       
  4273 		},
       
  4274 
       
  4275 		createMenu : function(s) {
       
  4276 			var t = this, cs = t.settings, m;
       
  4277 
       
  4278 			s.container = s.container || cs.container;
       
  4279 			s.parent = t;
       
  4280 			s.constrain = s.constrain || cs.constrain;
       
  4281 			s['class'] = s['class'] || cs['class'];
       
  4282 			s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x;
       
  4283 			s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y;
       
  4284 			m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s);
       
  4285 
       
  4286 			m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem);
       
  4287 
       
  4288 			return m;
       
  4289 		},
       
  4290 
       
  4291 		update : function() {
       
  4292 			var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;
       
  4293 
       
  4294 			tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth;
       
  4295 			th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight;
       
  4296 
       
  4297 			if (!DOM.boxModel)
       
  4298 				t.element.setStyles({width : tw + 2, height : th + 2});
       
  4299 			else
       
  4300 				t.element.setStyles({width : tw, height : th});
       
  4301 
       
  4302 			if (s.max_width)
       
  4303 				DOM.setStyle(co, 'width', tw);
       
  4304 
       
  4305 			if (s.max_height) {
       
  4306 				DOM.setStyle(co, 'height', th);
       
  4307 
       
  4308 				if (tb.clientHeight < s.max_height)
       
  4309 					DOM.setStyle(co, 'overflow', 'hidden');
       
  4310 			}
       
  4311 		},
       
  4312 
       
  4313 		showMenu : function(x, y, px) {
       
  4314 			var t = this, s = t.settings, co, vp = DOM.getViewPort(), w, h, mx, my, ot = 2, dm, tb;
       
  4315 
       
  4316 			t.collapse(1);
       
  4317 
       
  4318 			if (t.isMenuVisible)
       
  4319 				return;
       
  4320 
       
  4321 			if (!t.rendered) {
       
  4322 				co = DOM.add(t.settings.container, t.renderNode());
       
  4323 
       
  4324 				each(t.items, function(o) {
       
  4325 					o.postRender();
       
  4326 				});
       
  4327 
       
  4328 				t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});
       
  4329 			} else
       
  4330 				co = DOM.get('menu_' + t.id);
       
  4331 
       
  4332 			DOM.setStyles(co, {left : -0xFFFF , top : -0xFFFF});
       
  4333 			DOM.show(co);
       
  4334 			t.update();
       
  4335 
       
  4336 			x += s.offset_x || 0;
       
  4337 			y += s.offset_y || 0;
       
  4338 			vp.w -= 4;
       
  4339 			vp.h -= 4;
       
  4340 
       
  4341 			// Move inside viewport if not submenu
       
  4342 			if (s.constrain) {
       
  4343 				w = co.clientWidth - ot;
       
  4344 				h = co.clientHeight - ot;
       
  4345 				mx = vp.x + vp.w;
       
  4346 				my = vp.y + vp.h;
       
  4347 
       
  4348 				if ((x + s.vp_offset_x + w) > mx)
       
  4349 					x = px ? px - w : Math.max(0, (mx - s.vp_offset_x) - w);
       
  4350 
       
  4351 				if ((y + s.vp_offset_y + h) > my)
       
  4352 					y = Math.max(0, (my - s.vp_offset_y) - h);
       
  4353 			}
       
  4354 
       
  4355 			DOM.setStyles(co, {left : x , top : y});
       
  4356 			t.element.update();
       
  4357 
       
  4358 			t.isMenuVisible = 1;
       
  4359 			t.mouseClickFunc = Event.add(co, 'click', function(e) {
       
  4360 				var m;
       
  4361 
       
  4362 				e = e.target;
       
  4363 
       
  4364 				if (e && (e = DOM.getParent(e, 'TR'))) {
       
  4365 					m = t.items[e.id];
       
  4366 
       
  4367 					if (m.isDisabled())
       
  4368 						return;
       
  4369 
       
  4370 					if (m.settings.onclick)
       
  4371 						m.settings.onclick(e);
       
  4372 
       
  4373 					dm = t;
       
  4374 
       
  4375 					while (dm) {
       
  4376 						if (dm.hideMenu)
       
  4377 							dm.hideMenu();
       
  4378 
       
  4379 						dm = dm.settings.parent;
       
  4380 					}
       
  4381 
       
  4382 					return Event.cancel(e); // Cancel to fix onbeforeunload problem
       
  4383 				}
       
  4384 			});
       
  4385 
       
  4386 			if (t.hasMenus()) {
       
  4387 				t.mouseOverFunc = Event.add(co, 'mouseover', function(e) {
       
  4388 					var m, r, mi;
       
  4389 
       
  4390 					e = e.target;
       
  4391 					if (e && (e = DOM.getParent(e, 'TR'))) {
       
  4392 						m = t.items[e.id];
       
  4393 
       
  4394 						if (t.lastMenu)
       
  4395 							t.lastMenu.collapse(1);
       
  4396 
       
  4397 						if (m.isDisabled())
       
  4398 							return;
       
  4399 
       
  4400 						if (e && DOM.hasClass(e, 'mceMenuItemSub')) {
       
  4401 							//p = DOM.getPos(s.container);
       
  4402 							r = DOM.getRect(e);
       
  4403 							m.showMenu((r.x + r.w - ot), r.y - ot, r.x);
       
  4404 							t.lastMenu = m;
       
  4405 							DOM.addClass(DOM.get(m.id).firstChild, 'mceMenuItemActive');
       
  4406 						}
       
  4407 					}
       
  4408 				});
       
  4409 			}
       
  4410 		},
       
  4411 
       
  4412 		hideMenu : function() {
       
  4413 			var t = this, co = DOM.get('menu_' + t.id), e;
       
  4414 
       
  4415 			if (!t.isMenuVisible)
       
  4416 				return;
       
  4417 
       
  4418 			Event.remove(co, 'mouseover', t.mouseOverFunc);
       
  4419 			Event.remove(co, 'click', t.mouseClickFunc);
       
  4420 			DOM.hide(co);
       
  4421 			t.isMenuVisible = 0;
       
  4422 
       
  4423 			if (t.element)
       
  4424 				t.element.hide();
       
  4425 
       
  4426 			if (e = DOM.get(t.id))
       
  4427 				DOM.removeClass(e.firstChild, 'mceMenuItemActive');
       
  4428 
       
  4429 			t.onHideMenu.dispatch(t);
       
  4430 		},
       
  4431 
       
  4432 		add : function(o) {
       
  4433 			var t = this, co;
       
  4434 
       
  4435 			o = t.parent(o);
       
  4436 
       
  4437 			if (t.isRendered && (co = DOM.get('menu_' + t.id)))
       
  4438 				t._add(DOM.select('tbody', co)[0], o);
       
  4439 
       
  4440 			return o;
       
  4441 		},
       
  4442 
       
  4443 		collapse : function(d) {
       
  4444 			this.parent(d);
       
  4445 			this.hideMenu();
       
  4446 		},
       
  4447 
       
  4448 		remove : function(o) {
       
  4449 			DOM.remove(o.id);
       
  4450 
       
  4451 			return this.parent(o);
       
  4452 		},
       
  4453 
       
  4454 		destroy : function() {
       
  4455 			var t = this, co = DOM.get('menu_' + t.id);
       
  4456 
       
  4457 			Event.remove(co, 'mouseover', t.mouseOverFunc);
       
  4458 			Event.remove(co, 'click', t.mouseClickFunc);
       
  4459 
       
  4460 			if (t.element)
       
  4461 				t.element.remove();
       
  4462 
       
  4463 			DOM.remove(co);
       
  4464 		},
       
  4465 
       
  4466 		renderNode : function() {
       
  4467 			var t = this, s = t.settings, n, tb, co, w;
       
  4468 
       
  4469 			w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:150'});
       
  4470 			co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenu' + (s['class'] ? ' ' + s['class'] : '')});
       
  4471 			t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});
       
  4472 
       
  4473 			if (s.menu_line)
       
  4474 				DOM.add(co, 'span', {'class' : 'mceMenuLine'});
       
  4475 
       
  4476 //			n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'});
       
  4477 			n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0});
       
  4478 			tb = DOM.add(n, 'tbody');
       
  4479 
       
  4480 			each(t.items, function(o) {
       
  4481 				t._add(tb, o);
       
  4482 			});
       
  4483 
       
  4484 			t.rendered = true;
       
  4485 
       
  4486 			return w;
       
  4487 		},
       
  4488 
       
  4489 		// Internal functions
       
  4490 
       
  4491 		_add : function(tb, o) {
       
  4492 			var n, s = o.settings, a, ro, it;
       
  4493 
       
  4494 			if (s.separator) {
       
  4495 				ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItemSeparator'});
       
  4496 				DOM.add(ro, 'td', {'class' : 'mceMenuItemSeparator'});
       
  4497 
       
  4498 				if (n = ro.previousSibling)
       
  4499 					DOM.addClass(n, 'last');
       
  4500 
       
  4501 				return;
       
  4502 			}
       
  4503 
       
  4504 			n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItem mceMenuItemEnabled'});
       
  4505 			n = it = DOM.add(n, 'td');
       
  4506 			n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});
       
  4507 
       
  4508 			DOM.addClass(it, s['class']);
       
  4509 //			n = DOM.add(n, 'span', {'class' : 'item'});
       
  4510 			DOM.add(n, 'span', {'class' : 'icon' + (s.icon ? ' ' + s.icon : '')});
       
  4511 			n = DOM.add(n, s.element || 'span', {'class' : 'text', title : o.settings.title}, o.settings.title);
       
  4512 
       
  4513 			if (o.settings.style)
       
  4514 				DOM.setAttrib(n, 'style', o.settings.style);
       
  4515 
       
  4516 			if (tb.childNodes.length == 1)
       
  4517 				DOM.addClass(ro, 'first');
       
  4518 
       
  4519 			if ((n = ro.previousSibling) && DOM.hasClass(n, 'mceMenuItemSeparator'))
       
  4520 				DOM.addClass(ro, 'first');
       
  4521 
       
  4522 			if (o.collapse)
       
  4523 				DOM.addClass(ro, 'mceMenuItemSub');
       
  4524 
       
  4525 			if (n = ro.previousSibling)
       
  4526 				DOM.removeClass(n, 'last');
       
  4527 
       
  4528 			DOM.addClass(ro, 'last');
       
  4529 		}
       
  4530 
       
  4531 		});
       
  4532 })();
       
  4533 /* file:jscripts/tiny_mce/classes/ui/Button.js */
       
  4534 
       
  4535 (function() {
       
  4536 	var DOM = tinymce.DOM;
       
  4537 
       
  4538 	tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {
       
  4539 		Button : function(id, s) {
       
  4540 			this.parent(id, s);
       
  4541 			this.classPrefix = 'mceButton';
       
  4542 		},
       
  4543 
       
  4544 		renderHTML : function() {
       
  4545 			var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class'] + '" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">';
       
  4546 
       
  4547 			if (s.image)
       
  4548 				h += '<img class="icon" src="' + s.image + '" /></a>';
       
  4549 			else
       
  4550 				h += '<span class="icon ' + s['class'] + '"></span></a>';
       
  4551 
       
  4552 			return h;
       
  4553 		},
       
  4554 
       
  4555 		postRender : function() {
       
  4556 			var t = this, s = t.settings;
       
  4557 
       
  4558 			tinymce.dom.Event.add(t.id, 'click', function(e) {
       
  4559 				if (!t.isDisabled())
       
  4560 					return s.onclick.call(s.scope, e);
       
  4561 			});
       
  4562 		}
       
  4563 
       
  4564 		});
       
  4565 })();
       
  4566 
       
  4567 /* file:jscripts/tiny_mce/classes/ui/ListBox.js */
       
  4568 
       
  4569 (function() {
       
  4570 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
       
  4571 
       
  4572 	tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {
       
  4573 		ListBox : function(id, s) {
       
  4574 			var t = this;
       
  4575 
       
  4576 			t.parent(id, s);
       
  4577 			t.items = [];
       
  4578 			t.onChange = new Dispatcher(t);
       
  4579 			t.onPostRender = new Dispatcher(t);
       
  4580 			t.onAdd = new Dispatcher(t);
       
  4581 			t.onRenderMenu = new tinymce.util.Dispatcher(this);
       
  4582 			t.classPrefix = 'mceListBox';
       
  4583 		},
       
  4584 
       
  4585 		select : function(v) {
       
  4586 			var t = this, e, fv;
       
  4587 
       
  4588 			// Do we need to do something?
       
  4589 			if (v != t.selectedValue) {
       
  4590 				e = DOM.get(t.id + '_text');
       
  4591 				t.selectedValue = v;
       
  4592 
       
  4593 				// Find item
       
  4594 				each(t.items, function(o) {
       
  4595 					if (o.value == v) {
       
  4596 						DOM.setHTML(e, DOM.encode(o.title));
       
  4597 						fv = 1;
       
  4598 						return false;
       
  4599 					}
       
  4600 				});
       
  4601 
       
  4602 				// If no item was found then present title
       
  4603 				if (!fv) {
       
  4604 					DOM.setHTML(e, DOM.encode(t.settings.title));
       
  4605 					DOM.addClass(e, 'title');
       
  4606 					e = 0;
       
  4607 					return;
       
  4608 				} else
       
  4609 					DOM.removeClass(e, 'title');
       
  4610 			}
       
  4611 
       
  4612 			e = 0;
       
  4613 		},
       
  4614 
       
  4615 		add : function(n, v, o) {
       
  4616 			var t = this;
       
  4617 
       
  4618 			o = o || {};
       
  4619 			o = tinymce.extend(o, {
       
  4620 				title : n,
       
  4621 				value : v
       
  4622 			});
       
  4623 
       
  4624 			t.items.push(o);
       
  4625 			t.onAdd.dispatch(t, o);
       
  4626 		},
       
  4627 
       
  4628 		getLength : function() {
       
  4629 			return this.items.length;
       
  4630 		},
       
  4631 
       
  4632 		renderHTML : function() {
       
  4633 			var h = '', t = this, s = t.settings;
       
  4634 
       
  4635 			h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';
       
  4636 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'text', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>';
       
  4637 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>';
       
  4638 			h += '</tr></tbody></table>';
       
  4639 
       
  4640 			return h;
       
  4641 		},
       
  4642 
       
  4643 		showMenu : function() {
       
  4644 			var t = this, p1, p2, e = DOM.get(this.id), m;
       
  4645 
       
  4646 			if (t.isDisabled() || t.items.length == 0)
       
  4647 				return;
       
  4648 
       
  4649 			if (!t.isMenuRendered) {
       
  4650 				t.renderMenu();
       
  4651 				t.isMenuRendered = true;
       
  4652 			}
       
  4653 
       
  4654 			p1 = DOM.getPos(this.settings.menu_container);
       
  4655 			p2 = DOM.getPos(e);
       
  4656 
       
  4657 			m = t.menu;
       
  4658 			m.settings.offset_x = p2.x;
       
  4659 			m.settings.offset_y = p2.y;
       
  4660 
       
  4661 			// Select in menu
       
  4662 			if (t.oldID)
       
  4663 				m.items[t.oldID].setSelected(0);
       
  4664 
       
  4665 			each(t.items, function(o) {
       
  4666 				if (o.value === t.selectedValue) {
       
  4667 					m.items[o.id].setSelected(1);
       
  4668 					t.oldID = o.id;
       
  4669 				}
       
  4670 			});
       
  4671 
       
  4672 			m.showMenu(0, e.clientHeight);
       
  4673 
       
  4674 			Event.add(document, 'mousedown', t.hideMenu, t);
       
  4675 			DOM.addClass(t.id, 'mceListBoxSelected');
       
  4676 		},
       
  4677 
       
  4678 		hideMenu : function(e) {
       
  4679 			var t = this;
       
  4680 
       
  4681 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
       
  4682 				DOM.removeClass(t.id, 'mceListBoxSelected');
       
  4683 				Event.remove(document, 'mousedown', t.hideMenu, t);
       
  4684 
       
  4685 				if (t.menu)
       
  4686 					t.menu.hideMenu();
       
  4687 			}
       
  4688 		},
       
  4689 
       
  4690 		renderMenu : function() {
       
  4691 			var t = this, m;
       
  4692 
       
  4693 			m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
       
  4694 				menu_line : 1,
       
  4695 				'class' : 'mceListBoxMenu noIcons',
       
  4696 				max_width : 150,
       
  4697 				max_height : 150
       
  4698 			});
       
  4699 
       
  4700 			m.onHideMenu.add(t.hideMenu, t);
       
  4701 
       
  4702 			m.add({
       
  4703 				title : t.settings.title,
       
  4704 				'class' : 'mceMenuItemTitle'
       
  4705 			}).setDisabled(1);
       
  4706 
       
  4707 			each(t.items, function(o) {
       
  4708 				o.id = DOM.uniqueId();
       
  4709 				o.onclick = function() {
       
  4710 					if (t.settings.onselect(o.value) !== false)
       
  4711 						t.select(o.value); // Must be runned after
       
  4712 				};
       
  4713 
       
  4714 				m.add(o);
       
  4715 			});
       
  4716 
       
  4717 			t.onRenderMenu.dispatch(t, m);
       
  4718 			t.menu = m;
       
  4719 		},
       
  4720 
       
  4721 		postRender : function() {
       
  4722 			var t = this;
       
  4723 
       
  4724 			Event.add(t.id, 'click', t.showMenu, t);
       
  4725 
       
  4726 			// Old IE doesn't have hover on all elements
       
  4727 			if (tinymce.isIE6 || !DOM.boxModel) {
       
  4728 				Event.add(t.id, 'mouseover', function() {
       
  4729 					if (!DOM.hasClass(t.id, 'mceListBoxDisabled'))
       
  4730 						DOM.addClass(t.id, 'mceListBoxHover');
       
  4731 				});
       
  4732 
       
  4733 				Event.add(t.id, 'mouseout', function() {
       
  4734 					if (!DOM.hasClass(t.id, 'mceListBoxDisabled'))
       
  4735 						DOM.removeClass(t.id, 'mceListBoxHover');
       
  4736 				});
       
  4737 			}
       
  4738 
       
  4739 			t.onPostRender.dispatch(t, DOM.get(t.id));
       
  4740 		}
       
  4741 
       
  4742 		});
       
  4743 })();
       
  4744 /* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */
       
  4745 
       
  4746 (function() {
       
  4747 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
       
  4748 
       
  4749 	tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {
       
  4750 		NativeListBox : function(id, s) {
       
  4751 			this.parent(id, s);
       
  4752 			this.classPrefix = 'mceNativeListBox';
       
  4753 		},
       
  4754 
       
  4755 		setDisabled : function(s) {
       
  4756 			DOM.get(this.id).disabled = s;
       
  4757 		},
       
  4758 
       
  4759 		isDisabled : function() {
       
  4760 			return DOM.get(this.id).disabled;
       
  4761 		},
       
  4762 
       
  4763 		select : function(v) {
       
  4764 			var e = DOM.get(this.id), ol = e.options;
       
  4765 
       
  4766 			v = '' + (v || '');
       
  4767 
       
  4768 			e.selectedIndex = 0;
       
  4769 			each(ol, function(o, i) {
       
  4770 				if (o.value == v) {
       
  4771 					e.selectedIndex = i;
       
  4772 					return false;
       
  4773 				}
       
  4774 			});
       
  4775 		},
       
  4776 
       
  4777 		add : function(n, v, a) {
       
  4778 			var o, t = this;
       
  4779 
       
  4780 			a = a || {};
       
  4781 			a.value = v;
       
  4782 
       
  4783 			if (t.isRendered())
       
  4784 				DOM.add(DOM.get(this.id), 'option', a, n);
       
  4785 
       
  4786 			o = {
       
  4787 				title : n,
       
  4788 				value : v,
       
  4789 				attribs : a
       
  4790 			};
       
  4791 
       
  4792 			t.items.push(o);
       
  4793 			t.onAdd.dispatch(t, o);
       
  4794 		},
       
  4795 
       
  4796 		getLength : function() {
       
  4797 			return DOM.get(this.id).options.length - 1;
       
  4798 		},
       
  4799 
       
  4800 		renderHTML : function() {
       
  4801 			var h, t = this;
       
  4802 
       
  4803 			h = DOM.createHTML('option', {value : ''}, '-- ' + t.settings.title + ' --');
       
  4804 
       
  4805 			each(t.items, function(it) {
       
  4806 				h += DOM.createHTML('option', {value : it.value}, it.title);
       
  4807 			});
       
  4808 
       
  4809 			h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h);
       
  4810 
       
  4811 			return h;
       
  4812 		},
       
  4813 
       
  4814 		postRender : function() {
       
  4815 			var t = this, ch;
       
  4816 
       
  4817 			t.rendered = true;
       
  4818 
       
  4819 			function onChange(e) {
       
  4820 				var v = e.target.options[e.target.selectedIndex].value;
       
  4821 
       
  4822 				t.onChange.dispatch(t, v);
       
  4823 
       
  4824 				if (t.settings.onselect)
       
  4825 					t.settings.onselect(v);
       
  4826 			};
       
  4827 
       
  4828 			Event.add(t.id, 'change', onChange);
       
  4829 
       
  4830 			// Accessibility keyhandler
       
  4831 			Event.add(t.id, 'keydown', function(e) {
       
  4832 				var bf;
       
  4833 
       
  4834 				Event.remove(t.id, 'change', ch);
       
  4835 
       
  4836 				bf = Event.add(t.id, 'blur', function() {
       
  4837 					Event.add(t.id, 'change', onChange);
       
  4838 					Event.remove(t.id, 'blur', bf);
       
  4839 				});
       
  4840 
       
  4841 				if (e.keyCode == 13 || e.keyCode == 32) {
       
  4842 					onChange(e);
       
  4843 					return Event.cancel(e);
       
  4844 				}
       
  4845 			});
       
  4846 
       
  4847 			t.onPostRender.dispatch(t, DOM.get(t.id));
       
  4848 		}
       
  4849 
       
  4850 		});
       
  4851 })();
       
  4852 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */
       
  4853 
       
  4854 (function() {
       
  4855 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
       
  4856 
       
  4857 	tinymce.create('tinymce.ui.SplitButton:tinymce.ui.Button', {
       
  4858 		SplitButton : function(id, s) {
       
  4859 			this.parent(id, s);
       
  4860 			this.classPrefix = 'mceSplitButton';
       
  4861 			this.onRenderMenu = new tinymce.util.Dispatcher(this);
       
  4862 			s.menu_container = s.menu_container || document.body;
       
  4863 		},
       
  4864 
       
  4865 		showMenu : function() {
       
  4866 			var t = this, p1, p2, e = DOM.get(t.id), m;
       
  4867 
       
  4868 			if (t.isDisabled())
       
  4869 				return;
       
  4870 
       
  4871 			if (!t.isMenuRendered) {
       
  4872 				t.renderMenu();
       
  4873 				t.isMenuRendered = true;
       
  4874 			}
       
  4875 
       
  4876 			p1 = DOM.getPos(t.settings.menu_container);
       
  4877 			p2 = DOM.getPos(e);
       
  4878 
       
  4879 			m = t.menu;
       
  4880 			m.settings.offset_x = p2.x;
       
  4881 			m.settings.offset_y = p2.y;
       
  4882 			m.settings.vp_offset_x = p2.x;
       
  4883 			m.settings.vp_offset_y = p2.y;
       
  4884 			m.showMenu(0, e.clientHeight);
       
  4885 
       
  4886 			Event.add(document, 'mousedown', t.hideMenu, t);
       
  4887 			DOM.addClass(t.id, 'mceSplitButtonSelected');
       
  4888 		},
       
  4889 
       
  4890 		renderMenu : function() {
       
  4891 			var t = this, m;
       
  4892 
       
  4893 			m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
       
  4894 				menu_line : 1,
       
  4895 				'class' : 'mceSplitButtonMenu'
       
  4896 			});
       
  4897 
       
  4898 			m.onHideMenu.add(t.hideMenu, t);
       
  4899 
       
  4900 			t.onRenderMenu.dispatch(t, m);
       
  4901 			t.menu = m;
       
  4902 		},
       
  4903 
       
  4904 		hideMenu : function(e) {
       
  4905 			var t = this;
       
  4906 
       
  4907 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
       
  4908 				DOM.removeClass(t.id, 'mceSplitButtonSelected');
       
  4909 				Event.remove(document, 'mousedown', t.hideMenu, t);
       
  4910 				if (t.menu)
       
  4911 					t.menu.hideMenu();
       
  4912 			}
       
  4913 		},
       
  4914 
       
  4915 		renderHTML : function() {
       
  4916 			var h, t = this, s = t.settings, h1;
       
  4917 
       
  4918 			h = '<tbody><tr>';
       
  4919 
       
  4920 			if (s.image)
       
  4921 				h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'action ' + s['class']});
       
  4922 			else
       
  4923 				h1 = DOM.createHTML('span', {'class' : 'action ' + s['class']});
       
  4924 
       
  4925 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_action', href : 'javascript:;', 'class' : 'action ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';
       
  4926 	
       
  4927 			h1 = DOM.createHTML('span', {'class' : 'open ' + s['class']});
       
  4928 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';
       
  4929 
       
  4930 			h += '</tr></tbody>';
       
  4931 
       
  4932 			return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);
       
  4933 		},
       
  4934 
       
  4935 		postRender : function() {
       
  4936 			var t = this, s = t.settings;
       
  4937 
       
  4938 			if (s.onclick) {
       
  4939 				Event.add(t.id + '_action', 'click', function() {
       
  4940 					if (!t.isDisabled())
       
  4941 						s.onclick(t.value);
       
  4942 				});
       
  4943 			}
       
  4944 
       
  4945 			Event.add(t.id + '_open', 'click', t.showMenu, t);
       
  4946 
       
  4947 			// Old IE doesn't have hover on all elements
       
  4948 			if (tinymce.isIE6 || !DOM.boxModel) {
       
  4949 				Event.add(t.id, 'mouseover', function() {
       
  4950 					if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))
       
  4951 						DOM.addClass(t.id, 'mceSplitButtonHover');
       
  4952 				});
       
  4953 
       
  4954 				Event.add(t.id, 'mouseout', function() {
       
  4955 					if (!DOM.hasClass(t.id, 'mceSplitButtonDisabled'))
       
  4956 						DOM.removeClass(t.id, 'mceSplitButtonHover');
       
  4957 				});
       
  4958 			}
       
  4959 		}
       
  4960 
       
  4961 		});
       
  4962 })();
       
  4963 
       
  4964 /* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */
       
  4965 
       
  4966 (function() {
       
  4967 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
       
  4968 
       
  4969 	tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {
       
  4970 		ColorSplitButton : function(id, s) {
       
  4971 			var t = this;
       
  4972 
       
  4973 			t.parent(id, s);
       
  4974 
       
  4975 			t.settings = s = tinymce.extend({
       
  4976 				colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF',
       
  4977 				grid_width : 8,
       
  4978 				default_color : '#888888'
       
  4979 			}, t.settings);
       
  4980 
       
  4981 			t.value = s.default_color;
       
  4982 		},
       
  4983 
       
  4984 		showMenu : function() {
       
  4985 			var t = this, r, p, e;
       
  4986 
       
  4987 			if (t.isDisabled())
       
  4988 				return;
       
  4989 
       
  4990 			if (!t.isMenuRendered) {
       
  4991 				t.renderMenu();
       
  4992 				t.isMenuRendered = true;
       
  4993 			}
       
  4994 
       
  4995 			e = DOM.get(t.id);
       
  4996 			DOM.show(t.id + '_menu');
       
  4997 			DOM.addClass(e, 'mceSplitButtonSelected');
       
  4998 			p2 = DOM.getPos(e);
       
  4999 			DOM.setStyles(t.id + '_menu', {
       
  5000 				left : p2.x,
       
  5001 				top : p2.y + e.clientHeight,
       
  5002 				zIndex : 150
       
  5003 			});
       
  5004 			e = 0;
       
  5005 
       
  5006 			Event.add(document, 'mousedown', t.hideMenu, t);
       
  5007 		},
       
  5008 
       
  5009 		hideMenu : function(e) {
       
  5010 			var t = this;
       
  5011 
       
  5012 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {
       
  5013 				DOM.removeClass(t.id, 'mceSplitButtonSelected');
       
  5014 				Event.remove(document, 'mousedown', t.hideMenu, t);
       
  5015 				DOM.hide(t.id + '_menu');
       
  5016 			}
       
  5017 		},
       
  5018 
       
  5019 		renderMenu : function() {
       
  5020 			var t = this, m, i = 0, s = t.settings, n, tb, tr, w;
       
  5021 
       
  5022 			w = DOM.add(s.menu_container, 'div', {id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});
       
  5023 			m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});
       
  5024 			DOM.add(m, 'span', {'class' : 'mceMenuLine'});
       
  5025 
       
  5026 			n = DOM.add(m, 'table', {'class' : 'mceColorSplitMenu'});
       
  5027 			tb = DOM.add(n, 'tbody');
       
  5028 
       
  5029 			// Generate color grid
       
  5030 			i = 0;
       
  5031 			each(is(s.colors, 'array') ? s.colors : s.colors.split(','), function(c) {
       
  5032 				c = c.replace(/^#/, '');
       
  5033 
       
  5034 				if (!i--) {
       
  5035 					tr = DOM.add(tb, 'tr');
       
  5036 					i = s.grid_width - 1;
       
  5037 				}
       
  5038 
       
  5039 				n = DOM.add(tr, 'td');
       
  5040 
       
  5041 				n = DOM.add(n, 'a', {
       
  5042 					href : 'javascript:;',
       
  5043 					style : {
       
  5044 						backgroundColor : '#' + c
       
  5045 					}
       
  5046 				});
       
  5047 
       
  5048 				Event.add(n, 'mousedown', function() {
       
  5049 					t.setColor('#' + c);
       
  5050 				});
       
  5051 			});
       
  5052 
       
  5053 			if (s.more_colors_func) {
       
  5054 				n = DOM.add(tb, 'tr');
       
  5055 				n = DOM.add(n, 'td', {colSpan : s.grid_width, 'class' : 'morecolors'});
       
  5056 				n = DOM.add(n, 'a', {href : 'javascript:;', onclick : 'return false;', 'class' : 'morecolors'}, s.more_colors_title);
       
  5057 
       
  5058 				Event.add(n, 'click', function(e) {
       
  5059 					s.more_colors_func.call(s.more_colors_scope || this);
       
  5060 					return Event.cancel(e); // Cancel to fix onbeforeunload problem
       
  5061 				});
       
  5062 			}
       
  5063 
       
  5064 			DOM.addClass(m, 'mceColorSplitMenu');
       
  5065 
       
  5066 			return w;
       
  5067 		},
       
  5068 
       
  5069 		setColor : function(c) {
       
  5070 			var t = this, p, s = this.settings, co = s.menu_container, po, cp, id = t.id + '_preview';
       
  5071 
       
  5072 			if (!(p = DOM.get(id))) {
       
  5073 				DOM.setStyle(t.id + '_action', 'position', 'relative');
       
  5074 				p = DOM.add(t.id + '_action', 'div', {id : id, 'class' : 'mceColorPreview'});
       
  5075 			}
       
  5076 
       
  5077 			p.style.backgroundColor = c;
       
  5078 
       
  5079 			t.value = c;
       
  5080 			t.hideMenu();
       
  5081 			s.onselect(c);
       
  5082 		}
       
  5083 
       
  5084 		});
       
  5085 })();
       
  5086 
       
  5087 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */
       
  5088 
       
  5089 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
       
  5090 	renderHTML : function() {
       
  5091 		var h = '', c = 'mceToolbarEnd', co, dom = tinymce.DOM;
       
  5092 
       
  5093 		h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->'));
       
  5094 
       
  5095 		tinymce.each(this.controls, function(c) {
       
  5096 			h += '<td>' + c.renderHTML() + '</td>';
       
  5097 		});
       
  5098 
       
  5099 		co = this.controls[this.controls.length - 1].constructor;
       
  5100 
       
  5101 		if (co === tinymce.ui.Button)
       
  5102 			c += ' mceToolbarEndButton';
       
  5103 		else if (co === tinymce.ui.SplitButton)
       
  5104 			c += ' mceToolbarEndSplitButton';
       
  5105 		else if (co === tinymce.ui.ListBox)
       
  5106 			c += ' mceToolbarEndListBox';
       
  5107 
       
  5108 		h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));
       
  5109 
       
  5110 		return dom.createHTML('table', {'class' : 'mceToolbar', cellpadding : '0', cellspacing : '0', align : this.settings.align}, '<tbody><tr>' + h + '</tr></tbody>');
       
  5111 	}
       
  5112 
       
  5113 	});
       
  5114 
       
  5115 /* file:jscripts/tiny_mce/classes/AddOnManager.js */
       
  5116 
       
  5117 (function() {
       
  5118 	var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;
       
  5119 
       
  5120 	tinymce.create('tinymce.AddOnManager', {
       
  5121 		items : [],
       
  5122 		urls : {},
       
  5123 		lookup : {},
       
  5124 		onAdd : new Dispatcher(this),
       
  5125 
       
  5126 		get : function(n) {
       
  5127 			return this.lookup[n];
       
  5128 		},
       
  5129 
       
  5130 		requireLangPack : function(n) {
       
  5131 			var u, s;
       
  5132 
       
  5133 			if (tinymce.EditorManager.settings) {
       
  5134 				u = this.urls[n] + '/langs/' + tinymce.EditorManager.settings.language + '.js';
       
  5135 				s = tinymce.EditorManager.settings;
       
  5136 
       
  5137 				if (s) {
       
  5138 					if (!tinymce.dom.Event.domLoaded && !s.strict_mode)
       
  5139 						tinymce.ScriptLoader.load(u);
       
  5140 					else
       
  5141 						tinymce.ScriptLoader.add(u);
       
  5142 				}
       
  5143 			}
       
  5144 		},
       
  5145 
       
  5146 		add : function(id, o) {
       
  5147 			this.items.push(o);
       
  5148 			this.lookup[id] = o;
       
  5149 			this.onAdd.dispatch(this, id, o);
       
  5150 
       
  5151 			return o;
       
  5152 		},
       
  5153 
       
  5154 		load : function(n, u, cb, s) {
       
  5155 			if (u.indexOf('/') != 0 && u.indexOf('://') == -1)
       
  5156 				u = tinymce.baseURL + '/' +  u;
       
  5157 
       
  5158 			this.urls[n] = u.substring(0, u.lastIndexOf('/'));
       
  5159 			tinymce.ScriptLoader.add(u, cb, s);
       
  5160 		}
       
  5161 
       
  5162 		});
       
  5163 
       
  5164 	// Create plugin and theme managers
       
  5165 	tinymce.PluginManager = new tinymce.AddOnManager();
       
  5166 	tinymce.ThemeManager = new tinymce.AddOnManager();
       
  5167 }());
       
  5168 /* file:jscripts/tiny_mce/classes/EditorManager.js */
       
  5169 
       
  5170 (function() {
       
  5171 	// Shorten names
       
  5172 	var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager;
       
  5173 
       
  5174 	tinymce.create('static tinymce.EditorManager', {
       
  5175 		editors : {},
       
  5176 		i18n : {},
       
  5177 		activeEditor : null,
       
  5178 
       
  5179 		init : function(s) {
       
  5180 			var t = this, pl, sl = tinymce.ScriptLoader;
       
  5181 
       
  5182 			function execCallback(se, n, s) {
       
  5183 				var f = se[n];
       
  5184 
       
  5185 				if (!f)
       
  5186 					return;
       
  5187 
       
  5188 				if (tinymce.is(f, 'string')) {
       
  5189 					s = f.replace(/\.\w+$/, '');
       
  5190 					s = s ? tinymce.resolve(s) : 0;
       
  5191 					f = tinymce.resolve(f);
       
  5192 				}
       
  5193 
       
  5194 				return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
       
  5195 			};
       
  5196 
       
  5197 			s = extend({
       
  5198 				theme : "simple",
       
  5199 				language : "en"
       
  5200 			}, s);
       
  5201 
       
  5202 			t.settings = s;
       
  5203 
       
  5204 			// If page not loaded and strict mode isn't enabled then load them
       
  5205 			if (!Event.domLoaded && !s.strict_loading_mode) {
       
  5206 				// Load language
       
  5207 				if (s.language)
       
  5208 					sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');
       
  5209 
       
  5210 				// Load theme
       
  5211 				if (s.theme && s.theme.charAt(0) != '-')
       
  5212 					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
       
  5213 
       
  5214 				// Load plugins
       
  5215 				if (s.plugins) {
       
  5216 					pl = s.plugins.split(',');
       
  5217 
       
  5218 					// Load compat2x first
       
  5219 					if (tinymce.inArray(pl, 'compat2x') != -1)
       
  5220 						PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
       
  5221 
       
  5222 					// Load rest if plugins
       
  5223 					each(pl, function(v) {
       
  5224 						if (v && v.charAt(0) != '-') {
       
  5225 							// Skip safari plugin for other browsers
       
  5226 							if (!tinymce.isWebKit && v == 'safari')
       
  5227 								return;
       
  5228 
       
  5229 							PluginManager.load(v, 'plugins/' + v + '/editor_plugin' + tinymce.suffix + '.js');
       
  5230 						}
       
  5231 					});
       
  5232 				}
       
  5233 
       
  5234 				sl.loadQueue();
       
  5235 			}
       
  5236 
       
  5237 			// Legacy call
       
  5238 			Event.add(document, 'init', function() {
       
  5239 				var l, co;
       
  5240 
       
  5241 				execCallback(s, 'onpageload');
       
  5242 
       
  5243 				// Verify that it's a valid browser
       
  5244 				if (s.browsers) {
       
  5245 					l = false;
       
  5246 
       
  5247 					each(s.browsers.split(','), function(v) {
       
  5248 						switch (v) {
       
  5249 							case 'ie':
       
  5250 							case 'msie':
       
  5251 								if (tinymce.isIE)
       
  5252 									l = true;
       
  5253 								break;
       
  5254 
       
  5255 							case 'gecko':
       
  5256 								if (tinymce.isGecko)
       
  5257 									l = true;
       
  5258 								break;
       
  5259 
       
  5260 							case 'safari':
       
  5261 							case 'webkit':
       
  5262 								if (tinymce.isWebKit)
       
  5263 									l = true;
       
  5264 								break;
       
  5265 
       
  5266 							case 'opera':
       
  5267 								if (tinymce.isOpera)
       
  5268 									l = true;
       
  5269 
       
  5270 								break;
       
  5271 						}
       
  5272 					});
       
  5273 
       
  5274 					// Not a valid one
       
  5275 					if (!l)
       
  5276 						return;
       
  5277 				}
       
  5278 
       
  5279 				switch (s.mode) {
       
  5280 					case "exact":
       
  5281 						l = s.elements || '';
       
  5282 						each(l.split(','), function(v) {
       
  5283 							new tinymce.Editor(v, s).render();
       
  5284 						});
       
  5285 						break;
       
  5286 
       
  5287 					case "textareas":
       
  5288 						function hasClass(n, c) {
       
  5289 							return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
       
  5290 						};
       
  5291 
       
  5292 						each(DOM.select('textarea'), function(v) {
       
  5293 							if (s.editor_deselector && hasClass(v, s.editor_deselector))
       
  5294 								return;
       
  5295 
       
  5296 							if (!s.editor_selector || hasClass(v, s.editor_selector))
       
  5297 								new tinymce.Editor(v.id = (v.id || v.name || (v.id = DOM.uniqueId())), s).render();
       
  5298 						});
       
  5299 						break;
       
  5300 				}
       
  5301 
       
  5302 				// Call onInit when all editors are initialized
       
  5303 				if (s.oninit) {
       
  5304 					l = co = 0;
       
  5305 
       
  5306 					each (t.editors, function(ed) {
       
  5307 						co++;
       
  5308 
       
  5309 						if (!ed.initialized) {
       
  5310 							// Wait for it
       
  5311 							ed.onInit.add(function() {
       
  5312 								l++;
       
  5313 
       
  5314 								// All done
       
  5315 								if (l == co)
       
  5316 									execCallback(s, 'oninit');
       
  5317 							});
       
  5318 						} else
       
  5319 							l++;
       
  5320 
       
  5321 						// All done
       
  5322 						if (l == co)
       
  5323 							execCallback(s, 'oninit');					
       
  5324 					});
       
  5325 				}
       
  5326 			});
       
  5327 		},
       
  5328 
       
  5329 		get : function(id) {
       
  5330 			return this.editors[id];
       
  5331 		},
       
  5332 
       
  5333 		getInstanceById : function(id) {
       
  5334 			return this.get(id);
       
  5335 		},
       
  5336 
       
  5337 		add : function(e) {
       
  5338 			this.editors[e.id] = e;
       
  5339 			this._setActive(e);
       
  5340 
       
  5341 			return e;
       
  5342 		},
       
  5343 
       
  5344 		remove : function(e) {
       
  5345 			var t = this;
       
  5346 
       
  5347 			// Not in the collection
       
  5348 			if (!t.editors[e.id])
       
  5349 				return null;
       
  5350 
       
  5351 			delete t.editors[e.id];
       
  5352 
       
  5353 			// Select another editor since the active one was removed
       
  5354 			if (t.activeEditor == e) {
       
  5355 				each(t.editors, function(e) {
       
  5356 					t._setActive(e);
       
  5357 					return false; // Break
       
  5358 				});
       
  5359 			}
       
  5360 
       
  5361 			e._destroy();
       
  5362 
       
  5363 			return e;
       
  5364 		},
       
  5365 
       
  5366 		execCommand : function(c, u, v) {
       
  5367 			var t = this, ed = t.get(v);
       
  5368 
       
  5369 			// Manager commands
       
  5370 			switch (c) {
       
  5371 				case "mceFocus":
       
  5372 					ed.focus();
       
  5373 					return true;
       
  5374 
       
  5375 				case "mceAddEditor":
       
  5376 				case "mceAddControl":
       
  5377 					new tinymce.Editor(v, t.settings).render();
       
  5378 					return true;
       
  5379 
       
  5380 				case "mceAddFrameControl":
       
  5381 					// TODO: Implement this
       
  5382 					return true;
       
  5383 
       
  5384 				case "mceRemoveEditor":
       
  5385 				case "mceRemoveControl":
       
  5386 					ed.remove();
       
  5387 					return true;
       
  5388 
       
  5389 				case 'mceToggleEditor':
       
  5390 					if (!ed) {
       
  5391 						t.execCommand('mceAddControl', 0, v);
       
  5392 						return true;
       
  5393 					}
       
  5394 
       
  5395 					if (ed.isHidden())
       
  5396 						ed.show();
       
  5397 					else
       
  5398 						ed.hide();
       
  5399 
       
  5400 					return true;
       
  5401 			}
       
  5402 
       
  5403 			// Run command on active editor
       
  5404 			if (t.activeEditor)
       
  5405 				return t.activeEditor.execCommand(c, u, v);
       
  5406 
  6411 			return false;
  5407 			return false;
  6412 
  5408 		},
  6413 		if (tinyMCE.isSafari) {
  5409 
  6414 			sel.setBaseAndExtent(bookmark.rng.startContainer, bookmark.rng.startOffset, bookmark.rng.endContainer, bookmark.rng.endOffset);
  5410 		execInstanceCommand : function(id, c, u, v) {
       
  5411 			var ed = this.get(id);
       
  5412 
       
  5413 			if (ed)
       
  5414 				return ed.execCommand(c, u, v);
       
  5415 
       
  5416 			return false;
       
  5417 		},
       
  5418 
       
  5419 		triggerSave : function() {
       
  5420 			each(this.editors, function(e) {
       
  5421 				e.save();
       
  5422 			});
       
  5423 		},
       
  5424 
       
  5425 		addI18n : function(p, o) {
       
  5426 			var lo, i18n = this.i18n;
       
  5427 
       
  5428 			if (!tinymce.is(p, 'string')) {
       
  5429 				each(p, function(o, lc) {
       
  5430 					each(o, function(o, g) {
       
  5431 						each(o, function(o, k) {
       
  5432 							if (g === 'common')
       
  5433 								i18n[lc + '.' + k] = o;
       
  5434 							else
       
  5435 								i18n[lc + '.' + g + '.' + k] = o;
       
  5436 						});
       
  5437 					});
       
  5438 				});
       
  5439 			} else {
       
  5440 				each(o, function(o, k) {
       
  5441 					i18n[p + '.' + k] = o;
       
  5442 				});
       
  5443 			}
       
  5444 		},
       
  5445 
       
  5446 		// Private methods
       
  5447 
       
  5448 		_setActive : function(e) {
       
  5449 			this.selectedInstance = this.activeEditor = e;
       
  5450 		}
       
  5451 
       
  5452 		});
       
  5453 
       
  5454 	// Setup some URLs where the editor API is located and where the document is
       
  5455 	tinymce.documentBaseURL = document.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][\w.]+$/, '');
       
  5456 	if (!/[\/\\]$/.test(tinymce.documentBaseURL))
       
  5457 		tinymce.documentBaseURL += '/';
       
  5458 
       
  5459 	tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
       
  5460 	tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
       
  5461 })();
       
  5462 
       
  5463 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call
       
  5464 var tinyMCE = window.tinyMCE = tinymce.EditorManager;
       
  5465 
       
  5466 /* file:jscripts/tiny_mce/classes/Editor.js */
       
  5467 
       
  5468 (function() {
       
  5469 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;
       
  5470 	var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;
       
  5471 	var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;
       
  5472 	var inArray = tinymce.inArray, grep = tinymce.grep;
       
  5473 
       
  5474 	tinymce.create('tinymce.Editor', {
       
  5475 		Editor : function(id, s) {
       
  5476 			var t = this;
       
  5477 
       
  5478 			t.id = t.editorId = id;
       
  5479 			t.execCommands = {};
       
  5480 			t.queryStateCommands = {};
       
  5481 			t.queryValueCommands = {};
       
  5482 			t.plugins = {};
       
  5483 
       
  5484 			// Add events to the editor
       
  5485 			each([
       
  5486 				'onPreInit',
       
  5487 				'onBeforeRenderUI',
       
  5488 				'onPostRender',
       
  5489 				'onInit',
       
  5490 				'onRemove',
       
  5491 				'onActivate',
       
  5492 				'onDeactivate',
       
  5493 				'onClick',
       
  5494 				'onEvent',
       
  5495 				'onMouseUp',
       
  5496 				'onMouseDown',
       
  5497 				'onDblClick',
       
  5498 				'onKeyDown',
       
  5499 				'onKeyUp',
       
  5500 				'onKeyPress',
       
  5501 				'onContextMenu',
       
  5502 				'onSubmit',
       
  5503 				'onReset',
       
  5504 				'onPaste',
       
  5505 				'onPreProcess',
       
  5506 				'onPostProcess',
       
  5507 				'onBeforeSetContent',
       
  5508 				'onBeforeGetContent',
       
  5509 				'onSetContent',
       
  5510 				'onGetContent',
       
  5511 				'onLoadContent',
       
  5512 				'onSaveContent',
       
  5513 				'onNodeChange',
       
  5514 				'onChange',
       
  5515 				'onBeforeExecCommand',
       
  5516 				'onExecCommand',
       
  5517 				'onUndo',
       
  5518 				'onRedo',
       
  5519 				'onVisualAid',
       
  5520 				'onSetProgressState'
       
  5521 			], function(e) {
       
  5522 				t[e] = new Dispatcher(t);
       
  5523 			});
       
  5524 
       
  5525 			// Default editor config
       
  5526 			t.settings = s = extend({
       
  5527 				id : id,
       
  5528 				language : 'en',
       
  5529 				docs_language : 'en',
       
  5530 				theme : 'simple',
       
  5531 				skin : 'default',
       
  5532 				delta_width : 0,
       
  5533 				delta_height : 0,
       
  5534 				popup_css : '',
       
  5535 				plugins : '',
       
  5536 				document_base_url : tinymce.documentBaseURL,
       
  5537 				add_form_submit_trigger : 1,
       
  5538 				submit_patch : 1,
       
  5539 				add_unload_trigger : 1,
       
  5540 				convert_urls : 1,
       
  5541 				relative_urls : 1,
       
  5542 				remove_script_host : 1,
       
  5543 				table_inline_editing : 0,
       
  5544 				object_resizing : 1,
       
  5545 				cleanup : 1,
       
  5546 				accessibility_focus : 1,
       
  5547 				custom_shortcuts : 1,
       
  5548 				custom_undo_redo_keyboard_shortcuts : 1,
       
  5549 				custom_undo_redo_restore_selection : 1,
       
  5550 				custom_undo_redo : 1,
       
  5551 				doctype : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',
       
  5552 				visual_table_class : 'mceItemTable',
       
  5553 				visual : 1,
       
  5554 				inline_styles : true,
       
  5555 				convert_fonts_to_spans : true,
       
  5556 				font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
       
  5557 				apply_source_formatting : 1,
       
  5558 				directionality : 'ltr',
       
  5559 				forced_root_block : 'p',
       
  5560 				valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*]',
       
  5561 				hidden_input : 1,
       
  5562 				padd_empty_editor : 1,
       
  5563 				render_ui : 1,
       
  5564 				init_theme : 1
       
  5565 			}, s);
       
  5566 
       
  5567 			// Setup URIs
       
  5568 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
       
  5569 				base_uri : tinyMCE.baseURI
       
  5570 			});
       
  5571 			t.baseURI = EditorManager.baseURI;
       
  5572 
       
  5573 			// Call setup
       
  5574 			t.execCallback('setup', t);
       
  5575 		},
       
  5576 
       
  5577 		render : function() {
       
  5578 			var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
       
  5579 
       
  5580 			// Add hidden input for non input elements inside form elements
       
  5581 			if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
       
  5582 				DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
       
  5583 
       
  5584 			if (s.strict_loading_mode)
       
  5585 				sl.settings.strict_mode = s.strict_loading_mode;
       
  5586 
       
  5587 			t.windowManager = new tinymce.WindowManager(t);
       
  5588 
       
  5589 			if (s.encoding == 'xml') {
       
  5590 				t.onGetContent.add(function(ed, o) {
       
  5591 					if (o.get)
       
  5592 						o.content = DOM.encode(o.content);
       
  5593 				});
       
  5594 			}
       
  5595 
       
  5596 			if (s.add_form_submit_trigger) {
       
  5597 				t.onSubmit.add(function() {
       
  5598 					if (t.initialized) {
       
  5599 						t.save();
       
  5600 						t.isNotDirty = 1;
       
  5601 					}
       
  5602 				});
       
  5603 			}
       
  5604 
       
  5605 			Event.add(document, 'unload', function() {
       
  5606 				if (t.initialized && !t.destroyed && s.add_unload_trigger)
       
  5607 					t.save({format : 'raw', no_events : true});
       
  5608 			});
       
  5609 
       
  5610 			tinymce.addUnload(t._destroy, t);
       
  5611 
       
  5612 			if (s.submit_patch) {
       
  5613 				t.onBeforeRenderUI.add(function() {
       
  5614 					var n = t.getElement().form;
       
  5615 
       
  5616 					if (!n)
       
  5617 						return;
       
  5618 
       
  5619 					// Already patched
       
  5620 					if (n._mceOldSubmit)
       
  5621 						return;
       
  5622 
       
  5623 					// Check page uses id="submit" or name="submit" for it's submit button
       
  5624 					if (!n.submit.nodeType) {
       
  5625 						t.formElement = n;
       
  5626 						n._mceOldSubmit = n.submit;
       
  5627 						n.submit = function() {
       
  5628 							// Save all instances
       
  5629 							EditorManager.triggerSave();
       
  5630 							t.isNotDirty = 1;
       
  5631 
       
  5632 							return this._mceOldSubmit(this);
       
  5633 						};
       
  5634 					}
       
  5635 
       
  5636 					n = null;
       
  5637 				});
       
  5638 			}
       
  5639 
       
  5640 			// Load scripts
       
  5641 			function loadScripts() {
       
  5642 				sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');
       
  5643 
       
  5644 				if (s.theme.charAt(0) != '-')
       
  5645 					ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
       
  5646 
       
  5647 				each(s.plugins.split(','), function(p) {
       
  5648 					if (p && p.charAt(0) != '-') {
       
  5649 						// Skip safari plugin for other browsers
       
  5650 						if (!isWebKit && p == 'safari')
       
  5651 							return;
       
  5652 
       
  5653 						PluginManager.load(p, 'plugins/' + p + '/editor_plugin' + tinymce.suffix + '.js');
       
  5654 					}
       
  5655 				});
       
  5656 
       
  5657 				// Init when que is loaded
       
  5658 				sl.loadQueue(function() {
       
  5659 					if (s.ask) {
       
  5660 						function ask() {
       
  5661 							t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {
       
  5662 								if (s)
       
  5663 									t.init();
       
  5664 								else
       
  5665 									Event.remove(t.id, 'focus', ask);
       
  5666 							});
       
  5667 						};
       
  5668 
       
  5669 						Event.add(t.id, 'focus', ask);
       
  5670 						return;
       
  5671 					}
       
  5672 
       
  5673 					t.init();
       
  5674 				});
       
  5675 			};
       
  5676 
       
  5677 			// Load compat2x first
       
  5678 			if (s.plugins.indexOf('compat2x') != -1) {
       
  5679 				PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
       
  5680 				sl.loadQueue(loadScripts);
       
  5681 			} else
       
  5682 				loadScripts();
       
  5683 		},
       
  5684 
       
  5685 		init : function() {
       
  5686 			var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti;
       
  5687 
       
  5688 			EditorManager.add(t);
       
  5689 
       
  5690 			// Create theme
       
  5691 			s.theme = s.theme.replace(/-/, '');
       
  5692 			o = ThemeManager.get(s.theme);
       
  5693 			t.theme = new o();
       
  5694 
       
  5695 			if (t.theme.init && s.init_theme)
       
  5696 				t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
       
  5697 
       
  5698 			// Create all plugins
       
  5699 			each(s.plugins.replace(/\-/g, '').split(','), function(p) {
       
  5700 				var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po;
       
  5701 
       
  5702 				if (c) {
       
  5703 					po = new c(t, u);
       
  5704 
       
  5705 					t.plugins[p] = po;
       
  5706 
       
  5707 					if (po.init)
       
  5708 						po.init(t, u);
       
  5709 				}
       
  5710 			});
       
  5711 
       
  5712 			// Setup popup CSS path(s)
       
  5713 			s.popup_css = t.baseURI.toAbsolute(s.popup_css || "themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");
       
  5714 
       
  5715 			if (s.popup_css_add)
       
  5716 				s.popup_css += ',' + s.popup_css_add;
       
  5717 
       
  5718 			// Setup control factory
       
  5719 			t.controlManager = new tinymce.ControlManager(t);
       
  5720 			t.undoManager = new tinymce.UndoManager(t);
       
  5721 
       
  5722 			// Pass through
       
  5723 			t.undoManager.onAdd.add(function(um, l) {
       
  5724 				return t.onChange.dispatch(t, l, um);
       
  5725 			});
       
  5726 
       
  5727 			t.undoManager.onUndo.add(function(um, l) {
       
  5728 				return t.onUndo.dispatch(t, l, um);
       
  5729 			});
       
  5730 
       
  5731 			t.undoManager.onRedo.add(function(um, l) {
       
  5732 				return t.onRedo.dispatch(t, l, um);
       
  5733 			});
       
  5734 
       
  5735 			if (s.custom_undo_redo) {
       
  5736 				t.onExecCommand.add(function(ed, cmd) {
       
  5737 					if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint')
       
  5738 						t.undoManager.add();
       
  5739 				});
       
  5740 			}
       
  5741 
       
  5742 			t.onExecCommand.add(function(ed, c) {
       
  5743 				// Don't refresh the select lists until caret move
       
  5744 				if (!/^(FontName|FontSize)$/.test(c))
       
  5745 					t.nodeChanged();
       
  5746 			});
       
  5747 
       
  5748 			// Remove ghost selections on images and tables in Gecko
       
  5749 			if (isGecko) {
       
  5750 				function repaint() {
       
  5751 					t.execCommand('mceRepaint');
       
  5752 				};
       
  5753 
       
  5754 				t.onUndo.add(repaint);
       
  5755 				t.onRedo.add(repaint);
       
  5756 				t.onSetContent.add(repaint);
       
  5757 			}
       
  5758 
       
  5759 			// Enables users to override the control factory
       
  5760 			t.onBeforeRenderUI.dispatch(t, t.controlManager);
       
  5761 
       
  5762 			// Measure box
       
  5763 			if (s.render_ui) {
       
  5764 				w = s.width || e.style.width || e.clientWidth;
       
  5765 				h = s.height || e.style.height || e.clientHeight;
       
  5766 				t.orgDisplay = e.style.display;
       
  5767 
       
  5768 				if (('' + w).indexOf('%') == -1)
       
  5769 					w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);
       
  5770 
       
  5771 				if (('' + h).indexOf('%') == -1)
       
  5772 					h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
       
  5773 
       
  5774 				// Render UI
       
  5775 				o = t.theme.renderUI({
       
  5776 					targetNode : e,
       
  5777 					width : w,
       
  5778 					height : h,
       
  5779 					deltaWidth : s.delta_width,
       
  5780 					deltaHeight : s.delta_height
       
  5781 				});
       
  5782 			}
       
  5783 
       
  5784 			
       
  5785 			// Resize editor
       
  5786 			DOM.setStyles(o.sizeContainer || o.editorContainer, {
       
  5787 				width : w,
       
  5788 				height : h
       
  5789 			});
       
  5790 
       
  5791 			function createIfr() {
       
  5792 				h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');
       
  5793 				if (h < 100)
       
  5794 					h = 100;
       
  5795 
       
  5796 				// Create iframe
       
  5797 				n = DOM.add(o.iframeContainer, 'iframe', {
       
  5798 					id : s.id + "_ifr",
       
  5799 					src : 'javascript:""', // Workaround for HTTPS warning in IE6/7
       
  5800 					frameBorder : '0',
       
  5801 					style : {
       
  5802 						width : '100%',
       
  5803 						height : h
       
  5804 					}
       
  5805 				});
       
  5806 
       
  5807 				t.contentAreaContainer = o.iframeContainer;
       
  5808 				DOM.get(o.editorContainer).style.display = t.orgDisplay;
       
  5809 				DOM.get(s.id).style.display = 'none';
       
  5810 
       
  5811 				// Safari 2.x requires us to wait for the load event and load a real HTML doc
       
  5812 				if (tinymce.isOldWebKit) {
       
  5813 					Event.add(n, 'load', t.setupIframe, t);
       
  5814 					n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
       
  5815 				} else {
       
  5816 					t.setupIframe();
       
  5817 					e = n = o = null; // Cleanup
       
  5818 				}
       
  5819 			};
       
  5820 
       
  5821 			// Waits for the editor to become visible, then it will run the init
       
  5822 			// This method is somewhat ugly but this is the best way to deal with it without
       
  5823 			// forcing the user to add some logic to their application.
       
  5824 			if (isGecko) {
       
  5825 				function check() {
       
  5826 					var hi;
       
  5827 
       
  5828 					DOM.getParent(t.id, function(e) {
       
  5829 						if (DOM.getStyle(e, 'display', true) == 'none') {
       
  5830 							hi = 1;
       
  5831 							return true;
       
  5832 						}
       
  5833 					});
       
  5834 
       
  5835 					return hi;
       
  5836 				};
       
  5837 
       
  5838 				if (check()) {
       
  5839 					ti = window.setInterval(function() {
       
  5840 						if (!check()) {
       
  5841 							createIfr();
       
  5842 							window.clearInterval(ti);
       
  5843 						}
       
  5844 					}, 300);
       
  5845 
       
  5846 					return;
       
  5847 				}
       
  5848 			}
       
  5849 
       
  5850 			createIfr();
       
  5851 		},
       
  5852 
       
  5853 		setupIframe : function() {
       
  5854 			var t = this, s = t.settings, e = DOM.get(s.id), d = t.getDoc();
       
  5855 
       
  5856 			// Design mode needs to be added here Ctrl+A will fail otherwise
       
  5857 			if (!isIE)
       
  5858 				d.designMode = 'On';
       
  5859 
       
  5860 			// Setup body
       
  5861 			d.open();
       
  5862 			d.write(s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body id="tinymce" class="mceContentBody"></body></html>');
       
  5863 			d.close();
       
  5864 
       
  5865 			// IE needs to use contentEditable or it will display non secure items for HTTPS
       
  5866 			if (isIE)
       
  5867 				t.getBody().contentEditable = true;
       
  5868 
       
  5869 			// Setup objects
       
  5870 			t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
       
  5871 				keep_values : true,
       
  5872 				url_converter : t.convertURL,
       
  5873 				url_converter_scope : t,
       
  5874 				hex_colors : s.force_hex_style_colors,
       
  5875 				class_filter : s.class_filter
       
  5876 			});
       
  5877 
       
  5878 			t.serializer = new tinymce.dom.Serializer({
       
  5879 				entity_encoding : s.entity_encoding,
       
  5880 				entities : s.entities,
       
  5881 				valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,
       
  5882 				extended_valid_elements : s.extended_valid_elements,
       
  5883 				valid_child_elements : s.valid_child_elements,
       
  5884 				invalid_elements : s.invalid_elements,
       
  5885 				fix_table_elements : s.fix_table_elements,
       
  5886 				fix_list_elements : s.fix_list_elements,
       
  5887 				fix_content_duplication : s.fix_content_duplication,
       
  5888 				convert_fonts_to_spans : s.convert_fonts_to_spans,
       
  5889 				font_size_classes  : s.font_size_classes,
       
  5890 				font_size_style_values : s.font_size_style_values,
       
  5891 				apply_source_formatting : s.apply_source_formatting,
       
  5892 				remove_linebreaks : s.remove_linebreaks,
       
  5893 				dom : t.dom
       
  5894 			});
       
  5895 
       
  5896 			t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
       
  5897 			t.forceBlocks = new tinymce.ForceBlocks(t, {
       
  5898 				forced_root_block : s.forced_root_block
       
  5899 			});
       
  5900 			t.editorCommands = new tinymce.EditorCommands(t);
       
  5901 
       
  5902 			// Pass through
       
  5903 			t.serializer.onPreProcess.add(function(se, o) {
       
  5904 				return t.onPreProcess.dispatch(t, o, se);
       
  5905 			});
       
  5906 
       
  5907 			t.serializer.onPostProcess.add(function(se, o) {
       
  5908 				return t.onPostProcess.dispatch(t, o, se);
       
  5909 			});
       
  5910 
       
  5911 			t.onPreInit.dispatch(t);
       
  5912 
       
  5913 			if (!s.gecko_spellcheck)
       
  5914 				t.getBody().spellcheck = 0;
       
  5915 
       
  5916 			t._addEvents();
       
  5917 
       
  5918 			t.controlManager.onPostRender.dispatch(t, t.controlManager);
       
  5919 			t.onPostRender.dispatch(t);
       
  5920 
       
  5921 			if (s.directionality)
       
  5922 				t.getBody().dir = s.directionality;
       
  5923 
       
  5924 			if (s.nowrap)
       
  5925 				t.getBody().style.whiteSpace = "nowrap";
       
  5926 
       
  5927 			if (s.auto_resize)
       
  5928 				t.onNodeChange.add(t.resizeToContent, t);
       
  5929 
       
  5930 			if (s.handle_node_change_callback) {
       
  5931 				t.onNodeChange.add(function(ed, cm, n) {
       
  5932 					t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());
       
  5933 				});
       
  5934 			}
       
  5935 
       
  5936 			if (s.save_callback) {
       
  5937 				t.onSaveContent.add(function(ed, o) {
       
  5938 					var h = t.execCallback('save_callback', t.id, o.content, t.getBody());
       
  5939 
       
  5940 					if (h)
       
  5941 						o.content = h;
       
  5942 				});
       
  5943 			}
       
  5944 
       
  5945 			if (s.onchange_callback) {
       
  5946 				t.onChange.add(function(ed, l) {
       
  5947 					t.execCallback('onchange_callback', t, l);
       
  5948 				});
       
  5949 			}
       
  5950 
       
  5951 			if (s.convert_newlines_to_brs) {
       
  5952 				t.onBeforeSetContent.add(function(ed, o) {
       
  5953 					if (o.initial)
       
  5954 						o.content = o.content.replace(/\r?\n/g, '<br />');
       
  5955 				});
       
  5956 			}
       
  5957 
       
  5958 			if (s.preformatted) {
       
  5959 				t.onPostProcess.add(function(ed, o) {
       
  5960 					o.content = o.content.replace(/^\s*<pre.*?>/, '');
       
  5961 					o.content = o.content.replace(/<\/pre>\s*$/, '');
       
  5962 
       
  5963 					if (o.set)
       
  5964 						o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';
       
  5965 				});
       
  5966 			}
       
  5967 
       
  5968 			if (s.verify_css_classes) {
       
  5969 				t.serializer.attribValueFilter = function(n, v) {
       
  5970 					var s, cl;
       
  5971 
       
  5972 					if (n == 'class') {
       
  5973 						// Build regexp for classes
       
  5974 						if (!t.classesRE) {
       
  5975 							cl = t.dom.getClasses();
       
  5976 
       
  5977 							if (cl.length > 0) {
       
  5978 								s = '';
       
  5979 
       
  5980 								each (cl, function(o) {
       
  5981 									s += (s ? '|' : '') + o['class'];
       
  5982 								});
       
  5983 
       
  5984 								t.classesRE = new RegExp('(' + s + ')', 'gi');
       
  5985 							}
       
  5986 						}
       
  5987 
       
  5988 						return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';
       
  5989 					}
       
  5990 
       
  5991 					return v;
       
  5992 				};
       
  5993 			}
       
  5994 
       
  5995 			if (s.convert_fonts_to_spans)
       
  5996 				t._convertFonts();
       
  5997 
       
  5998 			if (s.inline_styles)
       
  5999 				t._convertInlineElements();
       
  6000 
       
  6001 			if (s.cleanup_callback) {
       
  6002 				t.onSetContent.add(function(ed, o) {
       
  6003 					if (o.initial) {
       
  6004 						t.setContent(t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o), {format : 'raw', no_events : true});
       
  6005 						t.execCallback('cleanup_callback', 'insert_to_editor_dom', t.getDoc(), o);
       
  6006 					}
       
  6007 				});
       
  6008 
       
  6009 				t.onPreProcess.add(function(ed, o) {
       
  6010 					if (o.set)
       
  6011 						t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
       
  6012 
       
  6013 					if (o.get)
       
  6014 						t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
       
  6015 				});
       
  6016 
       
  6017 				t.onPostProcess.add(function(ed, o) {
       
  6018 					if (o.set)
       
  6019 						o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
       
  6020 
       
  6021 					if (o.get)						
       
  6022 						o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
       
  6023 				});
       
  6024 			}
       
  6025 
       
  6026 			if (s.save_callback) {
       
  6027 				t.onGetContent.add(function(ed, o) {
       
  6028 					if (o.save)
       
  6029 						o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());
       
  6030 				});
       
  6031 			}
       
  6032 
       
  6033 			if (s.handle_event_callback) {
       
  6034 				t.onEvent.add(function(ed, e, o) {
       
  6035 					if (t.execCallback('handle_event_callback', e, ed, o) === false)
       
  6036 						Event.cancel(e);
       
  6037 				});
       
  6038 			}
       
  6039 
       
  6040 			t.onSetContent.add(function() {
       
  6041 				// Safari needs some time, it will crash the browser when a link is created otherwise
       
  6042 				// I think this crash issue is resolved in the latest 3.0.4
       
  6043 				//window.setTimeout(function() {
       
  6044 					t.addVisual(t.getBody());
       
  6045 				//}, 1);
       
  6046 			});
       
  6047 
       
  6048 			// Remove empty contents
       
  6049 			if (s.padd_empty_editor) {
       
  6050 				t.onPostProcess.add(function(ed, o) {
       
  6051 					o.content = o.content.replace(/^<p>(&nsbp;|#160;|\s)<\/p>$/, '');
       
  6052 				});
       
  6053 			}
       
  6054 
       
  6055 			t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});
       
  6056 			t.startContent = t.getContent({format : 'raw'});
       
  6057 			t.undoManager.add({initial : true});
       
  6058 
       
  6059 			t.initialized = true;
       
  6060 
       
  6061 			t.onInit.dispatch(t);
       
  6062 			t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());
       
  6063 			t.execCallback('init_instance_callback', t);
       
  6064 			t.focus(true);
       
  6065 			t.nodeChanged({initial : 1});
       
  6066 
       
  6067 			// Load specified content CSS last
       
  6068 			if (s.content_css) {
       
  6069 				tinymce.each(s.content_css.split(','), function(u) {
       
  6070 					t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));
       
  6071 				});
       
  6072 			}
       
  6073 
       
  6074 			// Handle auto focus
       
  6075 			if (s.auto_focus) {
       
  6076 				setTimeout(function () {
       
  6077 					var ed = EditorManager.get(s.auto_focus);
       
  6078 
       
  6079 					ed.selection.select(ed.getBody(), 1);
       
  6080 					ed.selection.collapse(1);
       
  6081 					ed.getWin().focus();
       
  6082 				}, 100);
       
  6083 			}
       
  6084 
       
  6085 			e = null;
       
  6086 		},
       
  6087 
       
  6088 		
       
  6089 		focus : function(sf) {
       
  6090 			var oed, t = this;
       
  6091 
       
  6092 			if (!sf) {
       
  6093 				t.getWin().focus();
       
  6094 
       
  6095 							}
       
  6096 
       
  6097 			if (EditorManager.activeEditor != t) {
       
  6098 				if ((oed = EditorManager.activeEditor) != null)
       
  6099 					oed.onDeactivate.dispatch(oed, t);
       
  6100 
       
  6101 				t.onActivate.dispatch(t, oed);
       
  6102 			}
       
  6103 
       
  6104 			EditorManager._setActive(t);
       
  6105 		},
       
  6106 
       
  6107 		execCallback : function(n) {
       
  6108 			var t = this, f = t.settings[n], s;
       
  6109 
       
  6110 			if (!f)
       
  6111 				return;
       
  6112 
       
  6113 			// Look through lookup
       
  6114 			if (t.callbackLookup && (s = t.callbackLookup[n])) {
       
  6115 				f = s.func;
       
  6116 				s = s.scope;
       
  6117 			}
       
  6118 
       
  6119 			if (is(f, 'string')) {
       
  6120 				s = f.replace(/\.\w+$/, '');
       
  6121 				s = s ? tinymce.resolve(s) : 0;
       
  6122 				f = tinymce.resolve(f);
       
  6123 				t.callbackLookup = t.callbackLookup || {};
       
  6124 				t.callbackLookup[n] = {func : f, scope : s};
       
  6125 			}
       
  6126 
       
  6127 			return f.apply(s || t, Array.prototype.slice.call(arguments, 1));
       
  6128 		},
       
  6129 
       
  6130 		translate : function(s) {
       
  6131 			var c = this.settings.language, i18n = EditorManager.i18n;
       
  6132 
       
  6133 			if (!s)
       
  6134 				return '';
       
  6135 
       
  6136 			return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {
       
  6137 				return i18n[c + '.' + b] || '{#' + b + '}';
       
  6138 			});
       
  6139 		},
       
  6140 
       
  6141 		getLang : function(n, dv) {
       
  6142 			return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');
       
  6143 		},
       
  6144 
       
  6145 		getParam : function(n, dv) {
       
  6146 			return is(this.settings[n]) ? this.settings[n] : dv;
       
  6147 		},
       
  6148 
       
  6149 		nodeChanged : function(o) {
       
  6150 			var t = this, s = t.selection, n = s.getNode() || this.getBody();
       
  6151 
       
  6152 			this.onNodeChange.dispatch(
       
  6153 				t,
       
  6154 				o ? o.controlManager || t.controlManager : t.controlManager,
       
  6155 				isIE && n.ownerDocument != t.getDoc() ? this.getBody() : n, // Fix for IE initial state
       
  6156 				s.isCollapsed(),
       
  6157 				o
       
  6158 			);
       
  6159 		},
       
  6160 
       
  6161 		addButton : function(n, s) {
       
  6162 			var t = this;
       
  6163 
       
  6164 			t.buttons = t.buttons || {};
       
  6165 			t.buttons[n] = s;
       
  6166 		},
       
  6167 
       
  6168 		addCommand : function(n, f, s) {
       
  6169 			this.execCommands[n] = {func : f, scope : s || this};
       
  6170 		},
       
  6171 
       
  6172 		addQueryStateHandler : function(n, f, s) {
       
  6173 			this.queryStateCommands[n] = {func : f, scope : s || this};
       
  6174 		},
       
  6175 
       
  6176 		addQueryValueHandler : function(n, f, s) {
       
  6177 			this.queryValueCommands[n] = {func : f, scope : s || this};
       
  6178 		},
       
  6179 
       
  6180 		addShortcut : function(pa, desc, cmd_func, sc) {
       
  6181 			var t = this, c;
       
  6182 
       
  6183 			if (!t.settings.custom_shortcuts)
       
  6184 				return false;
       
  6185 
       
  6186 			t.shortcuts = t.shortcuts || {};
       
  6187 
       
  6188 			if (is(cmd_func, 'string')) {
       
  6189 				c = cmd_func;
       
  6190 
       
  6191 				cmd_func = function() {
       
  6192 					t.execCommand(c, false, null);
       
  6193 				};
       
  6194 			}
       
  6195 
       
  6196 			if (is(cmd_func, 'object')) {
       
  6197 				c = cmd_func;
       
  6198 
       
  6199 				cmd_func = function() {
       
  6200 					t.execCommand(c[0], c[1], c[2]);
       
  6201 				};
       
  6202 			}
       
  6203 
       
  6204 			each(pa.split(','), function(pa) {
       
  6205 				var o = {
       
  6206 					func : cmd_func,
       
  6207 					scope : sc || this,
       
  6208 					desc : desc,
       
  6209 					alt : false,
       
  6210 					ctrl : false,
       
  6211 					shift : false
       
  6212 				};
       
  6213 
       
  6214 				each(pa.split('+'), function(v) {
       
  6215 					switch (v) {
       
  6216 						case 'alt':
       
  6217 						case 'ctrl':
       
  6218 						case 'shift':
       
  6219 							o[v] = true;
       
  6220 							break;
       
  6221 
       
  6222 						default:
       
  6223 							o.charCode = v.charCodeAt(0);
       
  6224 							o.keyCode = v.toUpperCase().charCodeAt(0);
       
  6225 					}
       
  6226 				});
       
  6227 
       
  6228 				t.shortcuts[(o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode] = o;
       
  6229 			});
       
  6230 
  6415 			return true;
  6231 			return true;
       
  6232 		},
       
  6233 
       
  6234 		execCommand : function(cmd, ui, val) {
       
  6235 			var t = this, s = 0, o;
       
  6236 
       
  6237 			if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(cmd))
       
  6238 				t.focus();
       
  6239 
       
  6240 			o = {};
       
  6241 			t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o);
       
  6242 			if (o.terminate)
       
  6243 				return false;
       
  6244 
       
  6245 			// Comamnd callback
       
  6246 			if (t.execCallback('execcommand_callback', null, t.id, t.selection.getNode(), cmd, ui, val)) {
       
  6247 				t.onExecCommand.dispatch(t, cmd, ui, val);
       
  6248 				return true;
       
  6249 			}
       
  6250 
       
  6251 			// Registred commands
       
  6252 			if (o = t.execCommands[cmd]) {
       
  6253 				s = o.func.call(o.scope, ui, val);
       
  6254 				t.onExecCommand.dispatch(t, cmd, ui, val);
       
  6255 				return s;
       
  6256 			}
       
  6257 
       
  6258 			// Plugin commands
       
  6259 			each(t.plugins, function(p) {
       
  6260 				if (p.execCommand && p.execCommand(cmd, ui, val)) {
       
  6261 					t.onExecCommand.dispatch(t, cmd, ui, val);
       
  6262 					s = 1;
       
  6263 					return false;
       
  6264 				}
       
  6265 			});
       
  6266 
       
  6267 			if (s)
       
  6268 				return true;
       
  6269 
       
  6270 			// Theme commands
       
  6271 			if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {
       
  6272 				t.onExecCommand.dispatch(t, cmd, ui, val);
       
  6273 				return true;
       
  6274 			}
       
  6275 
       
  6276 			// Editor commands
       
  6277 			if (t.editorCommands.execCommand(cmd, ui, val)) {
       
  6278 				t.onExecCommand.dispatch(t, cmd, ui, val);
       
  6279 				return true;
       
  6280 			}
       
  6281 
       
  6282 			// Browser commands
       
  6283 			t.getDoc().execCommand(cmd, ui, val);
       
  6284 			t.onExecCommand.dispatch(t, cmd, ui, val);
       
  6285 		},
       
  6286 
       
  6287 		queryCommandState : function(c) {
       
  6288 			var t = this, o;
       
  6289 
       
  6290 			// Registred commands
       
  6291 			if (o = t.queryStateCommands[c])
       
  6292 				return o.func.call(o.scope);
       
  6293 
       
  6294 			// Registred commands
       
  6295 			o = t.editorCommands.queryCommandState(c);
       
  6296 			if (o !== -1)
       
  6297 				return o;
       
  6298 
       
  6299 			// Browser commands
       
  6300 			return this.getDoc().queryCommandState(c);
       
  6301 		},
       
  6302 
       
  6303 		queryCommandValue : function(c) {
       
  6304 			var t = this, o;
       
  6305 
       
  6306 			// Registred commands
       
  6307 			if (o = t.queryValueCommands[c])
       
  6308 				return o.func.call(o.scope);
       
  6309 
       
  6310 			// Registred commands
       
  6311 			o = t.editorCommands.queryCommandValue(c);
       
  6312 			if (is(o))
       
  6313 				return o;
       
  6314 
       
  6315 			// Browser commands
       
  6316 			return this.getDoc().queryCommandValue(c);
       
  6317 		},
       
  6318 
       
  6319 		show : function() {
       
  6320 			var t = this;
       
  6321 
       
  6322 			DOM.show(t.getContainer());
       
  6323 			DOM.hide(t.id);
       
  6324 			t.load();
       
  6325 		},
       
  6326 
       
  6327 		hide : function() {
       
  6328 			var t = this, s = t.settings;
       
  6329 
       
  6330 			// Fixed bug where IE has a blinking cursor left from the editor
       
  6331 			if (isIE)
       
  6332 				t.execCommand('SelectAll');
       
  6333 
       
  6334 			DOM.hide(t.getContainer());
       
  6335 			DOM.setStyle(s.id, 'display', t.orgDisplay);
       
  6336 			t.save();
       
  6337 		},
       
  6338 
       
  6339 		isHidden : function() {
       
  6340 			return !DOM.isHidden(this.id);
       
  6341 		},
       
  6342 
       
  6343 		setProgressState : function(b, ti, o) {
       
  6344 			this.onSetProgressState.dispatch(this, b, ti, o);
       
  6345 
       
  6346 			return b;
       
  6347 		},
       
  6348 
       
  6349 		remove : function() {
       
  6350 			var t = this;
       
  6351 
       
  6352 			t.removed = 1; // Cancels post remove event execution
       
  6353 			t.hide();
       
  6354 			DOM.remove(t.getContainer());
       
  6355 
       
  6356 			t.execCallback('remove_instance_callback', t);
       
  6357 			t.onRemove.dispatch(t);
       
  6358 
       
  6359 			EditorManager.remove(t);
       
  6360 		},
       
  6361 
       
  6362 		resizeToContent : function() {
       
  6363 			var t = this;
       
  6364 
       
  6365 			DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight);
       
  6366 		},
       
  6367 
       
  6368 		load : function(o) {
       
  6369 			var t = this, e = t.getElement(), h;
       
  6370 
       
  6371 			o = o || {};
       
  6372 			o.load = true;
       
  6373 
       
  6374 			h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);
       
  6375 			o.element = e;
       
  6376 
       
  6377 			if (!o.no_events)
       
  6378 				t.onLoadContent.dispatch(t, o);
       
  6379 
       
  6380 			o.element = e = null;
       
  6381 
       
  6382 			return h;
       
  6383 		},
       
  6384 
       
  6385 		save : function(o) {
       
  6386 			var t = this, e = t.getElement(), h, f;
       
  6387 
       
  6388 			o = o || {};
       
  6389 			o.save = true;
       
  6390 
       
  6391 			o.element = e;
       
  6392 			h = o.content = t.getContent(o);
       
  6393 
       
  6394 			if (!o.no_events)
       
  6395 				t.onSaveContent.dispatch(t, o);
       
  6396 
       
  6397 			h = o.content;
       
  6398 
       
  6399 			if (!/TEXTAREA|INPUT/i.test(e.nodeName)) {
       
  6400 				e.innerHTML = h;
       
  6401 
       
  6402 				// Update hidden form element
       
  6403 				if (f = DOM.getParent(t.id, 'form')) {
       
  6404 					each(f.elements, function(e) {
       
  6405 						if (e.name == t.id) {
       
  6406 							e.value = h;
       
  6407 							return false;
       
  6408 						}
       
  6409 					});
       
  6410 				}
       
  6411 			} else
       
  6412 				e.value = h;
       
  6413 
       
  6414 			o.element = e = null;
       
  6415 
       
  6416 			return h;
       
  6417 		},
       
  6418 
       
  6419 		setContent : function(h, o) {
       
  6420 			var t = this;
       
  6421 
       
  6422 			o = o || {};
       
  6423 			o.format = o.format || 'html';
       
  6424 			o.set = true;
       
  6425 			o.content = h;
       
  6426 
       
  6427 			if (!o.no_events)
       
  6428 				t.onBeforeSetContent.dispatch(t, o);
       
  6429 
       
  6430 			// Padd empty content in Gecko and Safari. Commands will otherwise fail on the content
       
  6431 			// It will also be impossible to place the caret in the editor unless there is a BR element present
       
  6432 			if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {
       
  6433 				o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />');
       
  6434 				o.format = 'raw';
       
  6435 			}
       
  6436 
       
  6437 			o.content = t.dom.setHTML(t.getBody(), o.content);
       
  6438 
       
  6439 			if (o.format != 'raw' && t.settings.cleanup) {
       
  6440 				o.getInner = true;
       
  6441 				o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));
       
  6442 			}
       
  6443 
       
  6444 			if (!o.no_events)
       
  6445 				t.onSetContent.dispatch(t, o);
       
  6446 
       
  6447 			return o.content;
       
  6448 		},
       
  6449 
       
  6450 		getContent : function(o) {
       
  6451 			var t = this, h;
       
  6452 
       
  6453 			o = o || {};
       
  6454 			o.format = o.format || 'html';
       
  6455 			o.get = true;
       
  6456 
       
  6457 			if (!o.no_events)
       
  6458 				t.onBeforeGetContent.dispatch(t, o);
       
  6459 
       
  6460 			if (o.format != 'raw' && t.settings.cleanup) {
       
  6461 				o.getInner = true;
       
  6462 				h = t.serializer.serialize(t.getBody(), o);
       
  6463 			} else
       
  6464 				h = t.getBody().innerHTML;
       
  6465 
       
  6466 			h = h.replace(/^\s*|\s*$/g, '');
       
  6467 			o = {content : h};
       
  6468 			t.onGetContent.dispatch(t, o);
       
  6469 
       
  6470 			return o.content;
       
  6471 		},
       
  6472 
       
  6473 		isDirty : function() {
       
  6474 			var t = this;
       
  6475 
       
  6476 			return tinymce.trim(t.startContent) != tinymce.trim(t.getContent({format : 'raw', no_events : 1})) && !t.isNotDirty;
       
  6477 		},
       
  6478 
       
  6479 		getContainer : function() {
       
  6480 			var t = this;
       
  6481 
       
  6482 			if (!t.container)
       
  6483 				t.container = DOM.get(t.id + "_parent");
       
  6484 
       
  6485 			return t.container;
       
  6486 		},
       
  6487 
       
  6488 		getContentAreaContainer : function() {
       
  6489 			return this.contentAreaContainer;
       
  6490 		},
       
  6491 
       
  6492 		getElement : function() {
       
  6493 			return DOM.get(this.settings.content_element || this.id);
       
  6494 		},
       
  6495 
       
  6496 		getWin : function() {
       
  6497 			var t = this;
       
  6498 
       
  6499 			if (!t.contentWindow)
       
  6500 				t.contentWindow = DOM.get(t.id + "_ifr").contentWindow;
       
  6501 
       
  6502 			return t.contentWindow;
       
  6503 		},
       
  6504 
       
  6505 		getDoc : function() {
       
  6506 			var t = this;
       
  6507 
       
  6508 			if (!t.contentDocument)
       
  6509 				t.contentDocument = this.getWin().document;
       
  6510 
       
  6511 			return t.contentDocument;
       
  6512 		},
       
  6513 
       
  6514 		getBody : function() {
       
  6515 			return this.bodyElement || this.getDoc().body;
       
  6516 		},
       
  6517 
       
  6518 		convertURL : function(u, n, e) {
       
  6519 			var t = this, s = t.settings;
       
  6520 
       
  6521 			// Use callback instead
       
  6522 			if (s.urlconverter_callback)
       
  6523 				return t.execCallback('urlconverter_callback', u, e, true, n);
       
  6524 
       
  6525 			// Don't convert link href since thats the CSS files that gets loaded into the editor
       
  6526 			if (!s.convert_urls || (e && e.nodeName == 'LINK'))
       
  6527 				return u;
       
  6528 
       
  6529 			// Convert to relative
       
  6530 			if (s.relative_urls)
       
  6531 				return t.documentBaseURI.toRelative(u);
       
  6532 
       
  6533 			// Convert to absolute
       
  6534 			u = t.documentBaseURI.toAbsolute(u, s.remove_script_host);
       
  6535 
       
  6536 			return u;
       
  6537 		},
       
  6538 
       
  6539 		addVisual : function(e) {
       
  6540 			var t = this, s = t.settings;
       
  6541 
       
  6542 			e = e || t.getBody();
       
  6543 
       
  6544 			if (!is(t.hasVisual))
       
  6545 				t.hasVisual = s.visual;
       
  6546 
       
  6547 			each(t.dom.select('table,a', e), function(e) {
       
  6548 				var v;
       
  6549 
       
  6550 				switch (e.nodeName) {
       
  6551 					case 'TABLE':
       
  6552 						v = t.dom.getAttrib(e, 'border');
       
  6553 
       
  6554 						if (!v || v == '0') {
       
  6555 							if (t.hasVisual)
       
  6556 								t.dom.addClass(e, s.visual_table_class);
       
  6557 							else
       
  6558 								t.dom.removeClass(e, s.visual_table_class);
       
  6559 						}
       
  6560 
       
  6561 						return;
       
  6562 
       
  6563 					case 'A':
       
  6564 						v = t.dom.getAttrib(e, 'name');
       
  6565 
       
  6566 						if (v) {
       
  6567 							if (t.hasVisual)
       
  6568 								t.dom.addClass(e, 'mceItemAnchor');
       
  6569 							else
       
  6570 								t.dom.removeClass(e, 'mceItemAnchor');
       
  6571 						}
       
  6572 
       
  6573 						return;
       
  6574 				}
       
  6575 			});
       
  6576 
       
  6577 			t.onVisualAid.dispatch(t, e, t.hasVisual);
       
  6578 		},
       
  6579 
       
  6580 		// Internal functions
       
  6581 
       
  6582 		_addEvents : function() {
       
  6583 			// 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset
       
  6584 			var t = this, i, s = t.settings, lo = {
       
  6585 				mouseup : 'onMouseUp',
       
  6586 				mousedown : 'onMouseDown',
       
  6587 				click : 'onClick',
       
  6588 				keyup : 'onKeyUp',
       
  6589 				keydown : 'onKeyDown',
       
  6590 				keypress : 'onKeyPress',
       
  6591 				submit : 'onSubmit',
       
  6592 				reset : 'onReset',
       
  6593 				contextmenu : 'onContextMenu',
       
  6594 				dblclick : 'onDblClick',
       
  6595 				paste : 'onPaste' // Doesn't work in all browsers yet
       
  6596 			};
       
  6597 
       
  6598 			function eventHandler(e, o) {
       
  6599 				var ty = e.type;
       
  6600 
       
  6601 				// Generic event handler
       
  6602 				if (t.onEvent.dispatch(t, e, o) !== false) {
       
  6603 					// Specific event handler
       
  6604 					t[lo[e.fakeType || e.type]].dispatch(t, e, o);
       
  6605 				}
       
  6606 			};
       
  6607 
       
  6608 			// Add DOM events
       
  6609 			each(lo, function(v, k) {
       
  6610 				switch (k) {
       
  6611 					case 'contextmenu':
       
  6612 						if (tinymce.isOpera) {
       
  6613 							// Fake contextmenu on Opera
       
  6614 							Event.add(t.getDoc(), 'mousedown', function(e) {
       
  6615 								if (e.ctrlKey) {
       
  6616 									e.fakeType = 'contextmenu';
       
  6617 									eventHandler(e);
       
  6618 								}
       
  6619 							});
       
  6620 						} else
       
  6621 							Event.add(t.getDoc(), k, eventHandler);
       
  6622 						break;
       
  6623 
       
  6624 					case 'paste':
       
  6625 						Event.add(t.getBody(), k, function(e) {
       
  6626 							var tx, h, el, r;
       
  6627 
       
  6628 							// Get plain text data
       
  6629 							if (e.clipboardData)
       
  6630 								tx = e.clipboardData.getData('text/plain');
       
  6631 							else if (tinymce.isIE)
       
  6632 								tx = t.getWin().clipboardData.getData('Text');
       
  6633 
       
  6634 							// Get HTML data
       
  6635 							/*if (tinymce.isIE) {
       
  6636 								el = DOM.add(document.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'});
       
  6637 								r = document.body.createTextRange();
       
  6638 								r.moveToElementText(el);
       
  6639 								r.execCommand('Paste');
       
  6640 								h = el.innerHTML;
       
  6641 								DOM.remove(el);
       
  6642 							}*/
       
  6643 
       
  6644 							eventHandler(e, {text : tx, html : h});
       
  6645 						});
       
  6646 						break;
       
  6647 
       
  6648 					case 'submit':
       
  6649 					case 'reset':
       
  6650 						Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
       
  6651 						break;
       
  6652 
       
  6653 					default:
       
  6654 						Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
       
  6655 				}
       
  6656 			});
       
  6657 
       
  6658 			Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
       
  6659 				t.focus(true);
       
  6660 			});
       
  6661 
       
  6662 			// Fixes bug where a specified document_base_uri could result in broken images
       
  6663 			// This will also fix drag drop of images in Gecko
       
  6664 			if (tinymce.isGecko) {
       
  6665 				// Convert all images to absolute URLs
       
  6666 /*				t.onSetContent.add(function(ed, o) {
       
  6667 					each(ed.dom.select('img'), function(e) {
       
  6668 						var v;
       
  6669 
       
  6670 						if (v = e.getAttribute('mce_src'))
       
  6671 							e.src = t.documentBaseURI.toAbsolute(v);
       
  6672 					})
       
  6673 				});*/
       
  6674 
       
  6675 				Event.add(t.getDoc(), 'DOMNodeInserted', function(e) {
       
  6676 					var v;
       
  6677 
       
  6678 					e = e.target;
       
  6679 
       
  6680 					if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('mce_src')))
       
  6681 						e.src = t.documentBaseURI.toAbsolute(v);
       
  6682 				});
       
  6683 			}
       
  6684 
       
  6685 			// Set various midas options in Gecko
       
  6686 			if (isGecko) {
       
  6687 				function setOpts() {
       
  6688 					var t = this, d = t.getDoc(), s = t.settings;
       
  6689 
       
  6690 					if (isGecko) {
       
  6691 						try {
       
  6692 							// Try new Gecko method
       
  6693 							d.execCommand("styleWithCSS", 0, false);
       
  6694 						} catch (ex) {
       
  6695 							// Use old
       
  6696 							d.execCommand("useCSS", 0, true);
       
  6697 						}
       
  6698 
       
  6699 						if (!s.table_inline_editing)
       
  6700 							try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}
       
  6701 
       
  6702 						if (!s.object_resizing)
       
  6703 							try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}
       
  6704 					}
       
  6705 				};
       
  6706 
       
  6707 				t.onBeforeExecCommand.add(setOpts);
       
  6708 				t.onMouseDown.add(setOpts);
       
  6709 			}
       
  6710 
       
  6711 			// Add node change handlers
       
  6712 			t.onMouseUp.add(t.nodeChanged);
       
  6713 			t.onClick.add(t.nodeChanged);
       
  6714 			t.onKeyUp.add(function(ed, e) {
       
  6715 				if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.keyCode == 46 || e.keyCode == 8 || e.ctrlKey)
       
  6716 					t.nodeChanged();
       
  6717 			});
       
  6718 
       
  6719 			// Add reset handler
       
  6720 			t.onReset.add(function() {
       
  6721 				t.setContent(t.startContent, {format : 'raw'});
       
  6722 			});
       
  6723 
       
  6724 			if (t.getParam('tab_focus')) {
       
  6725 				function tabCancel(ed, e) {
       
  6726 					if (e.keyCode === 9)
       
  6727 						return Event.cancel(e);
       
  6728 				};
       
  6729 
       
  6730 				function tabHandler(ed, e) {
       
  6731 					var v, f, el;
       
  6732 
       
  6733 					if (e.keyCode === 9) {
       
  6734 						v = ed.getParam('tab_focus');
       
  6735 
       
  6736 						if (v == ':next') {
       
  6737 							f = DOM.getParent(ed.id, 'form');
       
  6738 
       
  6739 							if (f) {
       
  6740 								each(f.elements, function(e, i) {
       
  6741 									if (e.id == ed.id)
       
  6742 										el = f.elements[i + 1];
       
  6743 								});
       
  6744 							}
       
  6745 						} else
       
  6746 							el = DOM.get(v);
       
  6747 
       
  6748 						if (el) {
       
  6749 							window.setTimeout(function() {window.focus();el.focus();}, 10);
       
  6750 							return Event.cancel(e);
       
  6751 						}
       
  6752 					}
       
  6753 				};
       
  6754 
       
  6755 				t.onKeyUp.add(tabCancel);
       
  6756 
       
  6757 				if (isGecko) {
       
  6758 					t.onKeyPress.add(tabHandler);
       
  6759 					t.onKeyDown.add(tabCancel);
       
  6760 				} else
       
  6761 					t.onKeyDown.add(tabHandler);
       
  6762 			}
       
  6763 
       
  6764 			// Add shortcuts
       
  6765 			if (s.custom_shortcuts) {
       
  6766 				if (s.custom_undo_redo_keyboard_shortcuts) {
       
  6767 					t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');
       
  6768 					t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');
       
  6769 				}
       
  6770 
       
  6771 				// Add default shortcuts for gecko
       
  6772 				if (isGecko) {
       
  6773 					t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold');
       
  6774 					t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic');
       
  6775 					t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline');
       
  6776 				}
       
  6777 
       
  6778 				// BlockFormat shortcuts keys
       
  6779 				for (i=1; i<=6; i++)
       
  6780 					t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, '<h' + i + '>']);
       
  6781 
       
  6782 				t.addShortcut('ctrl+7', '', ['FormatBlock', false, '<p>']);
       
  6783 				t.addShortcut('ctrl+8', '', ['FormatBlock', false, '<div>']);
       
  6784 				t.addShortcut('ctrl+9', '', ['FormatBlock', false, '<address>']);
       
  6785 
       
  6786 				function find(e) {
       
  6787 					var v = null;
       
  6788 
       
  6789 					if (!e.altKey && !e.ctrlKey && !e.metaKey)
       
  6790 						return v;
       
  6791 
       
  6792 					each(t.shortcuts, function(o) {
       
  6793 						if (o.ctrl != e.ctrlKey && (!tinymce.isMac || o.ctrl == e.metaKey))
       
  6794 							return;
       
  6795 
       
  6796 						if (o.alt != e.altKey)
       
  6797 							return;
       
  6798 
       
  6799 						if (o.shift != e.shiftKey)
       
  6800 							return;
       
  6801 
       
  6802 						if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {
       
  6803 							v = o;
       
  6804 							return false;
       
  6805 						}
       
  6806 					});
       
  6807 
       
  6808 					return v;
       
  6809 				};
       
  6810 
       
  6811 				t.onKeyUp.add(function(ed, e) {
       
  6812 					var o = find(e);
       
  6813 
       
  6814 					if (o)
       
  6815 						return Event.cancel(e);
       
  6816 				});
       
  6817 
       
  6818 				t.onKeyPress.add(function(ed, e) {
       
  6819 					var o = find(e);
       
  6820 
       
  6821 					if (o)
       
  6822 						return Event.cancel(e);
       
  6823 				});
       
  6824 
       
  6825 				t.onKeyDown.add(function(ed, e) {
       
  6826 					var o = find(e);
       
  6827 
       
  6828 					if (o) {
       
  6829 						o.func.call(o.scope);
       
  6830 						return Event.cancel(e);
       
  6831 					}
       
  6832 				});
       
  6833 			}
       
  6834 
       
  6835 			if (tinymce.isIE) {
       
  6836 				// Fix so resize will only update the width and height attributes not the styles of an image
       
  6837 				// It will also block mceItemNoResize items
       
  6838 				Event.add(t.getDoc(), 'controlselect', function(e) {
       
  6839 					var re = t.resizeInfo, cb;
       
  6840 
       
  6841 					e = e.target;
       
  6842 
       
  6843 					if (re)
       
  6844 						Event.remove(re.node, re.ev, re.cb);
       
  6845 
       
  6846 					if (!t.dom.hasClass(e, 'mceItemNoResize')) {
       
  6847 						ev = 'resizeend';
       
  6848 						cb = Event.add(e, ev, function(e) {
       
  6849 							var v;
       
  6850 
       
  6851 							e = e.target;
       
  6852 
       
  6853 							if (v = t.dom.getStyle(e, 'width')) {
       
  6854 								t.dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));
       
  6855 								t.dom.setStyle(e, 'width', '');
       
  6856 							}
       
  6857 
       
  6858 							if (v = t.dom.getStyle(e, 'height')) {
       
  6859 								t.dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));
       
  6860 								t.dom.setStyle(e, 'height', '');
       
  6861 							}
       
  6862 						});
       
  6863 					} else {
       
  6864 						ev = 'resizestart';
       
  6865 						cb = Event.add(e, 'resizestart', Event.cancel, Event);
       
  6866 					}
       
  6867 
       
  6868 					re = t.resizeInfo = {
       
  6869 						node : e,
       
  6870 						ev : ev,
       
  6871 						cb : cb
       
  6872 					};
       
  6873 				});
       
  6874 
       
  6875 				t.onKeyDown.add(function(ed, e) {
       
  6876 					switch (e.keyCode) {
       
  6877 						case 8:
       
  6878 							// Fix IE control + backspace browser bug
       
  6879 							if (t.selection.getRng().item) {
       
  6880 								t.selection.getRng().item(0).removeNode();
       
  6881 								return Event.cancel(e);
       
  6882 							}
       
  6883 					}
       
  6884 				});
       
  6885 			}
       
  6886 
       
  6887 			// Add custom undo/redo handlers
       
  6888 			if (s.custom_undo_redo) {
       
  6889 				function addUndo() {
       
  6890 					t.undoManager.typing = 0;
       
  6891 					t.undoManager.add();
       
  6892 				};
       
  6893 
       
  6894 				// Add undo level on editor blur
       
  6895 				if (tinymce.isIE) {
       
  6896 					Event.add(t.getWin(), 'blur', function(e) {
       
  6897 						var n;
       
  6898 
       
  6899 						// Check added for fullscreen bug
       
  6900 						if (t.selection) {
       
  6901 							n = t.selection.getNode();
       
  6902 
       
  6903 							// Add undo level is selection was lost to another document
       
  6904 							if (!t.removed && n.ownerDocument && n.ownerDocument != t.getDoc())
       
  6905 								addUndo();
       
  6906 						}
       
  6907 					});
       
  6908 				} else {
       
  6909 					Event.add(t.getDoc(), 'blur', function() {
       
  6910 						if (!t.removed)
       
  6911 							addUndo();
       
  6912 					});
       
  6913 				}
       
  6914 
       
  6915 				t.onMouseDown.add(addUndo);
       
  6916 
       
  6917 				t.onKeyUp.add(function(ed, e) {
       
  6918 					if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey) {
       
  6919 						t.undoManager.typing = 0;
       
  6920 						t.undoManager.add();
       
  6921 					}
       
  6922 				});
       
  6923 
       
  6924 				t.onKeyDown.add(function(ed, e) {
       
  6925 					// Is caracter positon keys
       
  6926 					if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) {
       
  6927 						if (t.undoManager.typing) {
       
  6928 							t.undoManager.add();
       
  6929 							t.undoManager.typing = 0;
       
  6930 						}
       
  6931 
       
  6932 						return;
       
  6933 					}
       
  6934 
       
  6935 					if (!t.undoManager.typing) {
       
  6936 						t.undoManager.add();
       
  6937 						t.undoManager.typing = 1;
       
  6938 					}
       
  6939 				});
       
  6940 			}
       
  6941 		},
       
  6942 
       
  6943 		_destroy : function() {
       
  6944 			var t = this;
       
  6945 
       
  6946 			if (t.formElement) {
       
  6947 				t.formElement.submit = t.formElement._mceOldSubmit;
       
  6948 				t.formElement._mceOldSubmit = null;
       
  6949 			}
       
  6950 
       
  6951 			t.contentAreaContainer = t.formElement = t.container = t.contentDocument = t.contentWindow = null;
       
  6952 
       
  6953 			if (t.selection)
       
  6954 				t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null;
       
  6955 
       
  6956 			t.destroyed = 1;
       
  6957 		},
       
  6958 
       
  6959 		_convertInlineElements : function() {
       
  6960 			var t = this, s = t.settings, dom = t.dom;
       
  6961 
       
  6962 			t.onPreProcess.add(function(ed, o) {
       
  6963 				if (!s.inline_styles)
       
  6964 					return;
       
  6965 
       
  6966 				if (o.get) {
       
  6967 					each(t.dom.select('table,u,strike', o.node), function(n) {
       
  6968 						switch (n.nodeName) {
       
  6969 							case 'TABLE':
       
  6970 								if (v = dom.getAttrib(n, 'height')) {
       
  6971 									dom.setStyle(n, 'height', v);
       
  6972 									dom.setAttrib(n, 'height', '');
       
  6973 								}
       
  6974 								break;
       
  6975 
       
  6976 							case 'U':
       
  6977 								dom.replace(dom.create('span', {style : 'text-decoration: underline;'}), n, 1);
       
  6978 								break;
       
  6979 
       
  6980 							case 'STRIKE':
       
  6981 								dom.replace(dom.create('span', {style : 'text-decoration: line-through;'}), n, 1);
       
  6982 								break;
       
  6983 						}
       
  6984 					});
       
  6985 				} else if (o.set) {
       
  6986 					each(t.dom.select('table,span', o.node), function(n) {
       
  6987 						if (n.nodeName == 'TABLE') {
       
  6988 							if (v = dom.getStyle(n, 'height'))
       
  6989 								dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));
       
  6990 						} else {
       
  6991 							// Convert spans to elements
       
  6992 							if (n.style.textDecoration == 'underline')
       
  6993 								dom.replace(dom.create('u'), n, 1);
       
  6994 							else if (n.style.textDecoration == 'strikethrough')
       
  6995 								dom.replace(dom.create('strike'), n, 1);
       
  6996 						}
       
  6997 					});
       
  6998 				}
       
  6999 			});
       
  7000 		},
       
  7001 
       
  7002 		_convertFonts : function() {
       
  7003 			var t = this, s = t.settings, dom = t.dom, sl, cl, fz, fzn, v, i;
       
  7004 
       
  7005 			// Font pt values and font size names
       
  7006 			fz = [8, 10, 12, 14, 18, 24, 36];
       
  7007 			fzn = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large'];
       
  7008 
       
  7009 			if (sl = s.font_size_style_values)
       
  7010 				sl = sl.split(',');
       
  7011 
       
  7012 			if (cl = s.font_size_classes)
       
  7013 				cl = cl.split(',');
       
  7014 
       
  7015 			t.onPreProcess.add(function(ed, o) {
       
  7016 				if (!s.inline_styles)
       
  7017 					return;
       
  7018 
       
  7019 				if (o.set) {
       
  7020 					// Convert spans to fonts on non WebKit browsers
       
  7021 					if (tinymce.isWebKit)
       
  7022 						return;
       
  7023 
       
  7024 					each(t.dom.select('span', o.node), function(n) {
       
  7025 						var f = dom.create('font', {
       
  7026 							color : dom.toHex(dom.getStyle(n, 'color')),
       
  7027 							face : dom.getStyle(n, 'fontFamily')
       
  7028 						});
       
  7029 
       
  7030 						if (sl) {
       
  7031 							i = inArray(sl, dom.getStyle(n, 'fontSize'));
       
  7032 
       
  7033 							if (i != -1)
       
  7034 								dom.setAttrib(f, 'size', '' + (i + 1 || 1));
       
  7035 						} else if (cl) {
       
  7036 							i = inArray(cl, dom.getAttrib(n, 'class'));
       
  7037 
       
  7038 							v = dom.getStyle(n, 'fontSize');
       
  7039 
       
  7040 							if (i == -1 && v.indexOf('pt') > 0)
       
  7041 								i = inArray(fz, parseInt(v));
       
  7042 
       
  7043 							if (i == -1)
       
  7044 								i = inArray(fzn, v);
       
  7045 
       
  7046 							if (i != -1)
       
  7047 								dom.setAttrib(f, 'size', '' + (i + 1 || 1));
       
  7048 						}
       
  7049 
       
  7050 						if (f.color || f.face || f.size)
       
  7051 							dom.replace(f, n, 1);
       
  7052 					});
       
  7053 				} else if (o.get) {
       
  7054 					each(t.dom.select('font', o.node), function(n) {
       
  7055 						var sp = dom.create('span', {
       
  7056 							style : {
       
  7057 								fontFamily : dom.getAttrib(n, 'face'),
       
  7058 								color : dom.getAttrib(n, 'color'),
       
  7059 								backgroundColor : n.style.backgroundColor
       
  7060 							}
       
  7061 						});
       
  7062 
       
  7063 						if (n.size) {
       
  7064 							if (sl)
       
  7065 								dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]);
       
  7066 							else
       
  7067 								dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);
       
  7068 						}
       
  7069 
       
  7070 						dom.replace(sp, n, 1);
       
  7071 					});
       
  7072 				}
       
  7073 			});
  6416 		}
  7074 		}
  6417 
  7075 
  6418 		if (tinyMCE.isRealIE) {
  7076 		});
  6419 			if (bookmark.rng) {
  7077 })();
       
  7078 
       
  7079 /* file:jscripts/tiny_mce/classes/EditorCommands.js */
       
  7080 
       
  7081 (function() {
       
  7082 	var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;
       
  7083 
       
  7084 	tinymce.create('tinymce.EditorCommands', {
       
  7085 		EditorCommands : function(ed) {
       
  7086 			this.editor = ed;
       
  7087 		},
       
  7088 
       
  7089 		execCommand : function(cmd, ui, val) {
       
  7090 			var t = this, ed = t.editor, f;
       
  7091 
       
  7092 			switch (cmd) {
       
  7093 				case 'Cut':
       
  7094 				case 'Copy':
       
  7095 				case 'Paste':
       
  7096 					try {
       
  7097 						ed.getDoc().execCommand(cmd, ui, val);
       
  7098 					} catch (ex) {
       
  7099 						if (isGecko) {
       
  7100 							ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {
       
  7101 								if (s)
       
  7102 									window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
       
  7103 							});
       
  7104 						} else
       
  7105 							ed.windowManager.alert(ed.getLang('clipboard_no_support'));
       
  7106 					}
       
  7107 
       
  7108 					return true;
       
  7109 
       
  7110 				// Ignore these
       
  7111 				case 'mceResetDesignMode':
       
  7112 				case 'mceBeginUndoLevel':
       
  7113 					return true;
       
  7114 
       
  7115 				// Ignore these
       
  7116 				case 'unlink':
       
  7117 					t.UnLink();
       
  7118 					return true;
       
  7119 
       
  7120 				// Bundle these together
       
  7121 				case 'JustifyLeft':
       
  7122 				case 'JustifyCenter':
       
  7123 				case 'JustifyRight':
       
  7124 				case 'JustifyFull':
       
  7125 					t.mceJustify(cmd, cmd.substring(7).toLowerCase());
       
  7126 					return true;
       
  7127 
       
  7128 				case 'mceEndUndoLevel':
       
  7129 				case 'mceAddUndoLevel':
       
  7130 					ed.undoManager.add();
       
  7131 					return true;
       
  7132 
       
  7133 				default:
       
  7134 					f = this[cmd];
       
  7135 
       
  7136 					if (f) {
       
  7137 						f.call(this, ui, val);
       
  7138 						return true;
       
  7139 					}
       
  7140 			}
       
  7141 
       
  7142 			return false;
       
  7143 		},
       
  7144 
       
  7145 		Indent : function() {
       
  7146 			var ed = this.editor, d = ed.dom, s = ed.selection, e;
       
  7147 
       
  7148 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
       
  7149 				each(this._getSelectedBlocks(), function(e) {
       
  7150 					d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + 30) + 'px');
       
  7151 				});
       
  7152 
       
  7153 				return;
       
  7154 			}
       
  7155 
       
  7156 			ed.getDoc().execCommand('Indent', false, null);
       
  7157 
       
  7158 			if (isIE) {
       
  7159 				d.getParent(s.getNode(), function(n) {
       
  7160 					if (n.nodeName == 'BLOCKQUOTE') {
       
  7161 						n.dir = n.style.cssText = '';
       
  7162 					}
       
  7163 				});
       
  7164 			}
       
  7165 		},
       
  7166 
       
  7167 		Outdent : function() {
       
  7168 			var ed = this.editor, d = ed.dom, s = ed.selection, e, v;
       
  7169 
       
  7170 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
       
  7171 				each(this._getSelectedBlocks(), function(e) {
       
  7172 					v = Math.max(0, parseInt(e.style.paddingLeft || 0) - 30);
       
  7173 					d.setStyle(e, 'paddingLeft', v ? v + 'px' : '');
       
  7174 				});
       
  7175 
       
  7176 				return;
       
  7177 			}
       
  7178 
       
  7179 			ed.getDoc().execCommand('Outdent', false, null);
       
  7180 		},
       
  7181 
       
  7182 		mceSetAttribute : function(u, v) {
       
  7183 			var ed = this.editor, d = ed.dom, e;
       
  7184 
       
  7185 			if (e = d.getParent(ed.selection.getNode(), d.isBlock))
       
  7186 				d.setAttrib(e, v.name, v.value);
       
  7187 		},
       
  7188 
       
  7189 		mceSetContent : function(u, v) {
       
  7190 			this.editor.setContent(v);
       
  7191 		},
       
  7192 
       
  7193 		mceToggleVisualAid : function() {
       
  7194 			var ed = this.editor;
       
  7195 
       
  7196 			ed.hasVisual = !ed.hasVisual;
       
  7197 			ed.addVisual();
       
  7198 		},
       
  7199 
       
  7200 		mceReplaceContent : function(u, v) {
       
  7201 			var s = this.editor.selection;
       
  7202 
       
  7203 			s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'})));
       
  7204 		},
       
  7205 
       
  7206 		mceInsertLink : function(u, v) {
       
  7207 			var ed = this.editor, e = ed.dom.getParent(ed.selection.getNode(), 'A');
       
  7208 
       
  7209 			if (tinymce.is(v, 'string'))
       
  7210 				v = {href : v};
       
  7211 
       
  7212 			function set(e) {
       
  7213 				each(v, function(v, k) {
       
  7214 					ed.dom.setAttrib(e, k, v);
       
  7215 				});
       
  7216 			};
       
  7217 
       
  7218 			if (!e) {
       
  7219 				ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');
       
  7220 				each(ed.dom.select('a'), function(e) {
       
  7221 					if (e.href == 'javascript:mctmp(0);')
       
  7222 						set(e);
       
  7223 				});
       
  7224 			} else {
       
  7225 				if (v.href)
       
  7226 					set(e);
       
  7227 				else
       
  7228 					ed.dom.remove(e, 1);
       
  7229 			}
       
  7230 		},
       
  7231 
       
  7232 		UnLink : function() {
       
  7233 			var ed = this.editor, s = ed.selection;
       
  7234 
       
  7235 			if (s.isCollapsed())
       
  7236 				s.select(s.getNode());
       
  7237 
       
  7238 			ed.getDoc().execCommand('unlink', false, null);
       
  7239 			s.collapse(0);
       
  7240 		},
       
  7241 
       
  7242 		FontName : function(u, v) {
       
  7243 			var t = this, ed = t.editor, s = ed.selection, e;
       
  7244 
       
  7245 			if (!v) {
       
  7246 				if (s.isCollapsed())
       
  7247 					s.select(s.getNode());
       
  7248 
       
  7249 				t.RemoveFormat();
       
  7250 			} else
       
  7251 				ed.getDoc().execCommand('FontName', false, v);
       
  7252 		},
       
  7253 
       
  7254 		queryCommandValue : function(c) {
       
  7255 			var f = this['queryValue' + c];
       
  7256 
       
  7257 			if (f)
       
  7258 				return f.call(this, c);
       
  7259 
       
  7260 			return false;
       
  7261 		},
       
  7262 
       
  7263 		queryCommandState : function(cmd) {
       
  7264 			var f;
       
  7265 
       
  7266 			switch (cmd) {
       
  7267 				// Bundle these together
       
  7268 				case 'JustifyLeft':
       
  7269 				case 'JustifyCenter':
       
  7270 				case 'JustifyRight':
       
  7271 				case 'JustifyFull':
       
  7272 					return this.queryStateJustify(cmd, cmd.substring(7).toLowerCase());
       
  7273 
       
  7274 				default:
       
  7275 					if (f = this['queryState' + cmd])
       
  7276 						return f.call(this, cmd);
       
  7277 			}
       
  7278 
       
  7279 			return -1;
       
  7280 		},
       
  7281 
       
  7282 		queryValueFontSize : function() {
       
  7283 			var ed = this.editor, v = 0, p;
       
  7284 
       
  7285 			if (isOpera || isWebKit) {
       
  7286 				if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))
       
  7287 					v = p.size;
       
  7288 
       
  7289 				return v;
       
  7290 			}
       
  7291 
       
  7292 			return ed.getDoc().queryCommandValue('FontSize');
       
  7293 		},
       
  7294 
       
  7295 		queryValueFontName : function() {
       
  7296 			var ed = this.editor, v = 0, p;
       
  7297 
       
  7298 			if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))
       
  7299 				v = p.face;
       
  7300 
       
  7301 			if (!v)
       
  7302 				v = ed.getDoc().queryCommandValue('FontName');
       
  7303 
       
  7304 			return v;
       
  7305 		},
       
  7306 
       
  7307 		mceJustify : function(c, v) {
       
  7308 			var ed = this.editor, se = ed.selection, n = se.getNode(), nn = n.nodeName, bl, nb, dom = ed.dom, rm;
       
  7309 
       
  7310 			if (ed.settings.inline_styles && this.queryStateJustify(c, v))
       
  7311 				rm = 1;
       
  7312 
       
  7313 			bl = dom.getParent(n, ed.dom.isBlock);
       
  7314 
       
  7315 			if (nn == 'IMG') {
       
  7316 				if (v == 'full')
       
  7317 					return;
       
  7318 
       
  7319 				if (rm) {
       
  7320 					dom.setStyle(n, 'float', '');
       
  7321 					this.mceRepaint();
       
  7322 					return;
       
  7323 				}
       
  7324 
       
  7325 				if (v == 'center') {
       
  7326 					if (!bl || bl.childNodes.length > 1) {
       
  7327 						nb = dom.create('p');
       
  7328 						nb.appendChild(n.cloneNode(false));
       
  7329 
       
  7330 						if (bl)
       
  7331 							dom.insertAfter(nb, bl);
       
  7332 						else
       
  7333 							dom.insertAfter(nb, n);
       
  7334 
       
  7335 						dom.remove(n);
       
  7336 						n = nb.firstChild;
       
  7337 						bl = nb;
       
  7338 					}
       
  7339 
       
  7340 					dom.setStyle(bl, 'textAlign', v);
       
  7341 					dom.setStyle(n, 'float', '');
       
  7342 				} else
       
  7343 					dom.setStyle(n, 'float', v);
       
  7344 
       
  7345 				this.mceRepaint();
       
  7346 				return;
       
  7347 			}
       
  7348 
       
  7349 			// Handle the alignment outselfs, less quirks in all browsers
       
  7350 			if (ed.settings.inline_styles && ed.settings.forced_root_block) {
       
  7351 				if (rm)
       
  7352 					v = '';
       
  7353 
       
  7354 				each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {
       
  7355 					dom.setAttrib(e, 'align', '');
       
  7356 					dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);
       
  7357 				});
       
  7358 
       
  7359 				return;
       
  7360 			} else if (!rm)
       
  7361 				ed.getDoc().execCommand(c, false, null);
       
  7362 
       
  7363 			if (ed.settings.inline_styles) {
       
  7364 				if (rm) {
       
  7365 					dom.getParent(ed.selection.getNode(), function(n) {
       
  7366 						if (n.style && n.style.textAlign)
       
  7367 							dom.setStyle(n, 'textAlign', '');
       
  7368 					});
       
  7369 
       
  7370 					return;
       
  7371 				}
       
  7372 
       
  7373 				each(dom.select('*'), function(n) {
       
  7374 					var v = n.align;
       
  7375 
       
  7376 					if (v) {
       
  7377 						if (v == 'full')
       
  7378 							v = 'justify';
       
  7379 
       
  7380 						dom.setStyle(n, 'textAlign', v);
       
  7381 						dom.setAttrib(n, 'align', '');
       
  7382 					}
       
  7383 				});
       
  7384 			}
       
  7385 		},
       
  7386 
       
  7387 		mceSetCSSClass : function(u, v) {
       
  7388 			this.mceSetStyleInfo(0, {command : 'setattrib', name : 'class', value : v});
       
  7389 		},
       
  7390 
       
  7391 		getSelectedElement : function() {
       
  7392 			var t = this, ed = t.editor, dom = ed.dom, se = ed.selection, r = se.getRng(), r1, r2, sc, ec, so, eo, e, sp, ep, re;
       
  7393 
       
  7394 			if (se.isCollapsed() || r.item)
       
  7395 				return se.getNode();
       
  7396 
       
  7397 			// Setup regexp
       
  7398 			re = ed.settings.merge_styles_invalid_parents;
       
  7399 			if (tinymce.is(re, 'string'))
       
  7400 				re = new RegExp(re, 'i');
       
  7401 
       
  7402 			if (isIE) {
       
  7403 				r1 = r.duplicate();
       
  7404 				r1.collapse(true);
       
  7405 				sc = r1.parentElement();
       
  7406 
       
  7407 				r2 = r.duplicate();
       
  7408 				r2.collapse(false);
       
  7409 				ec = r2.parentElement();
       
  7410 
       
  7411 				if (sc != ec) {
       
  7412 					r1.move('character', 1);
       
  7413 					sc = r1.parentElement();
       
  7414 				}
       
  7415 
       
  7416 				if (sc == ec) {
       
  7417 					r1 = r.duplicate();
       
  7418 					r1.moveToElementText(sc);
       
  7419 
       
  7420 					if (r1.compareEndPoints('StartToStart', r) == 0 && r1.compareEndPoints('EndToEnd', r) == 0)
       
  7421 						return re && re.test(sc.nodeName) ? null : sc;
       
  7422 				}
       
  7423 			} else {
       
  7424 				function getParent(n) {
       
  7425 					return dom.getParent(n, function(n) {return n.nodeType == 1;});
       
  7426 				};
       
  7427 
       
  7428 				sc = r.startContainer;
       
  7429 				ec = r.endContainer;
       
  7430 				so = r.startOffset;
       
  7431 				eo = r.endOffset;
       
  7432 
       
  7433 				if (!r.collapsed) {
       
  7434 					if (sc == ec) {
       
  7435 						if (so - eo < 2) {
       
  7436 							if (sc.hasChildNodes()) {
       
  7437 								sp = sc.childNodes[so];
       
  7438 								return re && re.test(sp.nodeName) ? null : sp;
       
  7439 							}
       
  7440 						}
       
  7441 					}
       
  7442 				}
       
  7443 
       
  7444 				if (sc.nodeType != 3 || ec.nodeType != 3)
       
  7445 					return null;
       
  7446 
       
  7447 				if (so == 0) {
       
  7448 					sp = getParent(sc);
       
  7449 
       
  7450 					if (sp && sp.firstChild != sc)
       
  7451 						sp = null;
       
  7452 				}
       
  7453 
       
  7454 				if (so == sc.nodeValue.length) {
       
  7455 					e = sc.nextSibling;
       
  7456 
       
  7457 					if (e && e.nodeType == 1)
       
  7458 						sp = sc.nextSibling;
       
  7459 				}
       
  7460 
       
  7461 				if (eo == 0) {
       
  7462 					e = ec.previousSibling;
       
  7463 
       
  7464 					if (e && e.nodeType == 1)
       
  7465 						ep = e;
       
  7466 				}
       
  7467 
       
  7468 				if (eo == ec.nodeValue.length) {
       
  7469 					ep = getParent(ec);
       
  7470 
       
  7471 					if (ep && ep.lastChild != ec)
       
  7472 						ep = null;
       
  7473 				}
       
  7474 
       
  7475 				// Same element
       
  7476 				if (sp == ep)
       
  7477 					return re && sp && re.test(sp.nodeName) ? null : sp;
       
  7478 			}
       
  7479 
       
  7480 			return null;
       
  7481 		},
       
  7482 
       
  7483 		InsertHorizontalRule : function() {
       
  7484 			// Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");
       
  7485 			if (isGecko || isIE)
       
  7486 				this.editor.selection.setContent('<hr />');
       
  7487 			else
       
  7488 				this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');
       
  7489 		},
       
  7490 
       
  7491 		RemoveFormat : function() {
       
  7492 			var t = this, ed = t.editor, s = ed.selection, b;
       
  7493 
       
  7494 			// Safari breaks tables
       
  7495 			if (isWebKit)
       
  7496 				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'});
       
  7497 			else
       
  7498 				ed.getDoc().execCommand('RemoveFormat', false, null);
       
  7499 
       
  7500 			t.mceSetStyleInfo(0, {command : 'removeformat'});
       
  7501 			ed.addVisual();
       
  7502 		},
       
  7503 
       
  7504 		mceSetStyleInfo : function(u, v) {
       
  7505 			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;
       
  7506 
       
  7507 			function set(n, e) {
       
  7508 				if (n.nodeType == 1) {
       
  7509 					switch (v.command) {
       
  7510 						case 'setattrib':
       
  7511 							return dom.setAttrib(n, v.name, v.value);
       
  7512 
       
  7513 						case 'setstyle':
       
  7514 							return dom.setStyle(n, v.name, v.value);
       
  7515 
       
  7516 						case 'removeformat':
       
  7517 							return dom.setAttrib(n, 'class', '');
       
  7518 					}
       
  7519 				}
       
  7520 			};
       
  7521 
       
  7522 			// Setup regexp
       
  7523 			re = ed.settings.merge_styles_invalid_parents;
       
  7524 			if (tinymce.is(re, 'string'))
       
  7525 				re = new RegExp(re, 'i');
       
  7526 
       
  7527 			// Set style info on selected element
       
  7528 			if (e = t.getSelectedElement())
       
  7529 				set(e, 1);
       
  7530 			else {
       
  7531 				// Generate wrappers and set styles on them
       
  7532 				d.execCommand('FontName', false, '__');
       
  7533 				each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {
       
  7534 					var sp, e;
       
  7535 
       
  7536 					if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {
       
  7537 						sp = dom.create(nn, {mce_new : '1'});
       
  7538 
       
  7539 						set(sp);
       
  7540 
       
  7541 						each (n.childNodes, function(n) {
       
  7542 							sp.appendChild(n.cloneNode(true));
       
  7543 						});
       
  7544 
       
  7545 						dom.replace(sp, n);
       
  7546 					}
       
  7547 				});
       
  7548 			}
       
  7549 
       
  7550 			// Remove wrappers inside new ones
       
  7551 			each(dom.select(nn).reverse(), function(n) {
       
  7552 				var p = n.parentNode;
       
  7553 
       
  7554 				dom.setAttrib(n, 'mce_new', '');
       
  7555 
       
  7556 				// Check if it's an old span in a new wrapper
       
  7557 				if (!dom.getAttrib(n, 'mce_new')) {
       
  7558 					// Find new wrapper
       
  7559 					p = dom.getParent(n, function(n) {
       
  7560 						return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');
       
  7561 					});
       
  7562 
       
  7563 					if (p)
       
  7564 						dom.remove(n, 1);
       
  7565 				}
       
  7566 			});
       
  7567 
       
  7568 			// Merge wrappers with parent wrappers
       
  7569 			each(dom.select(nn).reverse(), function(n) {
       
  7570 				var p = n.parentNode;
       
  7571 
       
  7572 				if (!p)
       
  7573 					return;
       
  7574 
       
  7575 				// Has parent of the same type and only child
       
  7576 				if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1)
       
  7577 					return dom.remove(p, 1);
       
  7578 
       
  7579 				// Has parent that is more suitable to have the class and only child
       
  7580 				if (n.nodeType == 1 && (!re || !re.test(p.nodeName)) && p.childNodes.length == 1) {
       
  7581 					set(p); // Set style info on parent instead
       
  7582 					dom.setAttrib(n, 'class', '');
       
  7583 				}
       
  7584 			});
       
  7585 
       
  7586 			// Remove empty wrappers
       
  7587 			each(dom.select(nn).reverse(), function(n) {
       
  7588 				if (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style'))
       
  7589 					return dom.remove(n, 1);
       
  7590 			});
       
  7591 
       
  7592 			s.moveToBookmark(b);
       
  7593 		},
       
  7594 
       
  7595 		queryStateJustify : function(c, v) {
       
  7596 			var ed = this.editor, n = ed.selection.getNode(), dom = ed.dom;
       
  7597 
       
  7598 			if (n && n.nodeName == 'IMG')
       
  7599 				return dom.getStyle(n, 'float') == v;
       
  7600 
       
  7601 			n = dom.getParent(ed.selection.getStart(), function(n) {
       
  7602 				return n.nodeType == 1 && n.style.textAlign;
       
  7603 			});
       
  7604 
       
  7605 			if (v == 'full')
       
  7606 				v = 'justify';
       
  7607 
       
  7608 			if (ed.settings.inline_styles)
       
  7609 				return (n && n.style.textAlign == v);
       
  7610 
       
  7611 			return ed.getDoc().queryCommandState(c);
       
  7612 		},
       
  7613 
       
  7614 		HiliteColor : function(ui, val) {
       
  7615 			var t = this, ed = t.editor, d = ed.getDoc();
       
  7616 
       
  7617 			function set(s) {
       
  7618 				if (!isGecko)
       
  7619 					return;
       
  7620 
  6420 				try {
  7621 				try {
  6421 					bookmark.rng.select();
  7622 					// Try new Gecko method
       
  7623 					d.execCommand("styleWithCSS", 0, s);
       
  7624 				} catch (ex) {
       
  7625 					// Use old
       
  7626 					d.execCommand("useCSS", 0, !s);
       
  7627 				}
       
  7628 			};
       
  7629 
       
  7630 			if (isGecko || isOpera) {
       
  7631 				set(true);
       
  7632 				d.execCommand('hilitecolor', false, val);
       
  7633 				set(false);
       
  7634 			} else
       
  7635 				d.execCommand('BackColor', false, val);
       
  7636 		},
       
  7637 
       
  7638 		Undo : function() {
       
  7639 			var ed = this.editor;
       
  7640 
       
  7641 			if (ed.settings.custom_undo_redo) {
       
  7642 				ed.undoManager.undo();
       
  7643 				ed.nodeChanged();
       
  7644 			} else
       
  7645 				ed.getDoc().execCommand('Undo', false, null);
       
  7646 		},
       
  7647 
       
  7648 		Redo : function() {
       
  7649 			var ed = this.editor;
       
  7650 
       
  7651 			if (ed.settings.custom_undo_redo) {
       
  7652 				ed.undoManager.redo();
       
  7653 				ed.nodeChanged();
       
  7654 			} else
       
  7655 				ed.getDoc().execCommand('Redo', false, null);
       
  7656 		},
       
  7657 
       
  7658 		FormatBlock : function(ui, val) {
       
  7659 			var t = this, ed = t.editor;
       
  7660 
       
  7661 			val = ed.settings.forced_root_block ? (val || '<p>') : val;
       
  7662 			t.mceRemoveNode();
       
  7663 
       
  7664 			if (val.indexOf('<') == -1)
       
  7665 				val = '<' + val + '>';
       
  7666 
       
  7667 			if (tinymce.isGecko)
       
  7668 				val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1');
       
  7669 
       
  7670 			ed.getDoc().execCommand('FormatBlock', false, val);
       
  7671 		},
       
  7672 
       
  7673 		mceCleanup : function() {
       
  7674 			var ed = this.editor, s = ed.selection, b = s.getBookmark();
       
  7675 			ed.setContent(ed.getContent());
       
  7676 			s.moveToBookmark(b);
       
  7677 		},
       
  7678 
       
  7679 		mceRemoveNode : function(ui, val) {
       
  7680 			var ed = this.editor, s = ed.selection, b, n = val || s.getNode();
       
  7681 
       
  7682 			// Make sure that the body node isn't removed
       
  7683 			if (n == ed.getBody())
       
  7684 				return;
       
  7685 
       
  7686 			b = s.getBookmark();
       
  7687 			ed.dom.remove(n, 1);
       
  7688 			s.moveToBookmark(b);
       
  7689 			ed.nodeChanged();
       
  7690 		},
       
  7691 
       
  7692 		mceSelectNodeDepth : function(ui, val) {
       
  7693 			var ed = this.editor, s = ed.selection, c = 0;
       
  7694 
       
  7695 			ed.dom.getParent(s.getNode(), function(n) {
       
  7696 				if (n.nodeType == 1 && c++ == val) {
       
  7697 					s.select(n);
       
  7698 					ed.nodeChanged();
       
  7699 					return false;
       
  7700 				}
       
  7701 			}, ed.getBody());
       
  7702 		},
       
  7703 
       
  7704 		mceSelectNode : function(u, v) {
       
  7705 			this.editor.selection.select(v);
       
  7706 		},
       
  7707 
       
  7708 		mceInsertContent : function(ui, val) {
       
  7709 			this.editor.selection.setContent(val);
       
  7710 		},
       
  7711 
       
  7712 		mceInsertRawHTML : function(ui, val) {
       
  7713 			var ed = this.editor;
       
  7714 
       
  7715 			ed.execCommand('mceInsertContent', false, 'tiny_mce_marker');
       
  7716 			ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val));
       
  7717 		},
       
  7718 
       
  7719 		mceRepaint : function() {
       
  7720 			var s, b, e = this.editor;
       
  7721 
       
  7722 			if (tinymce.isGecko) {
       
  7723 				try {
       
  7724 					s = e.selection;
       
  7725 					b = s.getBookmark(true);
       
  7726 					s.getSel().selectAllChildren(e.getBody());
       
  7727 					s.collapse(true);
       
  7728 					s.moveToBookmark(b);
  6422 				} catch (ex) {
  7729 				} catch (ex) {
  6423 					// Ignore
  7730 					// Ignore
  6424 				}
  7731 				}
  6425 
  7732 			}
       
  7733 		},
       
  7734 
       
  7735 		queryStateUnderline : function() {
       
  7736 			var ed = this.editor, n;
       
  7737 
       
  7738 			if (n && n.nodeName == 'A')
       
  7739 				return false;
       
  7740 
       
  7741 			return ed.getDoc().queryCommandState('Underline');
       
  7742 		},
       
  7743 
       
  7744 		queryStateOutdent : function() {
       
  7745 			var ed = this.editor, n;
       
  7746 
       
  7747 			if (ed.settings.inline_styles) {
       
  7748 				if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)
       
  7749 					return true;
       
  7750 
       
  7751 				if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)
       
  7752 					return true;
       
  7753 			} else
       
  7754 				return !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE');
       
  7755 
       
  7756 			return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList();
       
  7757 		},
       
  7758 
       
  7759 		queryStateInsertUnorderedList : function() {
       
  7760 			return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL');
       
  7761 		},
       
  7762 
       
  7763 		queryStateInsertOrderedList : function() {
       
  7764 			return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL');
       
  7765 		},
       
  7766 
       
  7767 		queryStatemceBlockQuote : function() {
       
  7768 			return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});
       
  7769 		},
       
  7770 
       
  7771 		mceBlockQuote : function() {
       
  7772 			var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;
       
  7773 
       
  7774 			function findBQ(e) {
       
  7775 				return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
       
  7776 			};
       
  7777 
       
  7778 			// Remove blockquote(s)
       
  7779 			if (findBQ(s.getStart())) {
       
  7780 				each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {
       
  7781 					// Found BQ lets remove it
       
  7782 					if (e.nodeName == 'BLOCKQUOTE')
       
  7783 						dom.remove(e, 1);
       
  7784 				});
       
  7785 
       
  7786 				t.editor.selection.moveToBookmark(b);
       
  7787 				return;
       
  7788 			}
       
  7789 
       
  7790 			each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {
       
  7791 				var n;
       
  7792 
       
  7793 				// Found existing BQ add to this one
       
  7794 				if (e.nodeName == 'BLOCKQUOTE' && !bq) {
       
  7795 					bq = e;
       
  7796 					return;
       
  7797 				}
       
  7798 
       
  7799 				// No BQ found, create one
       
  7800 				if (!bq) {
       
  7801 					bq = dom.create('blockquote');
       
  7802 					e.parentNode.insertBefore(bq, e);
       
  7803 				}
       
  7804 
       
  7805 				// Add children from existing BQ
       
  7806 				if (e.nodeName == 'BLOCKQUOTE' && bq) {
       
  7807 					n = e.firstChild;
       
  7808 
       
  7809 					while (n) {
       
  7810 						bq.appendChild(n.cloneNode(true));
       
  7811 						n = n.nextSibling;
       
  7812 					}
       
  7813 
       
  7814 					dom.remove(e);
       
  7815 
       
  7816 					return;
       
  7817 				}
       
  7818 
       
  7819 				// Add non BQ element to BQ
       
  7820 				bq.appendChild(dom.remove(e));
       
  7821 			});
       
  7822 
       
  7823 			t.editor.selection.moveToBookmark(b);
       
  7824 		},
       
  7825 
       
  7826 		_getSelectedBlocks : function(st, en) {
       
  7827 			var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];
       
  7828 
       
  7829 			sb = dom.getParent(st || s.getStart(), dom.isBlock);
       
  7830 			eb = dom.getParent(en || s.getEnd(), dom.isBlock);
       
  7831 
       
  7832 			if (sb)
       
  7833 				bl.push(sb);
       
  7834 
       
  7835 			if (sb && eb && sb != eb) {
       
  7836 				n = sb;
       
  7837 
       
  7838 				while ((n = n.nextSibling) && n != eb) {
       
  7839 					if (dom.isBlock(n))
       
  7840 						bl.push(n);
       
  7841 				}
       
  7842 			}
       
  7843 
       
  7844 			if (eb && sb != eb)
       
  7845 				bl.push(eb);
       
  7846 
       
  7847 			return bl;
       
  7848 		}
       
  7849 	});
       
  7850 })();
       
  7851 
       
  7852 
       
  7853 /* file:jscripts/tiny_mce/classes/UndoManager.js */
       
  7854 
       
  7855 tinymce.create('tinymce.UndoManager', {
       
  7856 	index : 0,
       
  7857 	data : null,
       
  7858 	typing : 0,
       
  7859 
       
  7860 	UndoManager : function(ed) {
       
  7861 		var t = this, Dispatcher = tinymce.util.Dispatcher;
       
  7862 
       
  7863 		t.editor = ed;
       
  7864 		t.data = [];
       
  7865 		t.onAdd = new Dispatcher(this);
       
  7866 		t.onUndo = new Dispatcher(this);
       
  7867 		t.onRedo = new Dispatcher(this);
       
  7868 	},
       
  7869 
       
  7870 	add : function(l) {
       
  7871 		var t = this, i, ed = t.editor, b, s = ed.settings;
       
  7872 
       
  7873 		l = l || {};
       
  7874 		l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
       
  7875 
       
  7876 		// Add undo level if needed
       
  7877 		l.content = l.content.replace(/^\s*|\s*$/g, '');
       
  7878 		if (!l.initial && l.content == t.data[t.index > 0 ? t.index - 1 : 0].content)
       
  7879 			return null;
       
  7880 
       
  7881 		// Time to compress
       
  7882 		if (s.custom_undo_redo_levels) {
       
  7883 			if (t.data.length > s.custom_undo_redo_levels) {
       
  7884 				for (i = 0; i < t.data.length - 1; i++)
       
  7885 					t.data[i] = t.data[i + 1];
       
  7886 
       
  7887 				t.data.length--;
       
  7888 				t.index = t.data.length;
       
  7889 			}
       
  7890 		}
       
  7891 
       
  7892 		if (s.custom_undo_redo_restore_selection)
       
  7893 			l.bookmark = b = l.bookmark || ed.selection.getBookmark();
       
  7894 
       
  7895 		if (t.index < t.data.length && t.data[t.index].initial)
       
  7896 			t.index++;
       
  7897 
       
  7898 		// Add level
       
  7899 		t.data.length = t.index + 1;
       
  7900 		t.data[t.index++] = l;
       
  7901 
       
  7902 		if (l.initial)
       
  7903 			t.index = 0;
       
  7904 
       
  7905 		// Set initial bookmark use first real undo level
       
  7906 		if (t.data.length == 2 && t.data[0].initial)
       
  7907 			t.data[0].bookmark = b;
       
  7908 
       
  7909 		t.onAdd.dispatch(t, l);
       
  7910 
       
  7911 		//console.dir(t.data);
       
  7912 
       
  7913 		return l;
       
  7914 	},
       
  7915 
       
  7916 	undo : function() {
       
  7917 		var t = this, ed = t.editor, l = l, i;
       
  7918 
       
  7919 		if (t.typing) {
       
  7920 			t.add();
       
  7921 			t.typing = 0;
       
  7922 		}
       
  7923 
       
  7924 		if (t.index > 0) {
       
  7925 			// If undo on last index then take snapshot
       
  7926 			if (t.index == t.data.length && t.index > 1) {
       
  7927 				i = t.index;
       
  7928 				t.typing = 0;
       
  7929 
       
  7930 				if (!t.add())
       
  7931 					t.index = i;
       
  7932 
       
  7933 				--t.index;
       
  7934 			}
       
  7935 
       
  7936 			l = t.data[--t.index];
       
  7937 			ed.setContent(l.content, {format : 'raw'});
       
  7938 			ed.selection.moveToBookmark(l.bookmark);
       
  7939 
       
  7940 			t.onUndo.dispatch(t, l);
       
  7941 		}
       
  7942 
       
  7943 		return l;
       
  7944 	},
       
  7945 
       
  7946 	redo : function() {
       
  7947 		var t = this, ed = t.editor, l = null;
       
  7948 
       
  7949 		if (t.index < t.data.length - 1) {
       
  7950 			l = t.data[++t.index];
       
  7951 			ed.setContent(l.content, {format : 'raw'});
       
  7952 			ed.selection.moveToBookmark(l.bookmark);
       
  7953 
       
  7954 			t.onRedo.dispatch(t, l);
       
  7955 		}
       
  7956 
       
  7957 		return l;
       
  7958 	},
       
  7959 
       
  7960 	clear : function() {
       
  7961 		var t = this;
       
  7962 
       
  7963 		t.data = [];
       
  7964 		t.index = 0;
       
  7965 		t.typing = 0;
       
  7966 		t.add({initial : true});
       
  7967 	},
       
  7968 
       
  7969 	hasUndo : function() {
       
  7970 		return this.index != 0 || this.typing;
       
  7971 	},
       
  7972 
       
  7973 	hasRedo : function() {
       
  7974 		return this.index < this.data.length - 1;
       
  7975 	}
       
  7976 
       
  7977 	});
       
  7978 /* file:jscripts/tiny_mce/classes/ForceBlocks.js */
       
  7979 
       
  7980 (function() {
       
  7981 	// Shorten names
       
  7982 	var Event, isIE, isGecko, isOpera, each, extend;
       
  7983 
       
  7984 	Event = tinymce.dom.Event;
       
  7985 	isIE = tinymce.isIE;
       
  7986 	isGecko = tinymce.isGecko;
       
  7987 	isOpera = tinymce.isOpera;
       
  7988 	each = tinymce.each;
       
  7989 	extend = tinymce.extend;
       
  7990 
       
  7991 	tinymce.create('tinymce.ForceBlocks', {
       
  7992 		ForceBlocks : function(ed) {
       
  7993 			var t = this, s;
       
  7994 
       
  7995 			t.editor = ed;
       
  7996 			t.dom = ed.dom;
       
  7997 
       
  7998 			// Default settings
       
  7999 			t.settings = s = extend({
       
  8000 				element : 'P',
       
  8001 				forced_root_block : 'p',
       
  8002 				force_p_newlines : true
       
  8003 			}, ed.settings);
       
  8004 
       
  8005 			ed.onPreInit.add(t.setup, t);
       
  8006 
       
  8007 			if (!isIE) {
       
  8008 				ed.onSetContent.add(function(ed, o) {
       
  8009 					o.content = o.content.replace(/<p>[\s\u00a0]+<\/p>/g, '<p><br /></p>');
       
  8010 				});
       
  8011 			}
       
  8012 
       
  8013 			ed.onPostProcess.add(function(ed, o) {
       
  8014 				o.content = o.content.replace(/<p><\/p>/g, '<p>\u00a0</p>');
       
  8015 
       
  8016 				// Use BR instead of &nbsp; padded paragraphs
       
  8017 				o.content = o.content.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>\u00a0</p>');
       
  8018 				o.content = o.content.replace(/\s*<br \/>\s*<\/p>/g, '</p>');
       
  8019 			});
       
  8020 
       
  8021 			if (s.forced_root_block) {
       
  8022 				ed.onInit.add(t.forceRoots, t);
       
  8023 				ed.onSetContent.add(t.forceRoots, t);
       
  8024 				ed.onBeforeGetContent.add(t.forceRoots, t);
       
  8025 			}
       
  8026 		},
       
  8027 
       
  8028 		setup : function() {
       
  8029 			var t = this, ed = t.editor, s = t.settings;
       
  8030 
       
  8031 			// Force root blocks when typing and when getting output
       
  8032 			if (s.forced_root_block) {
       
  8033 				ed.onKeyUp.add(t.forceRoots, t);
       
  8034 				ed.onPreProcess.add(t.forceRoots, t);
       
  8035 			}
       
  8036 
       
  8037 			if (s.force_br_newlines) {
       
  8038 				ed.onKeyPress.add(function(ed, e) {
       
  8039 					var n, s = ed.selection;
       
  8040 
       
  8041 					if (e.keyCode == 13) {
       
  8042 						s.setContent('<br id="__" /> ', {format : 'raw'});
       
  8043 						n = ed.dom.get('__');
       
  8044 						n.removeAttribute('id');
       
  8045 						s.select(n);
       
  8046 						s.collapse();
       
  8047 						return Event.cancel(e);
       
  8048 					}
       
  8049 				});
       
  8050 
       
  8051 				return;
       
  8052 			}
       
  8053 
       
  8054 			if (!isIE && s.force_p_newlines) {
       
  8055 				ed.onPreProcess.add(function(ed, o) {
       
  8056 					each(ed.dom.select('br', o.node), function(n) {
       
  8057 						var p = n.parentNode;
       
  8058 
       
  8059 						// Replace <p><br /></p> with <p>&nbsp;</p>
       
  8060 						if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n))
       
  8061 							p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n);
       
  8062 					});
       
  8063 				});
       
  8064 
       
  8065 				ed.onKeyPress.add(function(ed, e) {
       
  8066 					if (e.keyCode == 13 && !e.shiftKey) {
       
  8067 						if (!t.insertPara(e))
       
  8068 							Event.cancel(e);
       
  8069 					}
       
  8070 				});
       
  8071 
       
  8072 				if (isGecko) {
       
  8073 					ed.onKeyDown.add(function(ed, e) {
       
  8074 						if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey)
       
  8075 							t.backspaceDelete(e, e.keyCode == 8);
       
  8076 					});
       
  8077 				}
       
  8078 			}
       
  8079 		},
       
  8080 
       
  8081 		find : function(n, t, s) {
       
  8082 			var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1;
       
  8083 
       
  8084 			while (n = w.nextNode()) {
       
  8085 				c++;
       
  8086 
       
  8087 				// Index by node
       
  8088 				if (t == 0 && n == s)
       
  8089 					return c;
       
  8090 
       
  8091 				// Node by index
       
  8092 				if (t == 1 && c == s)
       
  8093 					return n;
       
  8094 			}
       
  8095 
       
  8096 			return -1;
       
  8097 		},
       
  8098 
       
  8099 		forceRoots : function() {
       
  8100 			var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF;
       
  8101 			var nx, bl, bp, sp, le, nl = b.childNodes, i;
       
  8102 
       
  8103 			// Wrap non blocks into blocks
       
  8104 			for (i = nl.length - 1; i >= 0; i--) {
       
  8105 				nx = nl[i];
       
  8106 
       
  8107 				// Is text or non block element
       
  8108 				if (nx.nodeType == 3 || !t.dom.isBlock(nx)) {
       
  8109 					if (!bl) {
       
  8110 						// Create new block but ignore whitespace
       
  8111 						if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {
       
  8112 							// Store selection
       
  8113 							if (si == -2 && r) {
       
  8114 								if (!isIE) {
       
  8115 									so = r.startOffset;
       
  8116 									eo = r.endOffset;
       
  8117 									si = t.find(b, 0, r.startContainer);
       
  8118 									ei = t.find(b, 0, r.endContainer);
       
  8119 								} else {
       
  8120 									tr = d.body.createTextRange();
       
  8121 									tr.moveToElementText(b);
       
  8122 									tr.collapse(1);
       
  8123 									bp = tr.move('character', c) * -1;
       
  8124 
       
  8125 									tr = r.duplicate();
       
  8126 									tr.collapse(1);
       
  8127 									sp = tr.move('character', c) * -1;
       
  8128 
       
  8129 									tr = r.duplicate();
       
  8130 									tr.collapse(0);
       
  8131 									le = (tr.move('character', c) * -1) - sp;
       
  8132 
       
  8133 									si = sp - bp;
       
  8134 									ei = le;
       
  8135 								}
       
  8136 							}
       
  8137 
       
  8138 							bl = ed.dom.create(t.settings.forced_root_block);
       
  8139 							bl.appendChild(nx.cloneNode(1));
       
  8140 							b.replaceChild(bl, nx);
       
  8141 						}
       
  8142 					} else {
       
  8143 						if (bl.hasChildNodes())
       
  8144 							bl.insertBefore(nx, bl.firstChild);
       
  8145 						else
       
  8146 							bl.appendChild(nx);
       
  8147 					}
       
  8148 				} else
       
  8149 					bl = null; // Time to create new block
       
  8150 			}
       
  8151 
       
  8152 			// Restore selection
       
  8153 			if (si != -2) {
       
  8154 				if (!isIE) {
       
  8155 					bl = d.getElementsByTagName(t.settings.element)[0];
       
  8156 					r = d.createRange();
       
  8157 
       
  8158 					// Select last location or generated block
       
  8159 					if (si != -1)
       
  8160 						r.setStart(t.find(b, 1, si), so);
       
  8161 					else
       
  8162 						r.setStart(bl, 0);
       
  8163 
       
  8164 					// Select last location or generated block
       
  8165 					if (ei != -1)
       
  8166 						r.setEnd(t.find(b, 1, ei), eo);
       
  8167 					else
       
  8168 						r.setEnd(bl, 0);
       
  8169 
       
  8170 					s.removeAllRanges();
       
  8171 					s.addRange(r);
       
  8172 				} else {
       
  8173 					try {
       
  8174 						r = s.createRange();
       
  8175 						r.moveToElementText(b);
       
  8176 						r.collapse(1);
       
  8177 						r.moveStart('character', si);
       
  8178 						r.moveEnd('character', ei);
       
  8179 						r.select();
       
  8180 					} catch (ex) {
       
  8181 						// Ignore
       
  8182 					}
       
  8183 				}
       
  8184 			}
       
  8185 		},
       
  8186 
       
  8187 		getParentBlock : function(n) {
       
  8188 			var d = this.dom;
       
  8189 
       
  8190 			return d.getParent(n, d.isBlock);
       
  8191 		},
       
  8192 
       
  8193 		insertPara : function(e) {
       
  8194 			var t = this, ed = t.editor, d = ed.getDoc(), se = t.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
       
  8195 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n;
       
  8196 
       
  8197 			function isEmpty(n) {
       
  8198 				n = n.innerHTML;
       
  8199 				n = n.replace(/<img|hr|table/g, 'd'); // Keep these
       
  8200 				n = n.replace(/<[^>]+>/g, ''); // Remove all tags
       
  8201 
       
  8202 				return n.replace(/[ \t\r\n]+/g, '') == '';
       
  8203 			};
       
  8204 
       
  8205 			// If root blocks are forced then use Operas default behavior since it's really good
       
  8206 			if (se.forced_root_block && isOpera)
  6426 				return true;
  8207 				return true;
  6427 			}
  8208 
  6428 
  8209 			// Setup before range
  6429 			win.focus();
  8210 			rb = d.createRange();
  6430 
  8211 
  6431 			if (bookmark.tag) {
  8212 			// If is before the first block element and in body, then move it into first block element
  6432 				rng = b.createControlRange();
  8213 			rb.setStart(s.anchorNode, s.anchorOffset);
  6433 
  8214 			rb.collapse(true);
  6434 				nl = b.getElementsByTagName(bookmark.tag);
  8215 
  6435 
  8216 			// Setup after range
  6436 				if (nl.length > bookmark.index) {
  8217 			ra = d.createRange();
  6437 					try {
  8218 
  6438 						rng.addElement(nl[bookmark.index]);
  8219 			// If is before the first block element and in body, then move it into first block element
  6439 					} catch (ex) {
  8220 			ra.setStart(s.focusNode, s.focusOffset);
  6440 						// Might be thrown if the node no longer exists
  8221 			ra.collapse(true);
       
  8222 
       
  8223 			// Setup start/end points
       
  8224 			dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0;
       
  8225 			sn = dir ? s.anchorNode : s.focusNode;
       
  8226 			so = dir ? s.anchorOffset : s.focusOffset;
       
  8227 			en = dir ? s.focusNode : s.anchorNode;
       
  8228 			eo = dir ? s.focusOffset : s.anchorOffset;
       
  8229 
       
  8230 			// If the caret is in an invalid location in FF we need to move it into the first block
       
  8231 			if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) {
       
  8232 				sn = en = sn.firstChild;
       
  8233 				so = eo = 0;
       
  8234 				rb = d.createRange();
       
  8235 				rb.setStart(sn, 0);
       
  8236 				ra = d.createRange();
       
  8237 				ra.setStart(en, 0);
       
  8238 			}
       
  8239 
       
  8240 			// Never use body as start or end node
       
  8241 			sn = sn.nodeName == "BODY" ? sn.firstChild : sn;
       
  8242 			en = en.nodeName == "BODY" ? en.firstChild : en;
       
  8243 
       
  8244 			// Get start and end blocks
       
  8245 			sb = t.getParentBlock(sn);
       
  8246 			eb = t.getParentBlock(en);
       
  8247 			bn = sb ? sb.nodeName : se.element; // Get block name to create
       
  8248 
       
  8249 			// Return inside list use default browser behavior
       
  8250 			if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))
       
  8251 				return true;
       
  8252 
       
  8253 			// If caption or absolute layers then always generate new blocks within
       
  8254 			if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {
       
  8255 				bn = se.element;
       
  8256 				sb = null;
       
  8257 			}
       
  8258 
       
  8259 			// If caption or absolute layers then always generate new blocks within
       
  8260 			if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {
       
  8261 				bn = se.element;
       
  8262 				eb = null;
       
  8263 			}
       
  8264 
       
  8265 			// Use P instead
       
  8266 			if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {
       
  8267 				bn = se.element;
       
  8268 				sb = eb = null;
       
  8269 			}
       
  8270 
       
  8271 			// Setup new before and after blocks
       
  8272 			bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn);
       
  8273 			aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn);
       
  8274 
       
  8275 			// Remove id from after clone
       
  8276 			aft.removeAttribute('id');
       
  8277 
       
  8278 			// Is header and cursor is at the end, then force paragraph under
       
  8279 			if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)
       
  8280 				aft = ed.dom.create(se.element);
       
  8281 
       
  8282 			// Find start chop node
       
  8283 			n = sc = sn;
       
  8284 			do {
       
  8285 				if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))
       
  8286 					break;
       
  8287 
       
  8288 				sc = n;
       
  8289 			} while ((n = n.previousSibling ? n.previousSibling : n.parentNode));
       
  8290 
       
  8291 			// Find end chop node
       
  8292 			n = ec = en;
       
  8293 			do {
       
  8294 				if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName))
       
  8295 					break;
       
  8296 
       
  8297 				ec = n;
       
  8298 			} while ((n = n.nextSibling ? n.nextSibling : n.parentNode));
       
  8299 
       
  8300 			// Place first chop part into before block element
       
  8301 			if (sc.nodeName == bn)
       
  8302 				rb.setStart(sc, 0);
       
  8303 			else
       
  8304 				rb.setStartBefore(sc);
       
  8305 
       
  8306 			rb.setEnd(sn, so);
       
  8307 			bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari
       
  8308 
       
  8309 			// Place secnd chop part within new block element
       
  8310 			try {
       
  8311 				ra.setEndAfter(ec);
       
  8312 			} catch(ex) {
       
  8313 				//console.debug(s.focusNode, s.focusOffset);
       
  8314 			}
       
  8315 
       
  8316 			ra.setStart(en, eo);
       
  8317 			aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari
       
  8318 
       
  8319 			// Create range around everything
       
  8320 			r = d.createRange();
       
  8321 			if (!sc.previousSibling && sc.parentNode.nodeName == bn) {
       
  8322 				r.setStartBefore(sc.parentNode);
       
  8323 			} else {
       
  8324 				if (rb.startContainer.nodeName == bn && rb.startOffset == 0)
       
  8325 					r.setStartBefore(rb.startContainer);
       
  8326 				else
       
  8327 					r.setStart(rb.startContainer, rb.startOffset);
       
  8328 			}
       
  8329 
       
  8330 			if (!ec.nextSibling && ec.parentNode.nodeName == bn)
       
  8331 				r.setEndAfter(ec.parentNode);
       
  8332 			else
       
  8333 				r.setEnd(ra.endContainer, ra.endOffset);
       
  8334 
       
  8335 			// Delete and replace it with new block elements
       
  8336 			r.deleteContents();
       
  8337 
       
  8338 			// Never wrap blocks in blocks
       
  8339 			if (bef.firstChild && bef.firstChild.nodeName == bn)
       
  8340 				bef.innerHTML = bef.firstChild.innerHTML;
       
  8341 
       
  8342 			if (aft.firstChild && aft.firstChild.nodeName == bn)
       
  8343 				aft.innerHTML = aft.firstChild.innerHTML;
       
  8344 
       
  8345 			// Padd empty blocks
       
  8346 			if (isEmpty(bef))
       
  8347 				bef.innerHTML = '<br />';
       
  8348 
       
  8349 			if (isEmpty(aft))
       
  8350 				aft.innerHTML = isOpera ? ' <br />' : '<br />'; // Extra space for Opera
       
  8351 
       
  8352 			// Opera needs this one backwards
       
  8353 			if (isOpera) {
       
  8354 				r.insertNode(bef);
       
  8355 				r.insertNode(aft);
       
  8356 			} else {
       
  8357 				r.insertNode(aft);
       
  8358 				r.insertNode(bef);
       
  8359 			}
       
  8360 
       
  8361 			// Normalize
       
  8362 			aft.normalize();
       
  8363 			bef.normalize();
       
  8364 
       
  8365 			// Move cursor and scroll into view
       
  8366 			r = d.createRange();
       
  8367 			r.selectNodeContents(aft);
       
  8368 			r.collapse(1);
       
  8369 			s.removeAllRanges();
       
  8370 			s.addRange(r);
       
  8371 			aft.scrollIntoView(0);
       
  8372 
       
  8373 			return false;
       
  8374 		},
       
  8375 
       
  8376 		backspaceDelete : function(e, bs) {
       
  8377 			var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n;
       
  8378 
       
  8379 			// The caret sometimes gets stuck in Gecko if you delete empty paragraphs
       
  8380 			// This workaround removes the element by hand and moves the caret to the previous element
       
  8381 			if (sc && ed.dom.isBlock(sc) && bs) {
       
  8382 				if (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR') {
       
  8383 					n = sc.previousSibling;
       
  8384 					if (n) { 
       
  8385 						ed.dom.remove(sc);
       
  8386 						se.select(n, 1);
       
  8387 						se.collapse(0);
       
  8388 						return Event.cancel(e);
  6441 					}
  8389 					}
  6442 				}
  8390 				}
  6443 			} else {
  8391 			}
  6444 				// Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs
  8392 
  6445 				try {
  8393 			// Gecko generates BR elements here and there, we don't like those so lets remove them
  6446 					// Incorrect bookmark
  8394 			function handler(e) {
  6447 					if (bookmark.start < 0)
  8395 				e = e.target;
  6448 						return true;
  8396 
  6449 
  8397 				// A new BR was created in a block element, remove it
  6450 					rng = inst.getSel().createRange();
  8398 				if (e && e.parentNode && e.nodeName == 'BR' && t.getParentBlock(e)) {
  6451 					rng.moveToElementText(inst.getBody());
  8399 					ed.dom.remove(e);
  6452 					rng.collapse(true);
  8400 					Event.remove(b, 'DOMNodeInserted', handler);
  6453 					rng.moveStart('character', bookmark.start);
  8401 				}
  6454 					rng.moveEnd('character', bookmark.length);
  8402 			};
  6455 				} catch (ex) {
  8403 
  6456 					return true;
  8404 			// Listen for new nodes
  6457 				}
  8405 			Event._add(b, 'DOMNodeInserted', handler);
  6458 			}
  8406 
  6459 
  8407 			// Remove listener
  6460 			rng.select();
  8408 			window.setTimeout(function() {
  6461 
  8409 				Event._remove(b, 'DOMNodeInserted', handler);
  6462 			win.scrollTo(bookmark.scrollX, bookmark.scrollY);
  8410 			}, 1);
  6463 			return true;
       
  6464 		}
  8411 		}
  6465 
  8412 	});
  6466 		if (tinyMCE.isGecko || tinyMCE.isOpera) {
  8413 })();
  6467 			if (!sel)
  8414 
  6468 				return false;
  8415 /* file:jscripts/tiny_mce/classes/ControlManager.js */
  6469 
  8416 
  6470 			if (bookmark.rng) {
  8417 (function() {
  6471 				sel.removeAllRanges();
  8418 	// Shorten names
  6472 				sel.addRange(bookmark.rng);
  8419 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;
  6473 			}
  8420 
  6474 
  8421 	tinymce.create('tinymce.ControlManager', {
  6475 			if (bookmark.start != -1 && bookmark.end != -1) {
  8422 		ControlManager : function(ed, s) {
  6476 				try {
  8423 			var t = this, i;
  6477 					sd = this._getTextPos(b, bookmark.start, bookmark.end);
  8424 
  6478 					rng = doc.createRange();
  8425 			s = s || {};
  6479 					rng.setStart(sd.startNode, sd.startOffset);
  8426 			t.editor = ed;
  6480 					rng.setEnd(sd.endNode, sd.endOffset);
  8427 			t.controls = {};
  6481 					sel.removeAllRanges();
  8428 			t.onAdd = new tinymce.util.Dispatcher(t);
  6482 					sel.addRange(rng);
  8429 			t.onPostRender = new tinymce.util.Dispatcher(t);
  6483 					win.focus();
  8430 			t.prefix = s.prefix || ed.id + '_';
  6484 				} catch (ex) {
  8431 
  6485 					// Ignore
  8432 			t.onPostRender.add(function() {
  6486 				}
  8433 				each(t.controls, function(c) {
  6487 			}
  8434 					c.postRender();
  6488 
       
  6489 			/*
       
  6490 			if (typeof(bookmark.index) != 'undefined') {
       
  6491 				tinyMCE.selectElements(b, 'IMG', function (n) {
       
  6492 					if (bookmark.index-- == 0) {
       
  6493 						// Select image in Gecko here
       
  6494 					}
       
  6495 
       
  6496 					return false;
       
  6497 				});
  8435 				});
  6498 			}
  8436 			});
  6499 			*/
  8437 		},
  6500 
  8438 
  6501 			win.scrollTo(bookmark.scrollX, bookmark.scrollY);
  8439 		get : function(id) {
  6502 			return true;
  8440 			return this.controls[this.prefix + id] || this.controls[id];
       
  8441 		},
       
  8442 
       
  8443 		setActive : function(id, s) {
       
  8444 			var c = null;
       
  8445 
       
  8446 			if (c = this.get(id))
       
  8447 				c.setActive(s);
       
  8448 
       
  8449 			return c;
       
  8450 		},
       
  8451 
       
  8452 		setDisabled : function(id, s) {
       
  8453 			var c = null;
       
  8454 
       
  8455 			if (c = this.get(id))
       
  8456 				c.setDisabled(s);
       
  8457 
       
  8458 			return c;
       
  8459 		},
       
  8460 
       
  8461 		add : function(c) {
       
  8462 			var t = this;
       
  8463 
       
  8464 			if (c) {
       
  8465 				t.controls[c.id] = c;
       
  8466 				t.onAdd.dispatch(c, t);
       
  8467 			}
       
  8468 
       
  8469 			return c;
       
  8470 		},
       
  8471 
       
  8472 		createControl : function(n) {
       
  8473 			var c, t = this, ed = t.editor;
       
  8474 
       
  8475 			each(ed.plugins, function(p) {
       
  8476 				if (p.createControl) {
       
  8477 					c = p.createControl(n, t);
       
  8478 
       
  8479 					if (c)
       
  8480 						return false;
       
  8481 				}
       
  8482 			});
       
  8483 
       
  8484 			switch (n) {
       
  8485 				case "|":
       
  8486 				case "separator":
       
  8487 					return t.createSeparator();
       
  8488 			}
       
  8489 
       
  8490 			if (!c && ed.buttons && (c = ed.buttons[n]))
       
  8491 				return t.createButton(n, c);
       
  8492 
       
  8493 			return t.add(c);
       
  8494 		},
       
  8495 
       
  8496 		createDropMenu : function(id, s) {
       
  8497 			var t = this, ed = t.editor, c;
       
  8498 
       
  8499 			s = extend({
       
  8500 				'class' : 'mceDropDown'
       
  8501 			}, s);
       
  8502 
       
  8503 			s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';
       
  8504 
       
  8505 			id = t.prefix + id;
       
  8506 			c = t.controls[id] = new tinymce.ui.DropMenu(id, s);
       
  8507 			c.onAddItem.add(function(c, o) {
       
  8508 				var s = o.settings;
       
  8509 
       
  8510 				s.title = ed.getLang(s.title, s.title);
       
  8511 
       
  8512 				if (!s.onclick) {
       
  8513 					s.onclick = function(v) {
       
  8514 						ed.execCommand(s.cmd, s.ui || false, v || s.value);
       
  8515 					};
       
  8516 				}
       
  8517 			});
       
  8518 
       
  8519 			ed.onRemove.add(function() {
       
  8520 				c.destroy();
       
  8521 			});
       
  8522 
       
  8523 			return t.add(c);
       
  8524 		},
       
  8525 
       
  8526 		createListBox : function(id, s) {
       
  8527 			var t = this, ed = t.editor, cmd, c;
       
  8528 
       
  8529 			if (t.get(id))
       
  8530 				return null;
       
  8531 
       
  8532 			s.title = ed.translate(s.title);
       
  8533 			s.scope = s.scope || ed;
       
  8534 
       
  8535 			if (!s.onselect) {
       
  8536 				s.onselect = function(v) {
       
  8537 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
       
  8538 				};
       
  8539 			}
       
  8540 
       
  8541 			s = extend({
       
  8542 				title : s.title,
       
  8543 				'class' : id,
       
  8544 				scope : s.scope,
       
  8545 				control_manager : t
       
  8546 			}, s);
       
  8547 
       
  8548 			id = t.prefix + id;
       
  8549 
       
  8550 			if (ed.settings.use_native_selects)
       
  8551 				c = new tinymce.ui.NativeListBox(id, s);
       
  8552 			else
       
  8553 				c = new tinymce.ui.ListBox(id, s);
       
  8554 
       
  8555 			t.controls[id] = c;
       
  8556 
       
  8557 			// Fix focus problem in Safari
       
  8558 			if (tinymce.isWebKit) {
       
  8559 				c.onPostRender.add(function(c, n) {
       
  8560 					// Store bookmark on mousedown
       
  8561 					Event.add(n, 'mousedown', function() {
       
  8562 						ed.bookmark = ed.selection.getBookmark('simple');
       
  8563 					});
       
  8564 
       
  8565 					// Restore on focus, since it might be lost
       
  8566 					Event.add(n, 'focus', function() {
       
  8567 						ed.selection.moveToBookmark(ed.bookmark);
       
  8568 						ed.bookmark = null;
       
  8569 					});
       
  8570 				});
       
  8571 			}
       
  8572 
       
  8573 			if (c.hideMenu)
       
  8574 				ed.onMouseDown.add(c.hideMenu, c);
       
  8575 
       
  8576 			return t.add(c);
       
  8577 		},
       
  8578 
       
  8579 		createButton : function(id, s) {
       
  8580 			var t = this, ed = t.editor, o;
       
  8581 
       
  8582 			if (t.get(id))
       
  8583 				return null;
       
  8584 
       
  8585 			s.title = ed.translate(s.title);
       
  8586 			s.scope = s.scope || ed;
       
  8587 
       
  8588 			if (!s.onclick) {
       
  8589 				s.onclick = function() {
       
  8590 					ed.execCommand(s.cmd, s.ui || false, s.value);
       
  8591 				};
       
  8592 			}
       
  8593 
       
  8594 			s = extend({
       
  8595 				title : s.title,
       
  8596 				'class' : id,
       
  8597 				unavailable_prefix : ed.getLang('unavailable', ''),
       
  8598 				scope : s.scope
       
  8599 			}, s);
       
  8600 
       
  8601 			id = t.prefix + id;
       
  8602 
       
  8603 			return t.add(new tinymce.ui.Button(id, s));
       
  8604 		},
       
  8605 
       
  8606 		createSplitButton : function(id, s) {
       
  8607 			var t = this, ed = t.editor, cmd, c;
       
  8608 
       
  8609 			if (t.get(id))
       
  8610 				return null;
       
  8611 
       
  8612 			s.title = ed.translate(s.title);
       
  8613 			s.scope = s.scope || ed;
       
  8614 
       
  8615 			if (!s.onclick) {
       
  8616 				s.onclick = function(v) {
       
  8617 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
       
  8618 				};
       
  8619 			}
       
  8620 
       
  8621 			if (!s.onselect) {
       
  8622 				s.onselect = function(v) {
       
  8623 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
       
  8624 				};
       
  8625 			}
       
  8626 
       
  8627 			s = extend({
       
  8628 				title : s.title,
       
  8629 				'class' : id,
       
  8630 				scope : s.scope,
       
  8631 				control_manager : t
       
  8632 			}, s);
       
  8633 
       
  8634 			id = t.prefix + id;
       
  8635 			c = t.add(new tinymce.ui.SplitButton(id, s));
       
  8636 			ed.onMouseDown.add(c.hideMenu, c);
       
  8637 
       
  8638 			return c;
       
  8639 		},
       
  8640 
       
  8641 		createColorSplitButton : function(id, s) {
       
  8642 			var t = this, ed = t.editor, cmd, c;
       
  8643 
       
  8644 			if (t.get(id))
       
  8645 				return null;
       
  8646 
       
  8647 			s.title = ed.translate(s.title);
       
  8648 			s.scope = s.scope || ed;
       
  8649 
       
  8650 			if (!s.onclick) {
       
  8651 				s.onclick = function(v) {
       
  8652 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
       
  8653 				};
       
  8654 			}
       
  8655 
       
  8656 			if (!s.onselect) {
       
  8657 				s.onselect = function(v) {
       
  8658 					ed.execCommand(s.cmd, s.ui || false, v || s.value);
       
  8659 				};
       
  8660 			}
       
  8661 
       
  8662 			s = extend({
       
  8663 				title : s.title,
       
  8664 				'class' : id,
       
  8665 				'menu_class' : ed.getParam('skin') + 'Skin',
       
  8666 				scope : s.scope,
       
  8667 				more_colors_title : ed.getLang('more_colors')
       
  8668 			}, s);
       
  8669 
       
  8670 			id = t.prefix + id;
       
  8671 			c = new tinymce.ui.ColorSplitButton(id, s);
       
  8672 			ed.onMouseDown.add(c.hideMenu, c);
       
  8673 
       
  8674 			return t.add(c);
       
  8675 		},
       
  8676 
       
  8677 		createToolbar : function(id, s) {
       
  8678 			var c = new tinymce.ui.Toolbar(id, s);
       
  8679 
       
  8680 			if (this.get(id))
       
  8681 				return null;
       
  8682 
       
  8683 			return this.add(c);
       
  8684 		},
       
  8685 
       
  8686 		createSeparator : function() {
       
  8687 			return new tinymce.ui.Separator();
  6503 		}
  8688 		}
  6504 
  8689 
  6505 		return false;
  8690 		});
  6506 	},
  8691 })();
  6507 
  8692 
  6508 	_getPosText : function(r, sn, en) {
  8693 /* file:jscripts/tiny_mce/classes/WindowManager.js */
  6509 		var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
  8694 
  6510 
  8695 (function() {
  6511 		while ((n = w.nextNode()) != null) {
  8696 	var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;
  6512 			if (n == sn)
  8697 
  6513 				d.start = p;
  8698 	tinymce.create('tinymce.WindowManager', {
  6514 
  8699 		WindowManager : function(ed) {
  6515 			if (n == en) {
  8700 			var t = this;
  6516 				d.end = p;
  8701 
  6517 				return d;
  8702 			t.editor = ed;
  6518 			}
  8703 			t.onOpen = new Dispatcher(t);
  6519 
  8704 			t.onClose = new Dispatcher(t);
  6520 			p += n.nodeValue ? n.nodeValue.length : 0;
  8705 			t.params = {};
       
  8706 			t.features = {};
       
  8707 		},
       
  8708 
       
  8709 		open : function(s, p) {
       
  8710 			var t = this, f = '', x, y, mo = t.editor.settings.dialog_type == 'modal', w, sw, sh, vp = tinymce.DOM.getViewPort();
       
  8711 
       
  8712 			// Default some options
       
  8713 			s = s || {};
       
  8714 			p = p || {};
       
  8715 			sw = isOpera ? vp.w : screen.width; // Opera uses windows inside the Opera window
       
  8716 			sh = isOpera ? vp.h : screen.height;
       
  8717 			s.name = s.name || 'mc_' + new Date().getTime();
       
  8718 			s.width = parseInt(s.width || 320);
       
  8719 			s.height = parseInt(s.height || 240);
       
  8720 			s.resizable = true;
       
  8721 			s.left = s.left || parseInt(sw / 2.0) - (s.width / 2.0);
       
  8722 			s.top = s.top || parseInt(sh / 2.0) - (s.height / 2.0);
       
  8723 			p.inline = false;
       
  8724 			p.mce_width = s.width;
       
  8725 			p.mce_height = s.height;
       
  8726 
       
  8727 			if (mo) {
       
  8728 				if (isIE) {
       
  8729 					s.center = true;
       
  8730 					s.help = false;
       
  8731 					s.dialogWidth = s.width + 'px';
       
  8732 					s.dialogHeight = s.height + 'px';
       
  8733 					s.scroll = s.scrollbars || false;
       
  8734 				} else
       
  8735 					s.modal = s.alwaysRaised = s.dialog = s.centerscreen = s.dependent = true;
       
  8736 			}
       
  8737 
       
  8738 			// Build features string
       
  8739 			each(s, function(v, k) {
       
  8740 				if (tinymce.is(v, 'boolean'))
       
  8741 					v = v ? 'yes' : 'no';
       
  8742 
       
  8743 				if (!/^(name|url)$/.test(k)) {
       
  8744 					if (isIE && mo)
       
  8745 						f += (f ? ';' : '') + k + ':' + v;
       
  8746 					else
       
  8747 						f += (f ? ',' : '') + k + '=' + v;
       
  8748 				}
       
  8749 			});
       
  8750 
       
  8751 			t.features = s;
       
  8752 			t.params = p;
       
  8753 			t.onOpen.dispatch(t, s, p);
       
  8754 
       
  8755 			try {
       
  8756 				if (isIE && mo) {
       
  8757 					w = 1;
       
  8758 					window.showModalDialog(s.url || s.file, window, f);
       
  8759 				} else
       
  8760 					w = window.open(s.url || s.file, s.name, f);
       
  8761 			} catch (ex) {
       
  8762 				// Ignore
       
  8763 			}
       
  8764 
       
  8765 			if (!w)
       
  8766 				alert(t.editor.getLang('popup_blocked'));
       
  8767 		},
       
  8768 
       
  8769 		close : function(w) {
       
  8770 			w.close();
       
  8771 			this.onClose.dispatch(this);
       
  8772 		},
       
  8773 
       
  8774 		createInstance : function(cl) {
       
  8775 			var a = arguments, i, f = tinymce.resolve(cl), s = '';
       
  8776 
       
  8777 			// Is there a better way to dynamically create
       
  8778 			// a class with a dynamic number of arguments
       
  8779 			for (i=1; i<a.length; i++)
       
  8780 				s += (i > 1 ? ',' : '') + 'a[' + i + ']';
       
  8781 
       
  8782 			return eval('(new f(' + s + '))');
       
  8783 		},
       
  8784 
       
  8785 		confirm : function(t, cb, s) {
       
  8786 			cb.call(s || this, confirm(this._decode(this.editor.getLang(t, t))));
       
  8787 		},
       
  8788 
       
  8789 		alert : function(t, cb, s) {
       
  8790 			alert(this._decode(t));
       
  8791 
       
  8792 			if (cb)
       
  8793 				cb.call(s || this);
       
  8794 		},
       
  8795 
       
  8796 		// Internal functions
       
  8797 
       
  8798 		_decode : function(s) {
       
  8799 			return tinymce.DOM.decode(s).replace(/\\n/g, '\n');
  6521 		}
  8800 		}
  6522 
  8801 
  6523 		return null;
  8802 		});
  6524 	},
  8803 }());
  6525 
       
  6526 	_getTextPos : function(r, sp, ep) {
       
  6527 		var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
       
  6528 
       
  6529 		while ((n = w.nextNode()) != null) {
       
  6530 			p += n.nodeValue ? n.nodeValue.length : 0;
       
  6531 
       
  6532 			if (p >= sp && !d.startNode) {
       
  6533 				d.startNode = n;
       
  6534 				d.startOffset = sp - (p - n.nodeValue.length);
       
  6535 			}
       
  6536 
       
  6537 			if (p >= ep) {
       
  6538 				d.endNode = n;
       
  6539 				d.endOffset = ep - (p - n.nodeValue.length);
       
  6540 
       
  6541 				return d;
       
  6542 			}
       
  6543 		}
       
  6544 
       
  6545 		return null;
       
  6546 	},
       
  6547 
       
  6548 	selectNode : function(node, collapse, select_text_node, to_start) {
       
  6549 		var inst = this.instance, sel, rng, nodes;
       
  6550 
       
  6551 		if (!node)
       
  6552 			return;
       
  6553 
       
  6554 		if (typeof(collapse) == "undefined")
       
  6555 			collapse = true;
       
  6556 
       
  6557 		if (typeof(select_text_node) == "undefined")
       
  6558 			select_text_node = false;
       
  6559 
       
  6560 		if (typeof(to_start) == "undefined")
       
  6561 			to_start = true;
       
  6562 
       
  6563 		if (inst.settings.auto_resize)
       
  6564 			inst.resizeToContent();
       
  6565 
       
  6566 		if (tinyMCE.isRealIE) {
       
  6567 			rng = inst.getDoc().body.createTextRange();
       
  6568 
       
  6569 			try {
       
  6570 				rng.moveToElementText(node);
       
  6571 
       
  6572 				if (collapse)
       
  6573 					rng.collapse(to_start);
       
  6574 
       
  6575 				rng.select();
       
  6576 			} catch (e) {
       
  6577 				// Throws illigal agrument in MSIE some times
       
  6578 			}
       
  6579 		} else {
       
  6580 			sel = this.getSel();
       
  6581 
       
  6582 			if (!sel)
       
  6583 				return;
       
  6584 
       
  6585 			if (tinyMCE.isSafari) {
       
  6586 				sel.setBaseAndExtent(node, 0, node, node.innerText.length);
       
  6587 
       
  6588 				if (collapse) {
       
  6589 					if (to_start)
       
  6590 						sel.collapseToStart();
       
  6591 					else
       
  6592 						sel.collapseToEnd();
       
  6593 				}
       
  6594 
       
  6595 				this.scrollToNode(node);
       
  6596 
       
  6597 				return;
       
  6598 			}
       
  6599 
       
  6600 			rng = inst.getDoc().createRange();
       
  6601 
       
  6602 			if (select_text_node) {
       
  6603 				// Find first textnode in tree
       
  6604 				nodes = tinyMCE.getNodeTree(node, new Array(), 3);
       
  6605 				if (nodes.length > 0)
       
  6606 					rng.selectNodeContents(nodes[0]);
       
  6607 				else
       
  6608 					rng.selectNodeContents(node);
       
  6609 			} else
       
  6610 				rng.selectNode(node);
       
  6611 
       
  6612 			if (collapse) {
       
  6613 				// Special treatment of textnode collapse
       
  6614 				if (!to_start && node.nodeType == 3) {
       
  6615 					rng.setStart(node, node.nodeValue.length);
       
  6616 					rng.setEnd(node, node.nodeValue.length);
       
  6617 				} else
       
  6618 					rng.collapse(to_start);
       
  6619 			}
       
  6620 
       
  6621 			sel.removeAllRanges();
       
  6622 			sel.addRange(rng);
       
  6623 		}
       
  6624 
       
  6625 		this.scrollToNode(node);
       
  6626 
       
  6627 		// Set selected element
       
  6628 		tinyMCE.selectedElement = null;
       
  6629 		if (node.nodeType == 1)
       
  6630 			tinyMCE.selectedElement = node;
       
  6631 	},
       
  6632 
       
  6633 	scrollToNode : function(node) {
       
  6634 		var inst = this.instance, w = inst.getWin(), vp = inst.getViewPort(), pos = tinyMCE.getAbsPosition(node), cvp, p, cwin;
       
  6635 
       
  6636 		// Only scroll if out of visible area
       
  6637 		if (pos.absLeft < vp.left || pos.absLeft > vp.left + vp.width || pos.absTop < vp.top || pos.absTop > vp.top + (vp.height-25))
       
  6638 			w.scrollTo(pos.absLeft, pos.absTop - vp.height + 25);
       
  6639 
       
  6640 		// Scroll container window
       
  6641 		if (inst.settings.auto_resize) {
       
  6642 			cwin = inst.getContainerWin();
       
  6643 			cvp = tinyMCE.getViewPort(cwin);
       
  6644 			p = this.getAbsPosition(node);
       
  6645 
       
  6646 			if (p.absLeft < cvp.left || p.absLeft > cvp.left + cvp.width || p.absTop < cvp.top || p.absTop > cvp.top + cvp.height)
       
  6647 				cwin.scrollTo(p.absLeft, p.absTop - cvp.height + 25);
       
  6648 		}
       
  6649 	},
       
  6650 
       
  6651 	getAbsPosition : function(n) {
       
  6652 		var pos = tinyMCE.getAbsPosition(n), ipos = tinyMCE.getAbsPosition(this.instance.iframeElement);
       
  6653 
       
  6654 		return {
       
  6655 			absLeft : ipos.absLeft + pos.absLeft,
       
  6656 			absTop : ipos.absTop + pos.absTop
       
  6657 		};
       
  6658 	},
       
  6659 
       
  6660 	getSel : function() {
       
  6661 		var inst = this.instance;
       
  6662 
       
  6663 		if (tinyMCE.isRealIE)
       
  6664 			return inst.getDoc().selection;
       
  6665 
       
  6666 		return inst.contentWindow.getSelection();
       
  6667 	},
       
  6668 
       
  6669 	getRng : function() {
       
  6670 		var s = this.getSel();
       
  6671 
       
  6672 		if (s == null)
       
  6673 			return null;
       
  6674 
       
  6675 		if (tinyMCE.isRealIE)
       
  6676 			return s.createRange();
       
  6677 
       
  6678 		if (tinyMCE.isSafari && !s.getRangeAt)
       
  6679 			return '' + window.getSelection();
       
  6680 
       
  6681 		if (s.rangeCount > 0)
       
  6682 			return s.getRangeAt(0);
       
  6683 
       
  6684 		return null;
       
  6685 	},
       
  6686 
       
  6687 	isCollapsed : function() {
       
  6688 		var r = this.getRng();
       
  6689 
       
  6690 		if (r.item)
       
  6691 			return false;
       
  6692 
       
  6693 		return r.boundingWidth == 0 || this.getSel().isCollapsed;
       
  6694 	},
       
  6695 
       
  6696 	collapse : function(b) {
       
  6697 		var r = this.getRng(), s = this.getSel();
       
  6698 
       
  6699 		if (r.select) {
       
  6700 			r.collapse(b);
       
  6701 			r.select();
       
  6702 		} else {
       
  6703 			if (b)
       
  6704 				s.collapseToStart();
       
  6705 			else
       
  6706 				s.collapseToEnd();
       
  6707 		}
       
  6708 	},
       
  6709 
       
  6710 	getFocusElement : function() {
       
  6711 		var inst = this.instance, doc, rng, sel, elm;
       
  6712 
       
  6713 		if (tinyMCE.isRealIE) {
       
  6714 			doc = inst.getDoc();
       
  6715 			rng = doc.selection.createRange();
       
  6716 
       
  6717 	//		if (rng.collapse)
       
  6718 	//			rng.collapse(true);
       
  6719 
       
  6720 			elm = rng.item ? rng.item(0) : rng.parentElement();
       
  6721 		} else {
       
  6722 			if (!tinyMCE.isSafari && inst.isHidden())
       
  6723 				return inst.getBody();
       
  6724 
       
  6725 			sel = this.getSel();
       
  6726 			rng = this.getRng();
       
  6727 
       
  6728 			if (!sel || !rng)
       
  6729 				return null;
       
  6730 
       
  6731 			elm = rng.commonAncestorContainer;
       
  6732 			//elm = (sel && sel.anchorNode) ? sel.anchorNode : null;
       
  6733 
       
  6734 			// Handle selection a image or other control like element such as anchors
       
  6735 			if (!rng.collapsed) {
       
  6736 				// Is selection small
       
  6737 				if (rng.startContainer == rng.endContainer) {
       
  6738 					if (rng.startOffset - rng.endOffset < 2) {
       
  6739 						if (rng.startContainer.hasChildNodes())
       
  6740 							elm = rng.startContainer.childNodes[rng.startOffset];
       
  6741 					}
       
  6742 				}
       
  6743 			}
       
  6744 
       
  6745 			// Get the element parent of the node
       
  6746 			elm = tinyMCE.getParentElement(elm);
       
  6747 
       
  6748 			//if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img")
       
  6749 			//	elm = tinyMCE.selectedElement;
       
  6750 		}
       
  6751 
       
  6752 		return elm;
       
  6753 	}
       
  6754 
       
  6755 	};
       
  6756 
       
  6757 /* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */
       
  6758 
       
  6759 function TinyMCE_UndoRedo(inst) {
       
  6760 	this.instance = inst;
       
  6761 	this.undoLevels = new Array();
       
  6762 	this.undoIndex = 0;
       
  6763 	this.typingUndoIndex = -1;
       
  6764 	this.undoRedo = true;
       
  6765 };
       
  6766 
       
  6767 TinyMCE_UndoRedo.prototype = {
       
  6768 	add : function(l) {
       
  6769 		var b, customUndoLevels, newHTML, inst = this.instance, i, ul, ur;
       
  6770 
       
  6771 		if (l) {
       
  6772 			this.undoLevels[this.undoLevels.length] = l;
       
  6773 			return true;
       
  6774 		}
       
  6775 
       
  6776 		if (this.typingUndoIndex != -1) {
       
  6777 			this.undoIndex = this.typingUndoIndex;
       
  6778 
       
  6779 			if (tinyMCE.typingUndoIndex != -1)
       
  6780 				tinyMCE.undoIndex = tinyMCE.typingUndoIndex;
       
  6781 		}
       
  6782 
       
  6783 		newHTML = tinyMCE.trim(inst.getBody().innerHTML);
       
  6784 		if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) {
       
  6785 			//tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content);
       
  6786 
       
  6787 			tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst);
       
  6788 
       
  6789 			// Time to compress
       
  6790 			customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
       
  6791 			if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
       
  6792 				for (i=0; i<this.undoLevels.length-1; i++)
       
  6793 					this.undoLevels[i] = this.undoLevels[i+1];
       
  6794 
       
  6795 				this.undoLevels.length--;
       
  6796 				this.undoIndex--;
       
  6797 
       
  6798 				// Todo: Implement global undo/redo logic here
       
  6799 			}
       
  6800 
       
  6801 			b = inst.undoBookmark;
       
  6802 
       
  6803 			if (!b)
       
  6804 				b = inst.selection.getBookmark();
       
  6805 
       
  6806 			this.undoIndex++;
       
  6807 			this.undoLevels[this.undoIndex] = {
       
  6808 				content : newHTML,
       
  6809 				bookmark : b
       
  6810 			};
       
  6811 
       
  6812 			// Remove all above from global undo/redo
       
  6813 			ul = tinyMCE.undoLevels;
       
  6814 			for (i=tinyMCE.undoIndex + 1; i<ul.length; i++) {
       
  6815 				ur = ul[i].undoRedo;
       
  6816 
       
  6817 				if (ur.undoIndex == ur.undoLevels.length -1)
       
  6818 					ur.undoIndex--;
       
  6819 
       
  6820 				ur.undoLevels.length--;
       
  6821 			}
       
  6822 
       
  6823 			// Add global undo level
       
  6824 			tinyMCE.undoLevels[tinyMCE.undoIndex++] = inst;
       
  6825 			tinyMCE.undoLevels.length = tinyMCE.undoIndex;
       
  6826 
       
  6827 			this.undoLevels.length = this.undoIndex + 1;
       
  6828 
       
  6829 			return true;
       
  6830 		}
       
  6831 
       
  6832 		return false;
       
  6833 	},
       
  6834 
       
  6835 	undo : function() {
       
  6836 		var inst = this.instance;
       
  6837 
       
  6838 		// Do undo
       
  6839 		if (this.undoIndex > 0) {
       
  6840 			this.undoIndex--;
       
  6841 
       
  6842 			tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content);
       
  6843 			inst.repaint();
       
  6844 
       
  6845 			if (inst.settings.custom_undo_redo_restore_selection)
       
  6846 				inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark);
       
  6847 		}
       
  6848 	},
       
  6849 
       
  6850 	redo : function() {
       
  6851 		var inst = this.instance;
       
  6852 
       
  6853 		tinyMCE.execCommand("mceEndTyping");
       
  6854 
       
  6855 		if (this.undoIndex < (this.undoLevels.length-1)) {
       
  6856 			this.undoIndex++;
       
  6857 
       
  6858 			tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content);
       
  6859 			inst.repaint();
       
  6860 
       
  6861 			if (inst.settings.custom_undo_redo_restore_selection)
       
  6862 				inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark);
       
  6863 		}
       
  6864 
       
  6865 		tinyMCE.triggerNodeChange();
       
  6866 	}
       
  6867 
       
  6868 	};
       
  6869 
       
  6870 /* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */
       
  6871 
       
  6872 var TinyMCE_ForceParagraphs = {
       
  6873 	_insertPara : function(inst, e) {
       
  6874 		var doc = inst.getDoc(), sel = inst.getSel(), body = inst.getBody(), win = inst.contentWindow, rng = sel.getRangeAt(0);
       
  6875 		var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock;
       
  6876 		var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null;
       
  6877 		var paraBefore, paraAfter, startChop, endChop, contents;
       
  6878 
       
  6879 		function isEmpty(para) {
       
  6880 			function isEmptyHTML(html) {
       
  6881 				return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == "";
       
  6882 			}
       
  6883 
       
  6884 			// Check for images
       
  6885 			if (para.getElementsByTagName("img").length > 0)
       
  6886 				return false;
       
  6887 
       
  6888 			// Check for tables
       
  6889 			if (para.getElementsByTagName("table").length > 0)
       
  6890 				return false;
       
  6891 
       
  6892 			// Check for HRs
       
  6893 			if (para.getElementsByTagName("hr").length > 0)
       
  6894 				return false;
       
  6895 
       
  6896 			// Check all textnodes
       
  6897 			var nodes = tinyMCE.getNodeTree(para, new Array(), 3);
       
  6898 			for (var i=0; i<nodes.length; i++) {
       
  6899 				if (!isEmptyHTML(nodes[i].nodeValue))
       
  6900 					return false;
       
  6901 			}
       
  6902 
       
  6903 			// No images, no tables, no hrs, no text content then it's empty
       
  6904 			return true;
       
  6905 		}
       
  6906 
       
  6907 	//	tinyMCE.debug(body.innerHTML);
       
  6908 
       
  6909 	//	debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString());
       
  6910 
       
  6911 		// Setup before range
       
  6912 		rngBefore = doc.createRange();
       
  6913 		rngBefore.setStart(sel.anchorNode, sel.anchorOffset);
       
  6914 		rngBefore.collapse(true);
       
  6915 
       
  6916 		// Setup after range
       
  6917 		rngAfter = doc.createRange();
       
  6918 		rngAfter.setStart(sel.focusNode, sel.focusOffset);
       
  6919 		rngAfter.collapse(true);
       
  6920 
       
  6921 		// Setup start/end points
       
  6922 		direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0;
       
  6923 		startNode = direct ? sel.anchorNode : sel.focusNode;
       
  6924 		startOffset = direct ? sel.anchorOffset : sel.focusOffset;
       
  6925 		endNode = direct ? sel.focusNode : sel.anchorNode;
       
  6926 		endOffset = direct ? sel.focusOffset : sel.anchorOffset;
       
  6927 
       
  6928 		startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode;
       
  6929 		endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode;
       
  6930 
       
  6931 		// Get block elements
       
  6932 		startBlock = inst.getParentBlockElement(startNode);
       
  6933 		endBlock = inst.getParentBlockElement(endNode);
       
  6934 
       
  6935 		// If absolute force paragraph generation within
       
  6936 		if (startBlock && new RegExp('absolute|relative|static', 'gi').test(startBlock.style.position))
       
  6937 			startBlock = null;
       
  6938 
       
  6939 		if (endBlock && new RegExp('absolute|relative|static', 'gi').test(endBlock.style.position))
       
  6940 			endBlock = null;
       
  6941 
       
  6942 		// Use current block name
       
  6943 		if (startBlock != null) {
       
  6944 			blockName = startBlock.nodeName;
       
  6945 
       
  6946 			// Use P instead
       
  6947 			if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat)))
       
  6948 				blockName = "P";
       
  6949 		}
       
  6950 
       
  6951 		// Within a list use normal behaviour
       
  6952 		if (tinyMCE.getParentElement(startBlock, "OL,UL", null, body) != null)
       
  6953 			return false;
       
  6954 
       
  6955 		// Within a table create new paragraphs
       
  6956 		if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE"))
       
  6957 			startBlock = endBlock = null;
       
  6958 
       
  6959 		// Setup new paragraphs
       
  6960 		paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);
       
  6961 		paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);
       
  6962 
       
  6963 		// Is header, then force paragraph under
       
  6964 		if (/^(H[1-6])$/.test(blockName))
       
  6965 			paraAfter = doc.createElement("p");
       
  6966 
       
  6967 		// Setup chop nodes
       
  6968 		startChop = startNode;
       
  6969 		endChop = endNode;
       
  6970 
       
  6971 		// Get startChop node
       
  6972 		node = startChop;
       
  6973 		do {
       
  6974 			if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
       
  6975 				break;
       
  6976 
       
  6977 			startChop = node;
       
  6978 		} while ((node = node.previousSibling ? node.previousSibling : node.parentNode));
       
  6979 
       
  6980 		// Get endChop node
       
  6981 		node = endChop;
       
  6982 		do {
       
  6983 			if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
       
  6984 				break;
       
  6985 
       
  6986 			endChop = node;
       
  6987 		} while ((node = node.nextSibling ? node.nextSibling : node.parentNode));
       
  6988 
       
  6989 		// Fix when only a image is within the TD
       
  6990 		if (startChop.nodeName == "TD")
       
  6991 			startChop = startChop.firstChild;
       
  6992 
       
  6993 		if (endChop.nodeName == "TD")
       
  6994 			endChop = endChop.lastChild;
       
  6995 
       
  6996 		// If not in a block element
       
  6997 		if (startBlock == null) {
       
  6998 			// Delete selection
       
  6999 			rng.deleteContents();
       
  7000 
       
  7001 			if (!tinyMCE.isSafari)
       
  7002 				sel.removeAllRanges();
       
  7003 
       
  7004 			if (startChop != rootElm && endChop != rootElm) {
       
  7005 				// Insert paragraph before
       
  7006 				rngBefore = rng.cloneRange();
       
  7007 
       
  7008 				if (startChop == body)
       
  7009 					rngBefore.setStart(startChop, 0);
       
  7010 				else
       
  7011 					rngBefore.setStartBefore(startChop);
       
  7012 
       
  7013 				paraBefore.appendChild(rngBefore.cloneContents());
       
  7014 
       
  7015 				// Insert paragraph after
       
  7016 				if (endChop.parentNode.nodeName == blockName)
       
  7017 					endChop = endChop.parentNode;
       
  7018 
       
  7019 				// If not after image
       
  7020 				//if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY")
       
  7021 					rng.setEndAfter(endChop);
       
  7022 
       
  7023 				if (endChop.nodeName != "#text" && endChop.nodeName != "BODY")
       
  7024 					rngBefore.setEndAfter(endChop);
       
  7025 
       
  7026 				contents = rng.cloneContents();
       
  7027 				if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY"))
       
  7028 					paraAfter.innerHTML = contents.firstChild.innerHTML;
       
  7029 				else
       
  7030 					paraAfter.appendChild(contents);
       
  7031 
       
  7032 				// Check if it's a empty paragraph
       
  7033 				if (isEmpty(paraBefore))
       
  7034 					paraBefore.innerHTML = "&nbsp;";
       
  7035 
       
  7036 				// Check if it's a empty paragraph
       
  7037 				if (isEmpty(paraAfter))
       
  7038 					paraAfter.innerHTML = "&nbsp;";
       
  7039 
       
  7040 				// Delete old contents
       
  7041 				rng.deleteContents();
       
  7042 				rngAfter.deleteContents();
       
  7043 				rngBefore.deleteContents();
       
  7044 
       
  7045 				// Insert new paragraphs
       
  7046 				if (tinyMCE.isOpera) {
       
  7047 					paraBefore.normalize();
       
  7048 					rngBefore.insertNode(paraBefore);
       
  7049 					paraAfter.normalize();
       
  7050 					rngBefore.insertNode(paraAfter);
       
  7051 				} else {
       
  7052 					paraAfter.normalize();
       
  7053 					rngBefore.insertNode(paraAfter);
       
  7054 					paraBefore.normalize();
       
  7055 					rngBefore.insertNode(paraBefore);
       
  7056 				}
       
  7057 
       
  7058 				//tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);
       
  7059 			} else {
       
  7060 				body.innerHTML = "<" + blockName + ">&nbsp;</" + blockName + "><" + blockName + ">&nbsp;</" + blockName + ">";
       
  7061 				paraAfter = body.childNodes[1];
       
  7062 			}
       
  7063 
       
  7064 			inst.selection.moveToBookmark(b);
       
  7065 			inst.selection.selectNode(paraAfter, true, true);
       
  7066 
       
  7067 			return true;
       
  7068 		}
       
  7069 
       
  7070 		// Place first part within new paragraph
       
  7071 		if (startChop.nodeName == blockName)
       
  7072 			rngBefore.setStart(startChop, 0);
       
  7073 		else
       
  7074 			rngBefore.setStartBefore(startChop);
       
  7075 
       
  7076 		rngBefore.setEnd(startNode, startOffset);
       
  7077 		paraBefore.appendChild(rngBefore.cloneContents());
       
  7078 
       
  7079 		// Place secound part within new paragraph
       
  7080 		rngAfter.setEndAfter(endChop);
       
  7081 		rngAfter.setStart(endNode, endOffset);
       
  7082 		contents = rngAfter.cloneContents();
       
  7083 
       
  7084 		if (contents.firstChild && contents.firstChild.nodeName == blockName) {
       
  7085 	/*		var nodes = contents.firstChild.childNodes;
       
  7086 			for (var i=0; i<nodes.length; i++) {
       
  7087 				//tinyMCE.debug(nodes[i].nodeName);
       
  7088 				if (nodes[i].nodeName != "BODY")
       
  7089 					paraAfter.appendChild(nodes[i]);
       
  7090 			}
       
  7091 	*/
       
  7092 			paraAfter.innerHTML = contents.firstChild.innerHTML;
       
  7093 		} else
       
  7094 			paraAfter.appendChild(contents);
       
  7095 
       
  7096 		// Check if it's a empty paragraph
       
  7097 		if (isEmpty(paraBefore))
       
  7098 			paraBefore.innerHTML = "&nbsp;";
       
  7099 
       
  7100 		// Check if it's a empty paragraph
       
  7101 		if (isEmpty(paraAfter))
       
  7102 			paraAfter.innerHTML = "&nbsp;";
       
  7103 
       
  7104 		// Create a range around everything
       
  7105 		rng = doc.createRange();
       
  7106 
       
  7107 		if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) {
       
  7108 			rng.setStartBefore(startChop.parentNode);
       
  7109 		} else {
       
  7110 			if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0)
       
  7111 				rng.setStartBefore(rngBefore.startContainer);
       
  7112 			else
       
  7113 				rng.setStart(rngBefore.startContainer, rngBefore.startOffset);
       
  7114 		}
       
  7115 
       
  7116 		if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName)
       
  7117 			rng.setEndAfter(endChop.parentNode);
       
  7118 		else
       
  7119 			rng.setEnd(rngAfter.endContainer, rngAfter.endOffset);
       
  7120 
       
  7121 		// Delete all contents and insert new paragraphs
       
  7122 		rng.deleteContents();
       
  7123 
       
  7124 		if (tinyMCE.isOpera) {
       
  7125 			rng.insertNode(paraBefore);
       
  7126 			rng.insertNode(paraAfter);
       
  7127 		} else {
       
  7128 			rng.insertNode(paraAfter);
       
  7129 			rng.insertNode(paraBefore);
       
  7130 		}
       
  7131 
       
  7132 		//tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML);
       
  7133 
       
  7134 		// Normalize
       
  7135 		paraAfter.normalize();
       
  7136 		paraBefore.normalize();
       
  7137 
       
  7138 		inst.selection.moveToBookmark(b);
       
  7139 		inst.selection.selectNode(paraAfter, true, true);
       
  7140 
       
  7141 		return true;
       
  7142 	},
       
  7143 
       
  7144 	_handleBackSpace : function(inst) {
       
  7145 		var r = inst.getRng(), sn = r.startContainer, nv, s = false;
       
  7146 
       
  7147 		// Added body check for bug #1527787
       
  7148 		if (sn && sn.nextSibling && sn.nextSibling.nodeName == "BR" && sn.parentNode.nodeName != "BODY") {
       
  7149 			nv = sn.nodeValue;
       
  7150 
       
  7151 			// Handle if a backspace is pressed after a space character #bug 1466054 removed since fix for #1527787
       
  7152 			/*if (nv != null && nv.length >= r.startOffset && nv.charAt(r.startOffset - 1) == ' ')
       
  7153 				s = true;*/
       
  7154 
       
  7155 			// Only remove BRs if we are at the end of line #bug 1464152
       
  7156 			if (nv != null && r.startOffset == nv.length)
       
  7157 				sn.nextSibling.parentNode.removeChild(sn.nextSibling);
       
  7158 		}
       
  7159 
       
  7160 		if (inst.settings.auto_resize)
       
  7161 			inst.resizeToContent();
       
  7162 
       
  7163 		return s;
       
  7164 	}
       
  7165 
       
  7166 	};
       
  7167 
       
  7168 /* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */
       
  7169 
       
  7170 function TinyMCE_Layer(id, bm) {
       
  7171 	this.id = id;
       
  7172 	this.blockerElement = null;
       
  7173 	this.events = false;
       
  7174 	this.element = null;
       
  7175 	this.blockMode = typeof(bm) != 'undefined' ? bm : true;
       
  7176 	this.doc = document;
       
  7177 };
       
  7178 
       
  7179 TinyMCE_Layer.prototype = {
       
  7180 	moveRelativeTo : function(re, p) {
       
  7181 		var rep = this.getAbsPosition(re);
       
  7182 		var w = parseInt(re.offsetWidth);
       
  7183 		var h = parseInt(re.offsetHeight);
       
  7184 		var e = this.getElement();
       
  7185 		var ew = parseInt(e.offsetWidth);
       
  7186 		var eh = parseInt(e.offsetHeight);
       
  7187 		var x, y;
       
  7188 
       
  7189 		switch (p) {
       
  7190 			case "tl":
       
  7191 				x = rep.absLeft;
       
  7192 				y = rep.absTop;
       
  7193 				break;
       
  7194 
       
  7195 			case "tr":
       
  7196 				x = rep.absLeft + w;
       
  7197 				y = rep.absTop;
       
  7198 				break;
       
  7199 
       
  7200 			case "bl":
       
  7201 				x = rep.absLeft;
       
  7202 				y = rep.absTop + h;
       
  7203 				break;
       
  7204 
       
  7205 			case "br":
       
  7206 				x = rep.absLeft + w;
       
  7207 				y = rep.absTop + h;
       
  7208 				break;
       
  7209 
       
  7210 			case "cc":
       
  7211 				x = rep.absLeft + (w / 2) - (ew / 2);
       
  7212 				y = rep.absTop + (h / 2) - (eh / 2);
       
  7213 				break;
       
  7214 		}
       
  7215 
       
  7216 		this.moveTo(x, y);
       
  7217 	},
       
  7218 
       
  7219 	moveBy : function(x, y) {
       
  7220 		var e = this.getElement();
       
  7221 		this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y);
       
  7222 	},
       
  7223 
       
  7224 	moveTo : function(x, y) {
       
  7225 		var e = this.getElement();
       
  7226 
       
  7227 		e.style.left = x + "px";
       
  7228 		e.style.top = y + "px";
       
  7229 
       
  7230 		this.updateBlocker();
       
  7231 	},
       
  7232 
       
  7233 	resizeBy : function(w, h) {
       
  7234 		var e = this.getElement();
       
  7235 		this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h);
       
  7236 	},
       
  7237 
       
  7238 	resizeTo : function(w, h) {
       
  7239 		var e = this.getElement();
       
  7240 
       
  7241 		if (w != null)
       
  7242 			e.style.width = w + "px";
       
  7243 
       
  7244 		if (h != null)
       
  7245 			e.style.height = h + "px";
       
  7246 
       
  7247 		this.updateBlocker();
       
  7248 	},
       
  7249 
       
  7250 	show : function() {
       
  7251 		var el = this.getElement();
       
  7252 
       
  7253 		if (el) {
       
  7254 			el.style.display = 'block';
       
  7255 			this.updateBlocker();
       
  7256 		}
       
  7257 	},
       
  7258 
       
  7259 	hide : function() {
       
  7260 		var el = this.getElement();
       
  7261 
       
  7262 		if (el) {
       
  7263 			el.style.display = 'none';
       
  7264 			this.updateBlocker();
       
  7265 		}
       
  7266 	},
       
  7267 
       
  7268 	isVisible : function() {
       
  7269 		return this.getElement().style.display == 'block';
       
  7270 	},
       
  7271 
       
  7272 	getElement : function() {
       
  7273 		if (!this.element)
       
  7274 			this.element = this.doc.getElementById(this.id);
       
  7275 
       
  7276 		return this.element;
       
  7277 	},
       
  7278 
       
  7279 	setBlockMode : function(s) {
       
  7280 		this.blockMode = s;
       
  7281 	},
       
  7282 
       
  7283 	updateBlocker : function() {
       
  7284 		var e, b, x, y, w, h;
       
  7285 
       
  7286 		b = this.getBlocker();
       
  7287 		if (b) {
       
  7288 			if (this.blockMode) {
       
  7289 				e = this.getElement();
       
  7290 				x = this.parseInt(e.style.left);
       
  7291 				y = this.parseInt(e.style.top);
       
  7292 				w = this.parseInt(e.offsetWidth);
       
  7293 				h = this.parseInt(e.offsetHeight);
       
  7294 
       
  7295 				b.style.left = x + 'px';
       
  7296 				b.style.top = y + 'px';
       
  7297 				b.style.width = w + 'px';
       
  7298 				b.style.height = h + 'px';
       
  7299 				b.style.display = e.style.display;
       
  7300 			} else
       
  7301 				b.style.display = 'none';
       
  7302 		}
       
  7303 	},
       
  7304 
       
  7305 	getBlocker : function() {
       
  7306 		var d, b;
       
  7307 
       
  7308 		if (!this.blockerElement && this.blockMode) {
       
  7309 			d = this.doc;
       
  7310 			b = d.getElementById(this.id + "_blocker");
       
  7311 
       
  7312 			if (!b) {
       
  7313 				b = d.createElement("iframe");
       
  7314 
       
  7315 				b.setAttribute('id', this.id + "_blocker");
       
  7316 				b.style.cssText = 'display: none; position: absolute; left: 0; top: 0';
       
  7317 				b.src = 'javascript:false;';
       
  7318 				b.frameBorder = '0';
       
  7319 				b.scrolling = 'no';
       
  7320 	
       
  7321 				d.body.appendChild(b);
       
  7322 			}
       
  7323 
       
  7324 			this.blockerElement = b;
       
  7325 		}
       
  7326 
       
  7327 		return this.blockerElement;
       
  7328 	},
       
  7329 
       
  7330 	getAbsPosition : function(n) {
       
  7331 		var p = {absLeft : 0, absTop : 0};
       
  7332 
       
  7333 		while (n) {
       
  7334 			p.absLeft += n.offsetLeft;
       
  7335 			p.absTop += n.offsetTop;
       
  7336 			n = n.offsetParent;
       
  7337 		}
       
  7338 
       
  7339 		return p;
       
  7340 	},
       
  7341 
       
  7342 	create : function(n, c, p, h) {
       
  7343 		var d = this.doc, e = d.createElement(n);
       
  7344 
       
  7345 		e.setAttribute('id', this.id);
       
  7346 
       
  7347 		if (c)
       
  7348 			e.className = c;
       
  7349 
       
  7350 		if (!p)
       
  7351 			p = d.body;
       
  7352 
       
  7353 		if (h)
       
  7354 			e.innerHTML = h;
       
  7355 
       
  7356 		p.appendChild(e);
       
  7357 
       
  7358 		return this.element = e;
       
  7359 	},
       
  7360 
       
  7361 	exists : function() {
       
  7362 		return this.doc.getElementById(this.id) != null;
       
  7363 	},
       
  7364 
       
  7365 	parseInt : function(s) {
       
  7366 		if (s == null || s == '')
       
  7367 			return 0;
       
  7368 
       
  7369 		return parseInt(s);
       
  7370 	},
       
  7371 
       
  7372 	remove : function() {
       
  7373 		var e = this.getElement(), b = this.getBlocker();
       
  7374 
       
  7375 		if (e)
       
  7376 			e.parentNode.removeChild(e);
       
  7377 
       
  7378 		if (b)
       
  7379 			b.parentNode.removeChild(b);
       
  7380 	}
       
  7381 
       
  7382 	};
       
  7383 
       
  7384 /* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */
       
  7385 
       
  7386 function TinyMCE_Menu() {
       
  7387 	var id;
       
  7388 
       
  7389 	if (typeof(tinyMCE.menuCounter) == "undefined")
       
  7390 		tinyMCE.menuCounter = 0;
       
  7391 
       
  7392 	id = "mc_menu_" + tinyMCE.menuCounter++;
       
  7393 
       
  7394 	TinyMCE_Layer.call(this, id, true);
       
  7395 
       
  7396 	this.id = id;
       
  7397 	this.items = new Array();
       
  7398 	this.needsUpdate = true;
       
  7399 };
       
  7400 
       
  7401 TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, {
       
  7402 	init : function(s) {
       
  7403 		var n;
       
  7404 
       
  7405 		// Default params
       
  7406 		this.settings = {
       
  7407 			separator_class : 'mceMenuSeparator',
       
  7408 			title_class : 'mceMenuTitle',
       
  7409 			disabled_class : 'mceMenuDisabled',
       
  7410 			menu_class : 'mceMenu',
       
  7411 			drop_menu : true
       
  7412 		};
       
  7413 
       
  7414 		for (n in s)
       
  7415 			this.settings[n] = s[n];
       
  7416 
       
  7417 		this.create('div', this.settings.menu_class);
       
  7418 	},
       
  7419 
       
  7420 	clear : function() {
       
  7421 		this.items = new Array();
       
  7422 	},
       
  7423 
       
  7424 	addTitle : function(t) {
       
  7425 		this.add({type : 'title', text : t});
       
  7426 	},
       
  7427 
       
  7428 	addDisabled : function(t) {
       
  7429 		this.add({type : 'disabled', text : t});
       
  7430 	},
       
  7431 
       
  7432 	addSeparator : function() {
       
  7433 		this.add({type : 'separator'});
       
  7434 	},
       
  7435 
       
  7436 	addItem : function(t, js) {
       
  7437 		this.add({text : t, js : js});
       
  7438 	},
       
  7439 
       
  7440 	add : function(mi) {
       
  7441 		this.items[this.items.length] = mi;
       
  7442 		this.needsUpdate = true;
       
  7443 	},
       
  7444 
       
  7445 	update : function() {
       
  7446 		var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings;
       
  7447 
       
  7448 		if (this.settings.drop_menu)
       
  7449 			h += '<span class="mceMenuLine"></span>';
       
  7450 
       
  7451 		h += '<table border="0" cellpadding="0" cellspacing="0">';
       
  7452 
       
  7453 		for (i=0; i<m.length; i++) {
       
  7454 			t = tinyMCE.xmlEncode(m[i].text);
       
  7455 			c = m[i].class_name ? ' class="' + m[i].class_name + '"' : '';
       
  7456 
       
  7457 			switch (m[i].type) {
       
  7458 				case 'separator':
       
  7459 					h += '<tr class="' + s.separator_class + '"><td>';
       
  7460 					break;
       
  7461 
       
  7462 				case 'title':
       
  7463 					h += '<tr class="' + s.title_class + '"><td><span' + c +'>' + t + '</span>';
       
  7464 					break;
       
  7465 
       
  7466 				case 'disabled':
       
  7467 					h += '<tr class="' + s.disabled_class + '"><td><span' + c +'>' + t + '</span>';
       
  7468 					break;
       
  7469 
       
  7470 				default:
       
  7471 					h += '<tr><td><a href="' + tinyMCE.xmlEncode(m[i].js) + '" onmousedown="' + tinyMCE.xmlEncode(m[i].js) + ';return tinyMCE.cancelEvent(event);" onclick="return tinyMCE.cancelEvent(event);" onmouseup="return tinyMCE.cancelEvent(event);"><span' + c +'>' + t + '</span></a>';
       
  7472 			}
       
  7473 
       
  7474 			h += '</td></tr>';
       
  7475 		}
       
  7476 
       
  7477 		h += '</table>';
       
  7478 
       
  7479 		e.innerHTML = h;
       
  7480 
       
  7481 		this.needsUpdate = false;
       
  7482 		this.updateBlocker();
       
  7483 	},
       
  7484 
       
  7485 	show : function() {
       
  7486 		var nl, i;
       
  7487 
       
  7488 		if (tinyMCE.lastMenu == this)
       
  7489 			return;
       
  7490 
       
  7491 		if (this.needsUpdate)
       
  7492 			this.update();
       
  7493 
       
  7494 		if (tinyMCE.lastMenu && tinyMCE.lastMenu != this)
       
  7495 			tinyMCE.lastMenu.hide();
       
  7496 
       
  7497 		TinyMCE_Layer.prototype.show.call(this);
       
  7498 
       
  7499 		if (!tinyMCE.isOpera) {
       
  7500 			// Accessibility stuff
       
  7501 /*			nl = this.getElement().getElementsByTagName("a");
       
  7502 			if (nl.length > 0)
       
  7503 				nl[0].focus();*/
       
  7504 		}
       
  7505 
       
  7506 		tinyMCE.lastMenu = this;
       
  7507 	}
       
  7508 
       
  7509 	});
       
  7510 
       
  7511 /* file:jscripts/tiny_mce/classes/TinyMCE_Compatibility.class.js */
       
  7512 
       
  7513 if (!Function.prototype.call) {
       
  7514 	Function.prototype.call = function() {
       
  7515 		var a = arguments, s = a[0], i, as = '', r, o;
       
  7516 
       
  7517 		for (i=1; i<a.length; i++)
       
  7518 			as += (i > 1 ? ',' : '') + 'a[' + i + ']';
       
  7519 
       
  7520 		o = s._fu;
       
  7521 		s._fu = this;
       
  7522 		r = eval('s._fu(' + as + ')');
       
  7523 		s._fu = o;
       
  7524 
       
  7525 		return r;
       
  7526 	};
       
  7527 };
       
  7528 
       
  7529 /* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */
       
  7530 
       
  7531 TinyMCE_Engine.prototype.debug = function() {
       
  7532 	var m = "", a, i, l = tinyMCE.log.length;
       
  7533 
       
  7534 	for (i=0, a = this.debug.arguments; i<a.length; i++) {
       
  7535 		m += a[i];
       
  7536 
       
  7537 		if (i<a.length-1)
       
  7538 			m += ', ';
       
  7539 	}
       
  7540 
       
  7541 	if (l < 1000)
       
  7542 		tinyMCE.log[l] = "[debug] " + m;
       
  7543 };
       
  7544