|
1 |
|
2 /* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */ |
|
3 |
|
4 function TinyMCE_Engine() { |
|
5 var ua; |
|
6 |
|
7 this.majorVersion = "2"; |
|
8 this.minorVersion = "1.0"; |
|
9 this.releaseDate = "2007-02-13"; |
|
10 |
|
11 this.instances = new Array(); |
|
12 this.switchClassCache = new Array(); |
|
13 this.windowArgs = new Array(); |
|
14 this.loadedFiles = new Array(); |
|
15 this.pendingFiles = new Array(); |
|
16 this.loadingIndex = 0; |
|
17 this.configs = new Array(); |
|
18 this.currentConfig = 0; |
|
19 this.eventHandlers = new Array(); |
|
20 this.log = new Array(); |
|
21 this.undoLevels = []; |
|
22 this.undoIndex = 0; |
|
23 this.typingUndoIndex = -1; |
|
24 |
|
25 // Browser check |
|
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; |
|
66 |
|
67 this.settings = settings; |
|
68 |
|
69 // Check if valid browser has execcommand support |
|
70 if (typeof(document.execCommand) == 'undefined') |
|
71 return; |
|
72 |
|
73 // Get script base path |
|
74 if (!tinyMCE.baseURL) { |
|
75 var elements = document.getElementsByTagName('script'); |
|
76 |
|
77 // If base element found, add that infront of baseURL |
|
78 nl = document.getElementsByTagName('base'); |
|
79 for (i=0; i<nl.length; i++) { |
|
80 if (nl[i].href) |
|
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 } |
|
105 |
|
106 // Get document base path |
|
107 this.documentBasePath = document.location.href; |
|
108 if (this.documentBasePath.indexOf('?') != -1) |
|
109 this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?')); |
|
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 } |
|
118 |
|
119 // Set default values on settings |
|
120 this._def("mode", "none"); |
|
121 this._def("theme", "advanced"); |
|
122 this._def("plugins", "", true); |
|
123 this._def("language", "en"); |
|
124 this._def("docs_language", this.settings['language']); |
|
125 this._def("elements", ""); |
|
126 this._def("textarea_trigger", "mce_editable"); |
|
127 this._def("editor_selector", ""); |
|
128 this._def("editor_deselector", "mceNoEditor"); |
|
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]"); |
|
130 this._def("extended_valid_elements", ""); |
|
131 this._def("invalid_elements", ""); |
|
132 this._def("encoding", ""); |
|
133 this._def("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE_Engine.prototype.convertURL")); |
|
134 this._def("save_callback", ""); |
|
135 this._def("debug", false); |
|
136 this._def("force_br_newlines", false); |
|
137 this._def("force_p_newlines", true); |
|
138 this._def("add_form_submit_trigger", true); |
|
139 this._def("relative_urls", true); |
|
140 this._def("remove_script_host", true); |
|
141 this._def("focus_alert", true); |
|
142 this._def("document_base_url", this.documentURL); |
|
143 this._def("visual", true); |
|
144 this._def("visual_table_class", "mceVisualAid"); |
|
145 this._def("setupcontent_callback", ""); |
|
146 this._def("fix_content_duplication", true); |
|
147 this._def("custom_undo_redo", true); |
|
148 this._def("custom_undo_redo_levels", -1); |
|
149 this._def("custom_undo_redo_keyboard_shortcuts", true); |
|
150 this._def("custom_undo_redo_restore_selection", true); |
|
151 this._def("custom_undo_redo_global", false); |
|
152 this._def("verify_html", true); |
|
153 this._def("apply_source_formatting", false); |
|
154 this._def("directionality", "ltr"); |
|
155 this._def("cleanup_on_startup", false); |
|
156 this._def("inline_styles", false); |
|
157 this._def("convert_newlines_to_brs", false); |
|
158 this._def("auto_reset_designmode", true); |
|
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); |
|
160 this._def("entity_encoding", "named"); |
|
161 this._def("cleanup_callback", ""); |
|
162 this._def("add_unload_trigger", true); |
|
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 } |
|
231 |
|
232 // Trim away query part |
|
233 if (baseHREF.indexOf('?') != -1) |
|
234 baseHREF = baseHREF.substring(0, baseHREF.indexOf('?')); |
|
235 |
|
236 this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/"; |
|
237 |
|
238 theme = this.settings['theme']; |
|
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 = {'&':'&','"':'"',"'":''','<':'<','>':'>'}; |
|
347 }, |
|
348 |
|
349 _addUnloadEvents : function() { |
|
350 if (tinyMCE.isIE) { |
|
351 if (tinyMCE.settings['add_unload_trigger']) { |
|
352 tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler); |
|
353 tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler); |
|
354 } |
|
355 } else { |
|
356 if (tinyMCE.settings['add_unload_trigger']) |
|
357 tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);}); |
|
358 } |
|
359 }, |
|
360 |
|
361 _def : function(key, def_val, t) { |
|
362 var v = tinyMCE.getParam(key, def_val); |
|
363 |
|
364 v = t ? v.replace(/\s+/g, "") : v; |
|
365 |
|
366 this.settings[key] = v; |
|
367 }, |
|
368 |
|
369 hasPlugin : function(n) { |
|
370 return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; |
|
371 }, |
|
372 |
|
373 addPlugin : function(n, p) { |
|
374 var op = this.plugins[n]; |
|
375 |
|
376 // Use the previous plugin object base URL used when loading external plugins |
|
377 p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n; |
|
378 this.plugins[n] = p; |
|
379 |
|
380 this.loadNextScript(); |
|
381 }, |
|
382 |
|
383 setPluginBaseURL : function(n, u) { |
|
384 var op = this.plugins[n]; |
|
385 |
|
386 if (op) |
|
387 op.baseURL = u; |
|
388 else |
|
389 this.plugins[n] = {baseURL : u}; |
|
390 }, |
|
391 |
|
392 loadPlugin : function(n, u) { |
|
393 u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u; |
|
394 u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u; |
|
395 this.plugins[n] = {baseURL : u}; |
|
396 this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js"); |
|
397 }, |
|
398 |
|
399 hasTheme : function(n) { |
|
400 return typeof(this.themes[n]) != "undefined" && this.themes[n] != null; |
|
401 }, |
|
402 |
|
403 addTheme : function(n, t) { |
|
404 this.themes[n] = t; |
|
405 |
|
406 this.loadNextScript(); |
|
407 }, |
|
408 |
|
409 addMenu : function(n, m) { |
|
410 this.menus[n] = m; |
|
411 }, |
|
412 |
|
413 hasMenu : function(n) { |
|
414 return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; |
|
415 }, |
|
416 |
|
417 loadScript : function(url) { |
|
418 var i; |
|
419 |
|
420 for (i=0; i<this.loadedFiles.length; i++) { |
|
421 if (this.loadedFiles[i] == url) |
|
422 return; |
|
423 } |
|
424 |
|
425 if (tinyMCE.settings.strict_loading_mode) |
|
426 this.pendingFiles[this.pendingFiles.length] = url; |
|
427 else |
|
428 { |
|
429 document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>'); |
|
430 } |
|
431 |
|
432 this.loadedFiles[this.loadedFiles.length] = url; |
|
433 }, |
|
434 |
|
435 loadNextScript : function() { |
|
436 var d = document, se; |
|
437 |
|
438 if (!tinyMCE.settings.strict_loading_mode) |
|
439 return; |
|
440 |
|
441 if (this.loadingIndex < this.pendingFiles.length) { |
|
442 se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script'); |
|
443 se.setAttribute('language', 'javascript'); |
|
444 se.setAttribute('type', 'text/javascript'); |
|
445 se.setAttribute('src', this.pendingFiles[this.loadingIndex++]); |
|
446 |
|
447 d.getElementsByTagName("head")[0].appendChild(se); |
|
448 } else |
|
449 this.loadingIndex = -1; // Done with loading |
|
450 }, |
|
451 |
|
452 loadCSS : function(url) { |
|
453 var ar = url.replace(/\s+/, '').split(','); |
|
454 var lflen = 0, csslen = 0; |
|
455 var skip = false; |
|
456 var x = 0, i = 0, nl, le; |
|
457 |
|
458 for (x = 0,csslen = ar.length; x<csslen; x++) { |
|
459 if (ar[x] != null && ar[x] != 'null' && ar[x].length > 0) { |
|
460 /* Make sure it doesn't exist. */ |
|
461 for (i=0, lflen=this.loadedFiles.length; i<lflen; i++) { |
|
462 if (this.loadedFiles[i] == ar[x]) { |
|
463 skip = true; |
|
464 break; |
|
465 } |
|
466 } |
|
467 |
|
468 if (!skip) { |
|
469 if (tinyMCE.settings.strict_loading_mode) { |
|
470 nl = document.getElementsByTagName("head"); |
|
471 |
|
472 le = document.createElement('link'); |
|
473 le.setAttribute('href', ar[x]); |
|
474 le.setAttribute('rel', 'stylesheet'); |
|
475 le.setAttribute('type', 'text/css'); |
|
476 |
|
477 nl[0].appendChild(le); |
|
478 } else |
|
479 { |
|
480 document.write('<link href="' + ar[x] + '" rel="stylesheet" type="text/css" />'); |
|
481 } |
|
482 |
|
483 this.loadedFiles[this.loadedFiles.length] = ar[x]; |
|
484 } |
|
485 } |
|
486 } |
|
487 }, |
|
488 |
|
489 importCSS : function(doc, css) { |
|
490 var css_ary = css.replace(/\s+/, '').split(','); |
|
491 var csslen, elm, headArr, x, css_file; |
|
492 |
|
493 for (x = 0, csslen = css_ary.length; x<csslen; x++) { |
|
494 css_file = css_ary[x]; |
|
495 |
|
496 if (css_file != null && css_file != 'null' && css_file.length > 0) { |
|
497 // Is relative, make absolute |
|
498 if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/') |
|
499 css_file = this.documentBasePath + "/" + css_file; |
|
500 |
|
501 if (typeof(doc.createStyleSheet) == "undefined") { |
|
502 elm = doc.createElement("link"); |
|
503 |
|
504 elm.rel = "stylesheet"; |
|
505 elm.href = css_file; |
|
506 |
|
507 if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0) |
|
508 headArr[0].appendChild(elm); |
|
509 } else |
|
510 doc.createStyleSheet(css_file); |
|
511 } |
|
512 } |
|
513 }, |
|
514 |
|
515 confirmAdd : function(e, settings) { |
|
516 var elm = tinyMCE.isIE ? event.srcElement : e.target; |
|
517 var elementId = elm.name ? elm.name : elm.id; |
|
518 |
|
519 tinyMCE.settings = settings; |
|
520 |
|
521 if (tinyMCE.settings['convert_on_click'] || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm']))) |
|
522 tinyMCE.addMCEControl(elm, elementId); |
|
523 |
|
524 elm.setAttribute('mce_noask', 'true'); |
|
525 }, |
|
526 |
|
527 updateContent : function(form_element_name) { |
|
528 // Find MCE instance linked to given form element and copy it's value |
|
529 var formElement = document.getElementById(form_element_name); |
|
530 for (var n in tinyMCE.instances) { |
|
531 var inst = tinyMCE.instances[n]; |
|
532 if (!tinyMCE.isInstance(inst)) |
|
533 continue; |
|
534 |
|
535 inst.switchSettings(); |
|
536 |
|
537 if (inst.formElement == formElement) { |
|
538 var doc = inst.getDoc(); |
|
539 |
|
540 tinyMCE._setHTML(doc, inst.formElement.value); |
|
541 |
|
542 if (!tinyMCE.isIE) |
|
543 doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid); |
|
544 } |
|
545 } |
|
546 }, |
|
547 |
|
548 addMCEControl : function(replace_element, form_element_name, target_document) { |
|
549 var id = "mce_editor_" + tinyMCE.idCounter++; |
|
550 var inst = new TinyMCE_Control(tinyMCE.settings); |
|
551 |
|
552 inst.editorId = id; |
|
553 this.instances[id] = inst; |
|
554 |
|
555 inst._onAdd(replace_element, form_element_name, target_document); |
|
556 }, |
|
557 |
|
558 removeInstance : function(ti) { |
|
559 var t = [], n, i; |
|
560 |
|
561 // Remove from instances |
|
562 for (n in tinyMCE.instances) { |
|
563 i = tinyMCE.instances[n]; |
|
564 |
|
565 if (tinyMCE.isInstance(i) && ti != i) |
|
566 t[n] = i; |
|
567 } |
|
568 |
|
569 tinyMCE.instances = t; |
|
570 |
|
571 // Remove from global undo/redo |
|
572 n = []; |
|
573 t = tinyMCE.undoLevels; |
|
574 |
|
575 for (i=0; i<t.length; i++) { |
|
576 if (t[i] != ti) |
|
577 n.push(t[i]); |
|
578 } |
|
579 |
|
580 tinyMCE.undoLevels = n; |
|
581 tinyMCE.undoIndex = n.length; |
|
582 |
|
583 // Dispatch remove instance call |
|
584 tinyMCE.dispatchCallback(ti, 'remove_instance_callback', 'removeInstance', ti); |
|
585 |
|
586 return ti; |
|
587 }, |
|
588 |
|
589 removeMCEControl : function(editor_id) { |
|
590 var inst = tinyMCE.getInstanceById(editor_id), h, re, ot, tn; |
|
591 |
|
592 if (inst) { |
|
593 inst.switchSettings(); |
|
594 |
|
595 editor_id = inst.editorId; |
|
596 h = tinyMCE.getContent(editor_id); |
|
597 |
|
598 this.removeInstance(inst); |
|
599 |
|
600 tinyMCE.selectedElement = null; |
|
601 tinyMCE.selectedInstance = null; |
|
602 |
|
603 // Remove element |
|
604 re = document.getElementById(editor_id + "_parent"); |
|
605 ot = inst.oldTargetElement; |
|
606 tn = ot.nodeName.toLowerCase(); |
|
607 |
|
608 if (tn == "textarea" || tn == "input") { |
|
609 re.parentNode.removeChild(re); |
|
610 ot.style.display = "inline"; |
|
611 ot.value = h; |
|
612 } else { |
|
613 ot.innerHTML = h; |
|
614 ot.style.display = 'block'; |
|
615 re.parentNode.insertBefore(ot, re); |
|
616 re.parentNode.removeChild(re); |
|
617 } |
|
618 } |
|
619 }, |
|
620 |
|
621 triggerSave : function(skip_cleanup, skip_callback) { |
|
622 var inst, n; |
|
623 |
|
624 // Default to false |
|
625 if (typeof(skip_cleanup) == "undefined") |
|
626 skip_cleanup = false; |
|
627 |
|
628 // Default to false |
|
629 if (typeof(skip_callback) == "undefined") |
|
630 skip_callback = false; |
|
631 |
|
632 // Cleanup and set all form fields |
|
633 for (n in tinyMCE.instances) { |
|
634 inst = tinyMCE.instances[n]; |
|
635 |
|
636 if (!tinyMCE.isInstance(inst)) |
|
637 continue; |
|
638 |
|
639 inst.triggerSave(skip_cleanup, skip_callback); |
|
640 } |
|
641 }, |
|
642 |
|
643 resetForm : function(form_index) { |
|
644 var i, inst, n, formObj = document.forms[form_index]; |
|
645 |
|
646 for (n in tinyMCE.instances) { |
|
647 inst = tinyMCE.instances[n]; |
|
648 |
|
649 if (!tinyMCE.isInstance(inst)) |
|
650 continue; |
|
651 |
|
652 inst.switchSettings(); |
|
653 |
|
654 for (i=0; i<formObj.elements.length; i++) { |
|
655 if (inst.formTargetElementId == formObj.elements[i].name) |
|
656 inst.getBody().innerHTML = inst.startContent; |
|
657 } |
|
658 } |
|
659 }, |
|
660 |
|
661 execInstanceCommand : function(editor_id, command, user_interface, value, focus) { |
|
662 var inst = tinyMCE.getInstanceById(editor_id), r; |
|
663 |
|
664 if (inst) { |
|
665 r = inst.selection.getRng(); |
|
666 |
|
667 if (typeof(focus) == "undefined") |
|
668 focus = true; |
|
669 |
|
670 // IE bug lost focus on images in absolute divs Bug #1534575 |
|
671 if (focus && (!r || !r.item)) |
|
672 inst.contentWindow.focus(); |
|
673 |
|
674 // Reset design mode if lost |
|
675 inst.autoResetDesignMode(); |
|
676 |
|
677 this.selectedElement = inst.getFocusElement(); |
|
678 inst.select(); |
|
679 tinyMCE.execCommand(command, user_interface, value); |
|
680 |
|
681 // Cancel event so it doesn't call onbeforeonunlaod |
|
682 if (tinyMCE.isIE && window.event != null) |
|
683 tinyMCE.cancelEvent(window.event); |
|
684 } |
|
685 }, |
|
686 |
|
687 execCommand : function(command, user_interface, value) { |
|
688 var inst = tinyMCE.selectedInstance; |
|
689 |
|
690 // Default input |
|
691 user_interface = user_interface ? user_interface : false; |
|
692 value = value ? value : null; |
|
693 |
|
694 if (inst) |
|
695 inst.switchSettings(); |
|
696 |
|
697 switch (command) { |
|
698 case "Undo": |
|
699 if (this.getParam('custom_undo_redo_global')) { |
|
700 if (this.undoIndex > 0) { |
|
701 tinyMCE.nextUndoRedoAction = 'Undo'; |
|
702 inst = this.undoLevels[--this.undoIndex]; |
|
703 inst.select(); |
|
704 |
|
705 if (!tinyMCE.nextUndoRedoInstanceId) |
|
706 inst.execCommand('Undo'); |
|
707 } |
|
708 } else |
|
709 inst.execCommand('Undo'); |
|
710 return true; |
|
711 |
|
712 case "Redo": |
|
713 if (this.getParam('custom_undo_redo_global')) { |
|
714 if (this.undoIndex <= this.undoLevels.length - 1) { |
|
715 tinyMCE.nextUndoRedoAction = 'Redo'; |
|
716 inst = this.undoLevels[this.undoIndex++]; |
|
717 inst.select(); |
|
718 |
|
719 if (!tinyMCE.nextUndoRedoInstanceId) |
|
720 inst.execCommand('Redo'); |
|
721 } |
|
722 } else |
|
723 inst.execCommand('Redo'); |
|
724 |
|
725 return true; |
|
726 |
|
727 case 'mceFocus': |
|
728 var inst = tinyMCE.getInstanceById(value); |
|
729 if (inst) |
|
730 inst.getWin().focus(); |
|
731 return; |
|
732 |
|
733 case "mceAddControl": |
|
734 case "mceAddEditor": |
|
735 tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); |
|
736 return; |
|
737 |
|
738 case "mceAddFrameControl": |
|
739 tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'], value['document']), value['element'], value['document']); |
|
740 return; |
|
741 |
|
742 case "mceRemoveControl": |
|
743 case "mceRemoveEditor": |
|
744 tinyMCE.removeMCEControl(value); |
|
745 return; |
|
746 |
|
747 case "mceToggleEditor": |
|
748 var inst = tinyMCE.getInstanceById(value), pe, te; |
|
749 |
|
750 if (inst) { |
|
751 pe = document.getElementById(inst.editorId + '_parent'); |
|
752 te = inst.oldTargetElement; |
|
753 |
|
754 if (typeof(inst.enabled) == 'undefined') |
|
755 inst.enabled = true; |
|
756 |
|
757 inst.enabled = !inst.enabled; |
|
758 |
|
759 if (!inst.enabled) { |
|
760 pe.style.display = 'none'; |
|
761 te.value = inst.getHTML(); |
|
762 te.style.display = inst.oldTargetDisplay; |
|
763 tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst); |
|
764 } else { |
|
765 pe.style.display = 'block'; |
|
766 te.style.display = 'none'; |
|
767 inst.setHTML(te.value); |
|
768 inst.useCSS = false; |
|
769 tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst); |
|
770 } |
|
771 } else |
|
772 tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); |
|
773 |
|
774 return; |
|
775 |
|
776 case "mceResetDesignMode": |
|
777 // Resets the designmode state of the editors in Gecko |
|
778 if (!tinyMCE.isIE) { |
|
779 for (var n in tinyMCE.instances) { |
|
780 if (!tinyMCE.isInstance(tinyMCE.instances[n])) |
|
781 continue; |
|
782 |
|
783 try { |
|
784 tinyMCE.instances[n].getDoc().designMode = "on"; |
|
785 } catch (e) { |
|
786 // Ignore any errors |
|
787 } |
|
788 } |
|
789 } |
|
790 |
|
791 return; |
|
792 } |
|
793 |
|
794 if (inst) { |
|
795 inst.execCommand(command, user_interface, value); |
|
796 } else if (tinyMCE.settings['focus_alert']) |
|
797 alert(tinyMCELang['lang_focus_alert']); |
|
798 }, |
|
799 |
|
800 _createIFrame : function(replace_element, doc, win) { |
|
801 var iframe, id = replace_element.getAttribute("id"); |
|
802 var aw, ah; |
|
803 |
|
804 if (typeof(doc) == "undefined") |
|
805 doc = document; |
|
806 |
|
807 if (typeof(win) == "undefined") |
|
808 win = window; |
|
809 |
|
810 iframe = doc.createElement("iframe"); |
|
811 |
|
812 aw = "" + tinyMCE.settings['area_width']; |
|
813 ah = "" + tinyMCE.settings['area_height']; |
|
814 |
|
815 if (aw.indexOf('%') == -1) { |
|
816 aw = parseInt(aw); |
|
817 aw = (isNaN(aw) || aw < 0) ? 300 : aw; |
|
818 aw = aw + "px"; |
|
819 } |
|
820 |
|
821 if (ah.indexOf('%') == -1) { |
|
822 ah = parseInt(ah); |
|
823 ah = (isNaN(ah) || ah < 0) ? 240 : ah; |
|
824 ah = ah + "px"; |
|
825 } |
|
826 |
|
827 iframe.setAttribute("id", id); |
|
828 iframe.setAttribute("name", id); |
|
829 iframe.setAttribute("class", "mceEditorIframe"); |
|
830 iframe.setAttribute("border", "0"); |
|
831 iframe.setAttribute("frameBorder", "0"); |
|
832 iframe.setAttribute("marginWidth", "0"); |
|
833 iframe.setAttribute("marginHeight", "0"); |
|
834 iframe.setAttribute("leftMargin", "0"); |
|
835 iframe.setAttribute("topMargin", "0"); |
|
836 iframe.setAttribute("width", aw); |
|
837 iframe.setAttribute("height", ah); |
|
838 iframe.setAttribute("allowtransparency", "true"); |
|
839 iframe.className = 'mceEditorIframe'; |
|
840 |
|
841 if (tinyMCE.settings["auto_resize"]) |
|
842 iframe.setAttribute("scrolling", "no"); |
|
843 |
|
844 // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs |
|
845 if (tinyMCE.isRealIE) |
|
846 iframe.setAttribute("src", this.settings['default_document']); |
|
847 |
|
848 iframe.style.width = aw; |
|
849 iframe.style.height = ah; |
|
850 |
|
851 // Ugly hack for Gecko problem in strict mode |
|
852 if (tinyMCE.settings.strict_loading_mode) |
|
853 iframe.style.marginBottom = '-5px'; |
|
854 |
|
855 // MSIE 5.0 issue |
|
856 if (tinyMCE.isRealIE) |
|
857 replace_element.outerHTML = iframe.outerHTML; |
|
858 else |
|
859 replace_element.parentNode.replaceChild(iframe, replace_element); |
|
860 |
|
861 if (tinyMCE.isRealIE) |
|
862 return win.frames[id]; |
|
863 else |
|
864 return iframe; |
|
865 }, |
|
866 |
|
867 setupContent : function(editor_id) { |
|
868 var inst = tinyMCE.instances[editor_id], i; |
|
869 var doc = inst.getDoc(); |
|
870 var head = doc.getElementsByTagName('head').item(0); |
|
871 var content = inst.startContent; |
|
872 |
|
873 // HTML values get XML encoded in strict mode |
|
874 if (tinyMCE.settings.strict_loading_mode) { |
|
875 content = content.replace(/</g, '<'); |
|
876 content = content.replace(/>/g, '>'); |
|
877 content = content.replace(/"/g, '"'); |
|
878 content = content.replace(/&/g, '&'); |
|
879 } |
|
880 |
|
881 tinyMCE.selectedInstance = inst; |
|
882 inst.switchSettings(); |
|
883 |
|
884 // Not loaded correctly hit it again, Mozilla bug #997860 |
|
885 if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") { |
|
886 // This part will remove the designMode status |
|
887 // Failes first time in Firefox 1.5b2 on Mac |
|
888 try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {} |
|
889 window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000); |
|
890 return; |
|
891 } |
|
892 |
|
893 if (!head) { |
|
894 window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10); |
|
895 return; |
|
896 } |
|
897 |
|
898 // Import theme specific content CSS the user specific |
|
899 tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css"); |
|
900 tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']); |
|
901 tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst); |
|
902 |
|
903 // Setup keyboard shortcuts |
|
904 if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) { |
|
905 inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo'); |
|
906 inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo'); |
|
907 } |
|
908 |
|
909 // BlockFormat shortcuts keys |
|
910 for (i=1; i<=6; i++) |
|
911 inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, '<h' + i + '>'); |
|
912 |
|
913 inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '<p>'); |
|
914 inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '<div>'); |
|
915 inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '<address>'); |
|
916 |
|
917 // Add default shortcuts for gecko |
|
918 if (tinyMCE.isGecko) { |
|
919 inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold'); |
|
920 inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic'); |
|
921 inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline'); |
|
922 } |
|
923 |
|
924 // Setup span styles |
|
925 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
926 inst.getBody().setAttribute('id', 'mceSpanFonts'); |
|
927 |
|
928 if (tinyMCE.settings['nowrap']) |
|
929 doc.body.style.whiteSpace = "nowrap"; |
|
930 |
|
931 doc.body.dir = this.settings['directionality']; |
|
932 doc.editorId = editor_id; |
|
933 |
|
934 // Add on document element in Mozilla |
|
935 if (!tinyMCE.isIE) |
|
936 doc.documentElement.editorId = editor_id; |
|
937 |
|
938 inst.setBaseHREF(tinyMCE.settings['base_href']); |
|
939 |
|
940 // Replace new line characters to BRs |
|
941 if (tinyMCE.settings['convert_newlines_to_brs']) { |
|
942 content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi"); |
|
943 content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi"); |
|
944 content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi"); |
|
945 } |
|
946 |
|
947 // Open closed anchors |
|
948 // content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>'); |
|
949 |
|
950 // Call custom cleanup code |
|
951 content = tinyMCE.storeAwayURLs(content); |
|
952 content = tinyMCE._customCleanup(inst, "insert_to_editor", content); |
|
953 |
|
954 if (tinyMCE.isIE) { |
|
955 // Ugly!!! |
|
956 window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500); |
|
957 |
|
958 if (tinyMCE.settings["force_br_newlines"]) |
|
959 doc.styleSheets[0].addRule("p", "margin: 0;"); |
|
960 |
|
961 var body = inst.getBody(); |
|
962 body.editorId = editor_id; |
|
963 } |
|
964 |
|
965 content = tinyMCE.cleanupHTMLCode(content); |
|
966 |
|
967 // Fix for bug #958637 |
|
968 if (!tinyMCE.isIE) { |
|
969 var contentElement = inst.getDoc().createElement("body"); |
|
970 var doc = inst.getDoc(); |
|
971 |
|
972 contentElement.innerHTML = content; |
|
973 |
|
974 // Remove weridness! |
|
975 if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt']) |
|
976 content = content.replace(new RegExp('<>', 'g'), ""); |
|
977 |
|
978 if (tinyMCE.settings['cleanup_on_startup']) |
|
979 tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement)); |
|
980 else |
|
981 tinyMCE.setInnerHTML(inst.getBody(), content); |
|
982 |
|
983 tinyMCE.convertAllRelativeURLs(inst.getBody()); |
|
984 } else { |
|
985 if (tinyMCE.settings['cleanup_on_startup']) { |
|
986 tinyMCE._setHTML(inst.getDoc(), content); |
|
987 |
|
988 // Produces permission denied error in MSIE 5.5 |
|
989 eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}'); |
|
990 } else |
|
991 tinyMCE._setHTML(inst.getDoc(), content); |
|
992 } |
|
993 |
|
994 // Fix for bug #957681 |
|
995 //inst.getDoc().designMode = inst.getDoc().designMode; |
|
996 |
|
997 tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst); |
|
998 tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); |
|
999 |
|
1000 // Re-add design mode on mozilla |
|
1001 if (!tinyMCE.isIE) |
|
1002 tinyMCE.addEventHandlers(inst); |
|
1003 |
|
1004 // Add blur handler |
|
1005 if (tinyMCE.isIE) { |
|
1006 tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch); |
|
1007 tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953 |
|
1008 |
|
1009 // Workaround for drag drop/copy paste base href bug |
|
1010 if (!tinyMCE.isOpera) { |
|
1011 tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove); |
|
1012 tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch); |
|
1013 tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch); |
|
1014 } |
|
1015 } |
|
1016 |
|
1017 // Trigger node change, this call locks buttons for tables and so forth |
|
1018 inst.select(); |
|
1019 tinyMCE.selectedElement = inst.contentWindow.document.body; |
|
1020 |
|
1021 // Call custom DOM cleanup |
|
1022 tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody()); |
|
1023 tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody()); |
|
1024 tinyMCE._setEventsEnabled(inst.getBody(), false); |
|
1025 tinyMCE.cleanupAnchors(inst.getDoc()); |
|
1026 |
|
1027 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
1028 tinyMCE.convertSpansToFonts(inst.getDoc()); |
|
1029 |
|
1030 inst.startContent = tinyMCE.trim(inst.getBody().innerHTML); |
|
1031 inst.undoRedo.add({ content : inst.startContent }); |
|
1032 |
|
1033 // Cleanup any mess left from storyAwayURLs |
|
1034 if (tinyMCE.isGecko) { |
|
1035 // Remove mce_src from textnodes and comments |
|
1036 tinyMCE.selectNodes(inst.getBody(), function(n) { |
|
1037 if (n.nodeType == 3 || n.nodeType == 8) |
|
1038 n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); |
|
1039 |
|
1040 return false; |
|
1041 }); |
|
1042 } |
|
1043 |
|
1044 // Remove Gecko spellchecking |
|
1045 if (tinyMCE.isGecko) |
|
1046 inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck"); |
|
1047 |
|
1048 // Cleanup any mess left from storyAwayURLs |
|
1049 tinyMCE._removeInternal(inst.getBody()); |
|
1050 |
|
1051 inst.select(); |
|
1052 tinyMCE.triggerNodeChange(false, true); |
|
1053 }, |
|
1054 |
|
1055 storeAwayURLs : function(s) { |
|
1056 // Remove all mce_src, mce_href and replace them with new ones |
|
1057 // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); |
|
1058 // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); |
|
1059 |
|
1060 if (!s.match(/(mce_src|mce_href)/gi, s)) { |
|
1061 s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"'); |
|
1062 s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"'); |
|
1063 } |
|
1064 |
|
1065 return s; |
|
1066 }, |
|
1067 |
|
1068 _removeInternal : function(n) { |
|
1069 if (tinyMCE.isGecko) { |
|
1070 // Remove mce_src from textnodes and comments |
|
1071 tinyMCE.selectNodes(n, function(n) { |
|
1072 if (n.nodeType == 3 || n.nodeType == 8) |
|
1073 n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); |
|
1074 |
|
1075 return false; |
|
1076 }); |
|
1077 } |
|
1078 }, |
|
1079 |
|
1080 removeTinyMCEFormElements : function(form_obj) { |
|
1081 var i, elementId; |
|
1082 |
|
1083 // Skip form element removal |
|
1084 if (!tinyMCE.getParam('hide_selects_on_submit')) |
|
1085 return; |
|
1086 |
|
1087 // Check if form is valid |
|
1088 if (typeof(form_obj) == "undefined" || form_obj == null) |
|
1089 return; |
|
1090 |
|
1091 // If not a form, find the form |
|
1092 if (form_obj.nodeName != "FORM") { |
|
1093 if (form_obj.form) |
|
1094 form_obj = form_obj.form; |
|
1095 else |
|
1096 form_obj = tinyMCE.getParentElement(form_obj, "form"); |
|
1097 } |
|
1098 |
|
1099 // Still nothing |
|
1100 if (form_obj == null) |
|
1101 return; |
|
1102 |
|
1103 // Disable all UI form elements that TinyMCE created |
|
1104 for (i=0; i<form_obj.elements.length; i++) { |
|
1105 elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id; |
|
1106 |
|
1107 if (elementId.indexOf('mce_editor_') == 0) |
|
1108 form_obj.elements[i].disabled = true; |
|
1109 } |
|
1110 }, |
|
1111 |
|
1112 handleEvent : function(e) { |
|
1113 var inst = tinyMCE.selectedInstance; |
|
1114 |
|
1115 // Remove odd, error |
|
1116 if (typeof(tinyMCE) == "undefined") |
|
1117 return true; |
|
1118 |
|
1119 //tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : "")); |
|
1120 |
|
1121 if (tinyMCE.executeCallback(tinyMCE.selectedInstance, 'handle_event_callback', 'handleEvent', e)) |
|
1122 return false; |
|
1123 |
|
1124 switch (e.type) { |
|
1125 case "beforedeactivate": // Was added due to bug #1439953 |
|
1126 case "blur": |
|
1127 if (tinyMCE.selectedInstance) |
|
1128 tinyMCE.selectedInstance.execCommand('mceEndTyping'); |
|
1129 |
|
1130 tinyMCE.hideMenus(); |
|
1131 |
|
1132 return; |
|
1133 |
|
1134 // Workaround for drag drop/copy paste base href bug |
|
1135 case "drop": |
|
1136 case "beforepaste": |
|
1137 if (tinyMCE.selectedInstance) |
|
1138 tinyMCE.selectedInstance.setBaseHREF(null); |
|
1139 |
|
1140 // Fixes odd MSIE bug where drag/droping elements in a iframe with height 100% breaks |
|
1141 // This logic forces the width/height to be in pixels while the user is drag/dropping |
|
1142 if (tinyMCE.isRealIE) { |
|
1143 var ife = tinyMCE.selectedInstance.iframeElement; |
|
1144 |
|
1145 /*if (ife.style.width.indexOf('%') != -1) { |
|
1146 ife._oldWidth = ife.width.height; |
|
1147 ife.style.width = ife.clientWidth; |
|
1148 }*/ |
|
1149 |
|
1150 if (ife.style.height.indexOf('%') != -1) { |
|
1151 ife._oldHeight = ife.style.height; |
|
1152 ife.style.height = ife.clientHeight; |
|
1153 } |
|
1154 } |
|
1155 |
|
1156 window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings['base_href']);tinyMCE._resetIframeHeight();", 1); |
|
1157 return; |
|
1158 |
|
1159 case "submit": |
|
1160 tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target); |
|
1161 tinyMCE.triggerSave(); |
|
1162 tinyMCE.isNotDirty = true; |
|
1163 return; |
|
1164 |
|
1165 case "reset": |
|
1166 var formObj = tinyMCE.isIE ? window.event.srcElement : e.target; |
|
1167 |
|
1168 for (var i=0; i<document.forms.length; i++) { |
|
1169 if (document.forms[i] == formObj) |
|
1170 window.setTimeout('tinyMCE.resetForm(' + i + ');', 10); |
|
1171 } |
|
1172 |
|
1173 return; |
|
1174 |
|
1175 case "keypress": |
|
1176 if (inst && inst.handleShortcut(e)) |
|
1177 return false; |
|
1178 |
|
1179 if (e.target.editorId) { |
|
1180 tinyMCE.instances[e.target.editorId].select(); |
|
1181 } else { |
|
1182 if (e.target.ownerDocument.editorId) |
|
1183 tinyMCE.instances[e.target.ownerDocument.editorId].select(); |
|
1184 } |
|
1185 |
|
1186 if (tinyMCE.selectedInstance) |
|
1187 tinyMCE.selectedInstance.switchSettings(); |
|
1188 |
|
1189 // Insert P element |
|
1190 if ((tinyMCE.isGecko || tinyMCE.isOpera || tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) { |
|
1191 // Insert P element instead of BR |
|
1192 if (TinyMCE_ForceParagraphs._insertPara(tinyMCE.selectedInstance, e)) { |
|
1193 // Cancel event |
|
1194 tinyMCE.execCommand("mceAddUndoLevel"); |
|
1195 return tinyMCE.cancelEvent(e); |
|
1196 } |
|
1197 } |
|
1198 |
|
1199 // Handle backspace |
|
1200 if ((tinyMCE.isGecko && !tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { |
|
1201 // Insert P element instead of BR |
|
1202 if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { |
|
1203 // Cancel event |
|
1204 tinyMCE.execCommand("mceAddUndoLevel"); |
|
1205 return tinyMCE.cancelEvent(e); |
|
1206 } |
|
1207 } |
|
1208 |
|
1209 // Return key pressed |
|
1210 if (tinyMCE.isIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) { |
|
1211 if (e.target.editorId) |
|
1212 tinyMCE.instances[e.target.editorId].select(); |
|
1213 |
|
1214 if (tinyMCE.selectedInstance) { |
|
1215 var sel = tinyMCE.selectedInstance.getDoc().selection; |
|
1216 var rng = sel.createRange(); |
|
1217 |
|
1218 if (tinyMCE.getParentElement(rng.parentElement(), "li") != null) |
|
1219 return false; |
|
1220 |
|
1221 // Cancel event |
|
1222 e.returnValue = false; |
|
1223 e.cancelBubble = true; |
|
1224 |
|
1225 // Insert BR element |
|
1226 rng.pasteHTML("<br />"); |
|
1227 rng.collapse(false); |
|
1228 rng.select(); |
|
1229 |
|
1230 tinyMCE.execCommand("mceAddUndoLevel"); |
|
1231 tinyMCE.triggerNodeChange(false); |
|
1232 return false; |
|
1233 } |
|
1234 } |
|
1235 |
|
1236 // Backspace or delete |
|
1237 if (e.keyCode == 8 || e.keyCode == 46) { |
|
1238 tinyMCE.selectedElement = e.target; |
|
1239 tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a"); |
|
1240 tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img"); |
|
1241 tinyMCE.triggerNodeChange(false); |
|
1242 } |
|
1243 |
|
1244 return false; |
|
1245 break; |
|
1246 |
|
1247 case "keyup": |
|
1248 case "keydown": |
|
1249 tinyMCE.hideMenus(); |
|
1250 tinyMCE.hasMouseMoved = false; |
|
1251 |
|
1252 if (inst && inst.handleShortcut(e)) |
|
1253 return false; |
|
1254 |
|
1255 if (e.target.editorId) |
|
1256 tinyMCE.instances[e.target.editorId].select(); |
|
1257 |
|
1258 if (tinyMCE.selectedInstance) |
|
1259 tinyMCE.selectedInstance.switchSettings(); |
|
1260 |
|
1261 var inst = tinyMCE.selectedInstance; |
|
1262 |
|
1263 // Handle backspace |
|
1264 if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { |
|
1265 // Insert P element instead of BR |
|
1266 if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { |
|
1267 // Cancel event |
|
1268 tinyMCE.execCommand("mceAddUndoLevel"); |
|
1269 e.preventDefault(); |
|
1270 return false; |
|
1271 } |
|
1272 } |
|
1273 |
|
1274 tinyMCE.selectedElement = null; |
|
1275 tinyMCE.selectedNode = null; |
|
1276 var elm = tinyMCE.selectedInstance.getFocusElement(); |
|
1277 tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a"); |
|
1278 tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img"); |
|
1279 tinyMCE.selectedElement = elm; |
|
1280 |
|
1281 // Update visualaids on tabs |
|
1282 if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9) |
|
1283 tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance); |
|
1284 |
|
1285 // Fix empty elements on return/enter, check where enter occured |
|
1286 if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13) |
|
1287 tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement(); |
|
1288 |
|
1289 // Fix empty elements on return/enter |
|
1290 if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) { |
|
1291 var elm = tinyMCE.enterKeyElement; |
|
1292 if (elm) { |
|
1293 var re = new RegExp('^HR|IMG|BR$','g'); // Skip these |
|
1294 var dre = new RegExp('^H[1-6]$','g'); // Add double on these |
|
1295 |
|
1296 if (!elm.hasChildNodes() && !re.test(elm.nodeName)) { |
|
1297 if (dre.test(elm.nodeName)) |
|
1298 elm.innerHTML = " "; |
|
1299 else |
|
1300 elm.innerHTML = " "; |
|
1301 } |
|
1302 } |
|
1303 } |
|
1304 |
|
1305 // Check if it's a position key |
|
1306 var keys = tinyMCE.posKeyCodes; |
|
1307 var posKey = false; |
|
1308 for (var i=0; i<keys.length; i++) { |
|
1309 if (keys[i] == e.keyCode) { |
|
1310 posKey = true; |
|
1311 break; |
|
1312 } |
|
1313 } |
|
1314 |
|
1315 // MSIE custom key handling |
|
1316 if (tinyMCE.isIE && tinyMCE.settings['custom_undo_redo']) { |
|
1317 var keys = new Array(8,46); // Backspace,Delete |
|
1318 |
|
1319 for (var i=0; i<keys.length; i++) { |
|
1320 if (keys[i] == e.keyCode) { |
|
1321 if (e.type == "keyup") |
|
1322 tinyMCE.triggerNodeChange(false); |
|
1323 } |
|
1324 } |
|
1325 } |
|
1326 |
|
1327 // If Ctrl key |
|
1328 if (e.keyCode == 17) |
|
1329 return true; |
|
1330 |
|
1331 // Handle Undo/Redo when typing content |
|
1332 |
|
1333 if (tinyMCE.isGecko) { |
|
1334 // Start typing (not a position key or ctrl key, but ctrl+x and ctrl+p is ok) |
|
1335 if (!posKey && e.type == "keyup" && !e.ctrlKey || (e.ctrlKey && (e.keyCode == 86 || e.keyCode == 88))) |
|
1336 tinyMCE.execCommand("mceStartTyping"); |
|
1337 } else { |
|
1338 // IE seems to be working better with this setting |
|
1339 if (!posKey && e.type == "keyup") |
|
1340 tinyMCE.execCommand("mceStartTyping"); |
|
1341 } |
|
1342 |
|
1343 // Store undo bookmark |
|
1344 if (e.type == "keydown" && (posKey || e.ctrlKey) && inst) |
|
1345 inst.undoBookmark = inst.selection.getBookmark(); |
|
1346 |
|
1347 // End typing (position key) or some Ctrl event |
|
1348 if (e.type == "keyup" && (posKey || e.ctrlKey)) |
|
1349 tinyMCE.execCommand("mceEndTyping"); |
|
1350 |
|
1351 if (posKey && e.type == "keyup") |
|
1352 tinyMCE.triggerNodeChange(false); |
|
1353 |
|
1354 if (tinyMCE.isIE && e.ctrlKey) |
|
1355 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); |
|
1356 break; |
|
1357 |
|
1358 case "mousedown": |
|
1359 case "mouseup": |
|
1360 case "click": |
|
1361 case "dblclick": |
|
1362 case "focus": |
|
1363 tinyMCE.hideMenus(); |
|
1364 |
|
1365 if (tinyMCE.selectedInstance) { |
|
1366 tinyMCE.selectedInstance.switchSettings(); |
|
1367 tinyMCE.selectedInstance.isFocused = true; |
|
1368 } |
|
1369 |
|
1370 // Check instance event trigged on |
|
1371 var targetBody = tinyMCE.getParentElement(e.target, "html"); |
|
1372 for (var instanceName in tinyMCE.instances) { |
|
1373 if (!tinyMCE.isInstance(tinyMCE.instances[instanceName])) |
|
1374 continue; |
|
1375 |
|
1376 var inst = tinyMCE.instances[instanceName]; |
|
1377 |
|
1378 // Reset design mode if lost (on everything just in case) |
|
1379 inst.autoResetDesignMode(); |
|
1380 |
|
1381 // Use HTML element since users might click outside of body element |
|
1382 if (inst.getBody().parentNode == targetBody) { |
|
1383 inst.select(); |
|
1384 tinyMCE.selectedElement = e.target; |
|
1385 tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a"); |
|
1386 tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img"); |
|
1387 break; |
|
1388 } |
|
1389 } |
|
1390 |
|
1391 // Add first bookmark location |
|
1392 if (!tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark && (e.type == "mouseup" || e.type == "dblclick")) |
|
1393 tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark = tinyMCE.selectedInstance.selection.getBookmark(); |
|
1394 |
|
1395 // Reset selected node |
|
1396 if (e.type != "focus") |
|
1397 tinyMCE.selectedNode = null; |
|
1398 |
|
1399 tinyMCE.triggerNodeChange(false); |
|
1400 tinyMCE.execCommand("mceEndTyping"); |
|
1401 |
|
1402 if (e.type == "mouseup") |
|
1403 tinyMCE.execCommand("mceAddUndoLevel"); |
|
1404 |
|
1405 // Just in case |
|
1406 if (!tinyMCE.selectedInstance && e.target.editorId) |
|
1407 tinyMCE.instances[e.target.editorId].select(); |
|
1408 |
|
1409 return false; |
|
1410 break; |
|
1411 } |
|
1412 }, |
|
1413 |
|
1414 getButtonHTML : function(id, lang, img, cmd, ui, val) { |
|
1415 var h = '', m, x, io = ''; |
|
1416 |
|
1417 cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; |
|
1418 |
|
1419 if (typeof(ui) != "undefined" && ui != null) |
|
1420 cmd += ',' + ui; |
|
1421 |
|
1422 if (typeof(val) != "undefined" && val != null) |
|
1423 cmd += ",'" + val + "'"; |
|
1424 |
|
1425 cmd += ');'; |
|
1426 |
|
1427 // Patch for IE7 bug with hover out not restoring correctly |
|
1428 if (tinyMCE.isRealIE) |
|
1429 io = 'onmouseover="tinyMCE.lastHover = this;"'; |
|
1430 |
|
1431 // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled |
|
1432 if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = this.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { |
|
1433 // Tiled button |
|
1434 x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); |
|
1435 h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceTiledButton mceButtonNormal" target="_self">'; |
|
1436 h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" title="{$' + lang + '}" />'; |
|
1437 h += '</a>'; |
|
1438 } else { |
|
1439 // Normal button |
|
1440 h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceButtonNormal" target="_self">'; |
|
1441 h += '<img src="' + img + '" title="{$' + lang + '}" />'; |
|
1442 h += '</a>'; |
|
1443 } |
|
1444 |
|
1445 return h; |
|
1446 }, |
|
1447 |
|
1448 getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) { |
|
1449 var h = '', m, x; |
|
1450 |
|
1451 mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');'; |
|
1452 cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; |
|
1453 |
|
1454 if (typeof(ui) != "undefined" && ui != null) |
|
1455 cmd += ',' + ui; |
|
1456 |
|
1457 if (typeof(val) != "undefined" && val != null) |
|
1458 cmd += ",'" + val + "'"; |
|
1459 |
|
1460 cmd += ');'; |
|
1461 |
|
1462 // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled |
|
1463 if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { |
|
1464 x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); |
|
1465 |
|
1466 if (tinyMCE.isRealIE) |
|
1467 h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">'; |
|
1468 else |
|
1469 h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton">'; |
|
1470 |
|
1471 h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceTiledButton mceMenuButtonNormal" target="_self">'; |
|
1472 h += '<img src="{$themeurl}/images/spacer.gif" style="width: 20px; height: 20px; background-position: ' + x + 'px 0" title="{$' + lang + '}" /></a>'; |
|
1473 h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />'; |
|
1474 h += '</a></span>'; |
|
1475 } else { |
|
1476 if (tinyMCE.isRealIE) |
|
1477 h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">'; |
|
1478 else |
|
1479 h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton">'; |
|
1480 |
|
1481 h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">'; |
|
1482 h += '<img src="' + img + '" title="{$' + lang + '}" /></a>'; |
|
1483 h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />'; |
|
1484 h += '</a></span>'; |
|
1485 } |
|
1486 |
|
1487 return h; |
|
1488 }, |
|
1489 |
|
1490 _menuButtonEvent : function(e, o) { |
|
1491 if (o.className == 'mceMenuButtonFocus') |
|
1492 return; |
|
1493 |
|
1494 if (e == 'over') |
|
1495 o.className = o.className + ' mceMenuHover'; |
|
1496 else |
|
1497 o.className = o.className.replace(/\s.*$/, ''); |
|
1498 }, |
|
1499 |
|
1500 addButtonMap : function(m) { |
|
1501 var i, a = m.replace(/\s+/, '').split(','); |
|
1502 |
|
1503 for (i=0; i<a.length; i++) |
|
1504 this.buttonMap[a[i]] = i; |
|
1505 }, |
|
1506 |
|
1507 submitPatch : function() { |
|
1508 tinyMCE.removeTinyMCEFormElements(this); |
|
1509 tinyMCE.triggerSave(); |
|
1510 tinyMCE.isNotDirty = true; |
|
1511 this.mceOldSubmit(); |
|
1512 }, |
|
1513 |
|
1514 onLoad : function() { |
|
1515 var r; |
|
1516 |
|
1517 // Wait for everything to be loaded first |
|
1518 if (tinyMCE.settings.strict_loading_mode && this.loadingIndex != -1) { |
|
1519 window.setTimeout('tinyMCE.onLoad();', 1); |
|
1520 return; |
|
1521 } |
|
1522 |
|
1523 if (tinyMCE.isRealIE && window.event.type == "readystatechange" && document.readyState != "complete") |
|
1524 return true; |
|
1525 |
|
1526 if (tinyMCE.isLoaded) |
|
1527 return true; |
|
1528 |
|
1529 tinyMCE.isLoaded = true; |
|
1530 |
|
1531 // IE produces JS error if TinyMCE is placed in a frame |
|
1532 // It seems to have something to do with the selection not beeing |
|
1533 // correctly initialized in IE so this hack solves the problem |
|
1534 if (tinyMCE.isRealIE && document.body) { |
|
1535 r = document.body.createTextRange(); |
|
1536 r.collapse(true); |
|
1537 r.select(); |
|
1538 } |
|
1539 |
|
1540 tinyMCE.dispatchCallback(null, 'onpageload', 'onPageLoad'); |
|
1541 |
|
1542 for (var c=0; c<tinyMCE.configs.length; c++) { |
|
1543 tinyMCE.settings = tinyMCE.configs[c]; |
|
1544 |
|
1545 var selector = tinyMCE.getParam("editor_selector"); |
|
1546 var deselector = tinyMCE.getParam("editor_deselector"); |
|
1547 var elementRefAr = new Array(); |
|
1548 |
|
1549 // Add submit triggers |
|
1550 if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) { |
|
1551 for (var i=0; i<document.forms.length; i++) { |
|
1552 var form = document.forms[i]; |
|
1553 |
|
1554 tinyMCE.addEvent(form, "submit", TinyMCE_Engine.prototype.handleEvent); |
|
1555 tinyMCE.addEvent(form, "reset", TinyMCE_Engine.prototype.handleEvent); |
|
1556 tinyMCE.submitTriggers = true; // Do it only once |
|
1557 |
|
1558 // Patch the form.submit function |
|
1559 if (tinyMCE.settings['submit_patch']) { |
|
1560 try { |
|
1561 form.mceOldSubmit = form.submit; |
|
1562 form.submit = TinyMCE_Engine.prototype.submitPatch; |
|
1563 } catch (e) { |
|
1564 // Do nothing |
|
1565 } |
|
1566 } |
|
1567 } |
|
1568 } |
|
1569 |
|
1570 // Add editor instances based on mode |
|
1571 var mode = tinyMCE.settings['mode']; |
|
1572 switch (mode) { |
|
1573 case "exact": |
|
1574 var elements = tinyMCE.getParam('elements', '', true, ','); |
|
1575 |
|
1576 for (var i=0; i<elements.length; i++) { |
|
1577 var element = tinyMCE._getElementById(elements[i]); |
|
1578 var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : ""; |
|
1579 |
|
1580 if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(element, "class"))) |
|
1581 continue; |
|
1582 |
|
1583 if (trigger == "false") |
|
1584 continue; |
|
1585 |
|
1586 if ((tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) && element) { |
|
1587 elementRefAr[elementRefAr.length] = element; |
|
1588 continue; |
|
1589 } |
|
1590 |
|
1591 if (element) |
|
1592 tinyMCE.addMCEControl(element, elements[i]); |
|
1593 else if (tinyMCE.settings['debug']) |
|
1594 alert("Error: Could not find element by id or name: " + elements[i]); |
|
1595 } |
|
1596 break; |
|
1597 |
|
1598 case "specific_textareas": |
|
1599 case "textareas": |
|
1600 var nodeList = document.getElementsByTagName("textarea"); |
|
1601 |
|
1602 for (var i=0; i<nodeList.length; i++) { |
|
1603 var elm = nodeList.item(i); |
|
1604 var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']); |
|
1605 |
|
1606 if (selector != '' && !new RegExp('\\b' + selector + '\\b').test(tinyMCE.getAttrib(elm, "class"))) |
|
1607 continue; |
|
1608 |
|
1609 if (selector != '') |
|
1610 trigger = selector != "" ? "true" : ""; |
|
1611 |
|
1612 if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(elm, "class"))) |
|
1613 continue; |
|
1614 |
|
1615 if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false")) |
|
1616 elementRefAr[elementRefAr.length] = elm; |
|
1617 } |
|
1618 break; |
|
1619 } |
|
1620 |
|
1621 for (var i=0; i<elementRefAr.length; i++) { |
|
1622 var element = elementRefAr[i]; |
|
1623 var elementId = element.name ? element.name : element.id; |
|
1624 |
|
1625 if (tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) { |
|
1626 // Focus breaks in Mozilla |
|
1627 if (tinyMCE.isGecko) { |
|
1628 var settings = tinyMCE.settings; |
|
1629 |
|
1630 tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);}); |
|
1631 |
|
1632 if (element.nodeName != "TEXTAREA" && element.nodeName != "INPUT") |
|
1633 tinyMCE.addEvent(element, "click", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);}); |
|
1634 // tinyMCE.addEvent(element, "mouseover", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);}); |
|
1635 } else { |
|
1636 var settings = tinyMCE.settings; |
|
1637 |
|
1638 tinyMCE.addEvent(element, "focus", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); }); |
|
1639 tinyMCE.addEvent(element, "click", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); }); |
|
1640 // tinyMCE.addEvent(element, "mouseenter", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); }); |
|
1641 } |
|
1642 } else |
|
1643 tinyMCE.addMCEControl(element, elementId); |
|
1644 } |
|
1645 |
|
1646 // Handle auto focus |
|
1647 if (tinyMCE.settings['auto_focus']) { |
|
1648 window.setTimeout(function () { |
|
1649 var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']); |
|
1650 inst.selection.selectNode(inst.getBody(), true, true); |
|
1651 inst.contentWindow.focus(); |
|
1652 }, 100); |
|
1653 } |
|
1654 |
|
1655 tinyMCE.dispatchCallback(null, 'oninit', 'onInit'); |
|
1656 } |
|
1657 }, |
|
1658 |
|
1659 isInstance : function(o) { |
|
1660 return o != null && typeof(o) == "object" && o.isTinyMCE_Control; |
|
1661 }, |
|
1662 |
|
1663 getParam : function(name, default_value, strip_whitespace, split_chr) { |
|
1664 var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name]; |
|
1665 |
|
1666 // Fix bool values |
|
1667 if (value == "true" || value == "false") |
|
1668 return (value == "true"); |
|
1669 |
|
1670 if (strip_whitespace) |
|
1671 value = tinyMCE.regexpReplace(value, "[ \t\r\n]", "") + ''; |
|
1672 |
|
1673 if (typeof(split_chr) != "undefined" && split_chr != null) { |
|
1674 value = value.split(split_chr); |
|
1675 var outArray = new Array(); |
|
1676 |
|
1677 for (var i=0; i<value.length; i++) { |
|
1678 if (value[i] && value[i] != "") |
|
1679 outArray[outArray.length] = value[i]; |
|
1680 } |
|
1681 |
|
1682 value = outArray; |
|
1683 } |
|
1684 |
|
1685 return value; |
|
1686 }, |
|
1687 |
|
1688 getLang : function(name, default_value, parse_entities, va) { |
|
1689 var v = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name], n; |
|
1690 |
|
1691 if (parse_entities) |
|
1692 v = tinyMCE.entityDecode(v); |
|
1693 |
|
1694 if (va) { |
|
1695 for (n in va) |
|
1696 v = this.replaceVar(v, n, va[n]); |
|
1697 } |
|
1698 |
|
1699 return v; |
|
1700 }, |
|
1701 |
|
1702 entityDecode : function(s) { |
|
1703 var e = document.createElement("div"); |
|
1704 |
|
1705 e.innerHTML = s; |
|
1706 |
|
1707 return e.firstChild.nodeValue; |
|
1708 }, |
|
1709 |
|
1710 addToLang : function(prefix, ar) { |
|
1711 for (var key in ar) { |
|
1712 if (typeof(ar[key]) == 'function') |
|
1713 continue; |
|
1714 |
|
1715 tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key]; |
|
1716 } |
|
1717 |
|
1718 this.loadNextScript(); |
|
1719 |
|
1720 // for (var key in ar) |
|
1721 // tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|"; |
|
1722 }, |
|
1723 |
|
1724 triggerNodeChange : function(focus, setup_content) { |
|
1725 var elm, inst, editorId, undoIndex = -1, undoLevels = -1, doc, anySelection = false, st; |
|
1726 |
|
1727 if (tinyMCE.selectedInstance) { |
|
1728 inst = tinyMCE.selectedInstance; |
|
1729 elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement(); |
|
1730 |
|
1731 /* if (elm == inst.lastTriggerEl) |
|
1732 return; |
|
1733 |
|
1734 inst.lastTriggerEl = elm;*/ |
|
1735 |
|
1736 editorId = inst.editorId; |
|
1737 st = inst.selection.getSelectedText(); |
|
1738 |
|
1739 if (tinyMCE.settings.auto_resize) |
|
1740 inst.resizeToContent(); |
|
1741 |
|
1742 if (setup_content && tinyMCE.isGecko && inst.isHidden()) |
|
1743 elm = inst.getBody(); |
|
1744 |
|
1745 inst.switchSettings(); |
|
1746 |
|
1747 if (tinyMCE.selectedElement) |
|
1748 anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0); |
|
1749 |
|
1750 if (tinyMCE.settings['custom_undo_redo']) { |
|
1751 undoIndex = inst.undoRedo.undoIndex; |
|
1752 undoLevels = inst.undoRedo.undoLevels.length; |
|
1753 } |
|
1754 |
|
1755 tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content); |
|
1756 } |
|
1757 |
|
1758 if (this.selectedInstance && (typeof(focus) == "undefined" || focus)) |
|
1759 this.selectedInstance.contentWindow.focus(); |
|
1760 }, |
|
1761 |
|
1762 _customCleanup : function(inst, type, content) { |
|
1763 var pl, po, i; |
|
1764 |
|
1765 // Call custom cleanup |
|
1766 var customCleanup = tinyMCE.settings['cleanup_callback']; |
|
1767 if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined") |
|
1768 content = eval(customCleanup + "(type, content, inst);"); |
|
1769 |
|
1770 // Trigger theme cleanup |
|
1771 po = tinyMCE.themes[tinyMCE.settings['theme']]; |
|
1772 if (po && po.cleanup) |
|
1773 content = po.cleanup(type, content, inst); |
|
1774 |
|
1775 // Trigger plugin cleanups |
|
1776 pl = inst.plugins; |
|
1777 for (i=0; i<pl.length; i++) { |
|
1778 po = tinyMCE.plugins[pl[i]]; |
|
1779 |
|
1780 if (po && po.cleanup) |
|
1781 content = po.cleanup(type, content, inst); |
|
1782 } |
|
1783 |
|
1784 return content; |
|
1785 }, |
|
1786 |
|
1787 setContent : function(h) { |
|
1788 if (tinyMCE.selectedInstance) { |
|
1789 tinyMCE.selectedInstance.execCommand('mceSetContent', false, h); |
|
1790 tinyMCE.selectedInstance.repaint(); |
|
1791 } |
|
1792 }, |
|
1793 |
|
1794 importThemeLanguagePack : function(name) { |
|
1795 if (typeof(name) == "undefined") |
|
1796 name = tinyMCE.settings['theme']; |
|
1797 |
|
1798 tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js'); |
|
1799 }, |
|
1800 |
|
1801 importPluginLanguagePack : function(name) { |
|
1802 var b = tinyMCE.baseURL + '/plugins/' + name; |
|
1803 |
|
1804 if (this.plugins[name]) |
|
1805 b = this.plugins[name].baseURL; |
|
1806 |
|
1807 tinyMCE.loadScript(b + '/langs/' + tinyMCE.settings['language'] + '.js'); |
|
1808 }, |
|
1809 |
|
1810 applyTemplate : function(h, as) { |
|
1811 return h.replace(new RegExp('\\{\\$([a-z0-9_]+)\\}', 'gi'), function(m, s) { |
|
1812 if (s.indexOf('lang_') == 0 && tinyMCELang[s]) |
|
1813 return tinyMCELang[s]; |
|
1814 |
|
1815 if (as && as[s]) |
|
1816 return as[s]; |
|
1817 |
|
1818 if (tinyMCE.settings[s]) |
|
1819 return tinyMCE.settings[s]; |
|
1820 |
|
1821 if (m == 'themeurl') |
|
1822 return tinyMCE.themeURL; |
|
1823 |
|
1824 return m; |
|
1825 }); |
|
1826 }, |
|
1827 |
|
1828 replaceVar : function(h, r, v) { |
|
1829 return h.replace(new RegExp('{\\\$' + r + '}', 'g'), v); |
|
1830 }, |
|
1831 |
|
1832 openWindow : function(template, args) { |
|
1833 var html, width, height, x, y, resizable, scrollbars, url; |
|
1834 |
|
1835 args = !args ? {} : args; |
|
1836 |
|
1837 args['mce_template_file'] = template['file']; |
|
1838 args['mce_width'] = template['width']; |
|
1839 args['mce_height'] = template['height']; |
|
1840 tinyMCE.windowArgs = args; |
|
1841 |
|
1842 html = template['html']; |
|
1843 if (!(width = parseInt(template['width']))) |
|
1844 width = 320; |
|
1845 |
|
1846 if (!(height = parseInt(template['height']))) |
|
1847 height = 200; |
|
1848 |
|
1849 // Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!! |
|
1850 if (tinyMCE.isIE) |
|
1851 height += 40; |
|
1852 else |
|
1853 height += 20; |
|
1854 |
|
1855 x = parseInt(screen.width / 2.0) - (width / 2.0); |
|
1856 y = parseInt(screen.height / 2.0) - (height / 2.0); |
|
1857 |
|
1858 resizable = (args && args['resizable']) ? args['resizable'] : "no"; |
|
1859 scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no"; |
|
1860 |
|
1861 if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1) |
|
1862 url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file']; |
|
1863 else |
|
1864 url = template['file']; |
|
1865 |
|
1866 // Replace all args as variables in URL |
|
1867 for (var name in args) { |
|
1868 if (typeof(args[name]) == 'function') |
|
1869 continue; |
|
1870 |
|
1871 url = tinyMCE.replaceVar(url, name, escape(args[name])); |
|
1872 } |
|
1873 |
|
1874 if (html) { |
|
1875 html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']); |
|
1876 html = tinyMCE.applyTemplate(html, args); |
|
1877 |
|
1878 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); |
|
1879 if (win == null) { |
|
1880 alert(tinyMCELang['lang_popup_blocked']); |
|
1881 return; |
|
1882 } |
|
1883 |
|
1884 //alert('docwrite 2'); |
|
1885 win.document.write(html); |
|
1886 win.document.close(); |
|
1887 win.resizeTo(width, height); |
|
1888 win.focus(); |
|
1889 } else { |
|
1890 if ((tinyMCE.isRealIE) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") { |
|
1891 height += 10; |
|
1892 |
|
1893 var features = "resizable:" + resizable |
|
1894 + ";scroll:" |
|
1895 + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:" |
|
1896 + width + "px;dialogHeight:" + height + "px;"; |
|
1897 |
|
1898 window.showModalDialog(url, window, features); |
|
1899 } else { |
|
1900 var modal = (resizable == "yes") ? "no" : "yes"; |
|
1901 |
|
1902 if (tinyMCE.isGecko && tinyMCE.isMac) |
|
1903 modal = "no"; |
|
1904 |
|
1905 if (template['close_previous'] != "no") |
|
1906 try {tinyMCE.lastWindow.close();} catch (ex) {} |
|
1907 |
|
1908 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); |
|
1909 if (win == null) { |
|
1910 alert(tinyMCELang['lang_popup_blocked']); |
|
1911 return; |
|
1912 } |
|
1913 |
|
1914 if (template['close_previous'] != "no") |
|
1915 tinyMCE.lastWindow = win; |
|
1916 |
|
1917 eval('try { win.resizeTo(width, height); } catch(e) { }'); |
|
1918 |
|
1919 // Make it bigger if statusbar is forced |
|
1920 if (tinyMCE.isGecko) { |
|
1921 if (win.document.defaultView.statusbar.visible) |
|
1922 win.resizeBy(0, tinyMCE.isMac ? 10 : 24); |
|
1923 } |
|
1924 |
|
1925 win.focus(); |
|
1926 } |
|
1927 } |
|
1928 }, |
|
1929 |
|
1930 closeWindow : function(win) { |
|
1931 win.close(); |
|
1932 }, |
|
1933 |
|
1934 getVisualAidClass : function(class_name, state) { |
|
1935 var aidClass = tinyMCE.settings['visual_table_class']; |
|
1936 |
|
1937 if (typeof(state) == "undefined") |
|
1938 state = tinyMCE.settings['visual']; |
|
1939 |
|
1940 // Split |
|
1941 var classNames = new Array(); |
|
1942 var ar = class_name.split(' '); |
|
1943 for (var i=0; i<ar.length; i++) { |
|
1944 if (ar[i] == aidClass) |
|
1945 ar[i] = ""; |
|
1946 |
|
1947 if (ar[i] != "") |
|
1948 classNames[classNames.length] = ar[i]; |
|
1949 } |
|
1950 |
|
1951 if (state) |
|
1952 classNames[classNames.length] = aidClass; |
|
1953 |
|
1954 // Glue |
|
1955 var className = ""; |
|
1956 for (var i=0; i<classNames.length; i++) { |
|
1957 if (i > 0) |
|
1958 className += " "; |
|
1959 |
|
1960 className += classNames[i]; |
|
1961 } |
|
1962 |
|
1963 return className; |
|
1964 }, |
|
1965 |
|
1966 handleVisualAid : function(el, deep, state, inst, skip_dispatch) { |
|
1967 if (!el) |
|
1968 return; |
|
1969 |
|
1970 if (!skip_dispatch) |
|
1971 tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst); |
|
1972 |
|
1973 var tableElement = null; |
|
1974 |
|
1975 switch (el.nodeName) { |
|
1976 case "TABLE": |
|
1977 var oldW = el.style.width; |
|
1978 var oldH = el.style.height; |
|
1979 var bo = tinyMCE.getAttrib(el, "border"); |
|
1980 |
|
1981 bo = bo == "" || bo == "0" ? true : false; |
|
1982 |
|
1983 tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo)); |
|
1984 |
|
1985 el.style.width = oldW; |
|
1986 el.style.height = oldH; |
|
1987 |
|
1988 for (var y=0; y<el.rows.length; y++) { |
|
1989 for (var x=0; x<el.rows[y].cells.length; x++) { |
|
1990 var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo); |
|
1991 tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn); |
|
1992 } |
|
1993 } |
|
1994 |
|
1995 break; |
|
1996 |
|
1997 case "A": |
|
1998 var anchorName = tinyMCE.getAttrib(el, "name"); |
|
1999 |
|
2000 if (anchorName != '' && state) { |
|
2001 el.title = anchorName; |
|
2002 tinyMCE.addCSSClass(el, 'mceItemAnchor'); |
|
2003 } else if (anchorName != '' && !state) |
|
2004 el.className = ''; |
|
2005 |
|
2006 break; |
|
2007 } |
|
2008 |
|
2009 if (deep && el.hasChildNodes()) { |
|
2010 for (var i=0; i<el.childNodes.length; i++) |
|
2011 tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst, true); |
|
2012 } |
|
2013 }, |
|
2014 |
|
2015 /* |
|
2016 applyClassesToFonts : function(doc, size) { |
|
2017 var f = doc.getElementsByTagName("font"); |
|
2018 for (var i=0; i<f.length; i++) { |
|
2019 var s = tinyMCE.getAttrib(f[i], "size"); |
|
2020 |
|
2021 if (s != "") |
|
2022 tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s); |
|
2023 } |
|
2024 |
|
2025 if (typeof(size) != "undefined") { |
|
2026 var css = ""; |
|
2027 |
|
2028 for (var x=0; x<doc.styleSheets.length; x++) { |
|
2029 for (var i=0; i<doc.styleSheets[x].rules.length; i++) { |
|
2030 if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) { |
|
2031 css = doc.styleSheets[x].rules[i].style.cssText; |
|
2032 break; |
|
2033 } |
|
2034 } |
|
2035 |
|
2036 if (css != "") |
|
2037 break; |
|
2038 } |
|
2039 |
|
2040 if (doc.styleSheets[0].rules[0].selectorText == "FONT") |
|
2041 doc.styleSheets[0].removeRule(0); |
|
2042 |
|
2043 doc.styleSheets[0].addRule("FONT", css, 0); |
|
2044 } |
|
2045 }, |
|
2046 */ |
|
2047 |
|
2048 fixGeckoBaseHREFBug : function(m, e, h) { |
|
2049 var xsrc, xhref; |
|
2050 |
|
2051 if (tinyMCE.isGecko) { |
|
2052 if (m == 1) { |
|
2053 h = h.replace(/\ssrc=/gi, " mce_tsrc="); |
|
2054 h = h.replace(/\shref=/gi, " mce_thref="); |
|
2055 |
|
2056 return h; |
|
2057 } else { |
|
2058 // Why bother if there is no src or href broken |
|
2059 if (!new RegExp('(src|href)=', 'g').test(h)) |
|
2060 return h; |
|
2061 |
|
2062 // Restore src and href that gets messed up by Gecko |
|
2063 tinyMCE.selectElements(e, 'A,IMG,SELECT,AREA,IFRAME,BASE,INPUT,SCRIPT,EMBED,OBJECT,LINK', function (n) { |
|
2064 xsrc = tinyMCE.getAttrib(n, "mce_tsrc"); |
|
2065 xhref = tinyMCE.getAttrib(n, "mce_thref"); |
|
2066 |
|
2067 if (xsrc != "") { |
|
2068 try { |
|
2069 n.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc); |
|
2070 } catch (e) { |
|
2071 // Ignore, Firefox cast exception if local file wasn't found |
|
2072 } |
|
2073 |
|
2074 n.removeAttribute("mce_tsrc"); |
|
2075 } |
|
2076 |
|
2077 if (xhref != "") { |
|
2078 try { |
|
2079 n.href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref); |
|
2080 } catch (e) { |
|
2081 // Ignore, Firefox cast exception if local file wasn't found |
|
2082 } |
|
2083 |
|
2084 n.removeAttribute("mce_thref"); |
|
2085 } |
|
2086 |
|
2087 return false; |
|
2088 }); |
|
2089 |
|
2090 // Restore text/comment nodes |
|
2091 tinyMCE.selectNodes(e, function(n) { |
|
2092 if (n.nodeType == 3 || n.nodeType == 8) { |
|
2093 n.nodeValue = n.nodeValue.replace(/\smce_tsrc=/gi, " src="); |
|
2094 n.nodeValue = n.nodeValue.replace(/\smce_thref=/gi, " href="); |
|
2095 } |
|
2096 |
|
2097 return false; |
|
2098 }); |
|
2099 } |
|
2100 } |
|
2101 |
|
2102 return h; |
|
2103 }, |
|
2104 |
|
2105 _setHTML : function(doc, html_content) { |
|
2106 // Force closed anchors open |
|
2107 //html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>'); |
|
2108 |
|
2109 html_content = tinyMCE.cleanupHTMLCode(html_content); |
|
2110 |
|
2111 // Try innerHTML if it fails use pasteHTML in MSIE |
|
2112 try { |
|
2113 tinyMCE.setInnerHTML(doc.body, html_content); |
|
2114 } catch (e) { |
|
2115 if (this.isMSIE) |
|
2116 doc.body.createTextRange().pasteHTML(html_content); |
|
2117 } |
|
2118 |
|
2119 // Content duplication bug fix |
|
2120 if (tinyMCE.isIE && tinyMCE.settings['fix_content_duplication']) { |
|
2121 // Remove P elements in P elements |
|
2122 var paras = doc.getElementsByTagName("P"); |
|
2123 for (var i=0; i<paras.length; i++) { |
|
2124 var node = paras[i]; |
|
2125 while ((node = node.parentNode) != null) { |
|
2126 if (node.nodeName == "P") |
|
2127 node.outerHTML = node.innerHTML; |
|
2128 } |
|
2129 } |
|
2130 |
|
2131 // Content duplication bug fix (Seems to be word crap) |
|
2132 var html = doc.body.innerHTML; |
|
2133 /* |
|
2134 if (html.indexOf('="mso') != -1) { |
|
2135 for (var i=0; i<doc.body.all.length; i++) { |
|
2136 var el = doc.body.all[i]; |
|
2137 el.removeAttribute("className","",0); |
|
2138 el.removeAttribute("style","",0); |
|
2139 } |
|
2140 |
|
2141 html = doc.body.innerHTML; |
|
2142 html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />"); |
|
2143 html = tinyMCE.regexpReplace(html, "<o:p> <\/o:p>", ""); |
|
2144 html = tinyMCE.regexpReplace(html, "<st1:.*?>", ""); |
|
2145 html = tinyMCE.regexpReplace(html, "<p><\/p>", ""); |
|
2146 html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", ""); |
|
2147 html = tinyMCE.regexpReplace(html, "<p> <\/p>", "<br />"); |
|
2148 html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>"); |
|
2149 html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>"); |
|
2150 }*/ |
|
2151 |
|
2152 // Always set the htmlText output |
|
2153 tinyMCE.setInnerHTML(doc.body, html); |
|
2154 } |
|
2155 |
|
2156 tinyMCE.cleanupAnchors(doc); |
|
2157 |
|
2158 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
2159 tinyMCE.convertSpansToFonts(doc); |
|
2160 }, |
|
2161 |
|
2162 getEditorId : function(form_element) { |
|
2163 var inst = this.getInstanceById(form_element); |
|
2164 if (!inst) |
|
2165 return null; |
|
2166 |
|
2167 return inst.editorId; |
|
2168 }, |
|
2169 |
|
2170 getInstanceById : function(editor_id) { |
|
2171 var inst = this.instances[editor_id]; |
|
2172 if (!inst) { |
|
2173 for (var n in tinyMCE.instances) { |
|
2174 var instance = tinyMCE.instances[n]; |
|
2175 if (!tinyMCE.isInstance(instance)) |
|
2176 continue; |
|
2177 |
|
2178 if (instance.formTargetElementId == editor_id) { |
|
2179 inst = instance; |
|
2180 break; |
|
2181 } |
|
2182 } |
|
2183 } |
|
2184 |
|
2185 return inst; |
|
2186 }, |
|
2187 |
|
2188 queryInstanceCommandValue : function(editor_id, command) { |
|
2189 var inst = tinyMCE.getInstanceById(editor_id); |
|
2190 if (inst) |
|
2191 return inst.queryCommandValue(command); |
|
2192 |
|
2193 return false; |
|
2194 }, |
|
2195 |
|
2196 queryInstanceCommandState : function(editor_id, command) { |
|
2197 var inst = tinyMCE.getInstanceById(editor_id); |
|
2198 if (inst) |
|
2199 return inst.queryCommandState(command); |
|
2200 |
|
2201 return null; |
|
2202 }, |
|
2203 |
|
2204 setWindowArg : function(n, v) { |
|
2205 this.windowArgs[n] = v; |
|
2206 }, |
|
2207 |
|
2208 getWindowArg : function(n, d) { |
|
2209 return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n]; |
|
2210 }, |
|
2211 |
|
2212 getCSSClasses : function(editor_id, doc) { |
|
2213 var inst = tinyMCE.getInstanceById(editor_id); |
|
2214 |
|
2215 // Is cached, use that |
|
2216 if (inst && inst.cssClasses.length > 0) |
|
2217 return inst.cssClasses; |
|
2218 |
|
2219 if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") { |
|
2220 var instance; |
|
2221 |
|
2222 for (var instanceName in tinyMCE.instances) { |
|
2223 instance = tinyMCE.instances[instanceName]; |
|
2224 if (!tinyMCE.isInstance(instance)) |
|
2225 continue; |
|
2226 |
|
2227 break; |
|
2228 } |
|
2229 |
|
2230 doc = instance.getDoc(); |
|
2231 } |
|
2232 |
|
2233 if (typeof(doc) == "undefined") { |
|
2234 var instance = tinyMCE.getInstanceById(editor_id); |
|
2235 doc = instance.getDoc(); |
|
2236 } |
|
2237 |
|
2238 if (doc) { |
|
2239 var styles = doc.styleSheets; |
|
2240 |
|
2241 if (styles && styles.length > 0) { |
|
2242 for (var x=0; x<styles.length; x++) { |
|
2243 var csses = null; |
|
2244 |
|
2245 // Just ignore any errors |
|
2246 eval("try {var csses = tinyMCE.isIE ? doc.styleSheets(" + x + ").rules : styles[" + x + "].cssRules;} catch(e) {}"); |
|
2247 if (!csses) |
|
2248 return new Array(); |
|
2249 |
|
2250 for (var i=0; i<csses.length; i++) { |
|
2251 var selectorText = csses[i].selectorText; |
|
2252 |
|
2253 // Can be multiple rules per selector |
|
2254 if (selectorText) { |
|
2255 var rules = selectorText.split(','); |
|
2256 for (var c=0; c<rules.length; c++) { |
|
2257 var rule = rules[c]; |
|
2258 |
|
2259 // Strip spaces between selectors |
|
2260 while (rule.indexOf(' ') == 0) |
|
2261 rule = rule.substring(1); |
|
2262 |
|
2263 // Invalid rule |
|
2264 if (rule.indexOf(' ') != -1 || rule.indexOf(':') != -1 || rule.indexOf('mceItem') != -1) |
|
2265 continue; |
|
2266 |
|
2267 if (rule.indexOf(tinyMCE.settings['visual_table_class']) != -1 || rule.indexOf('mceEditable') != -1 || rule.indexOf('mceNonEditable') != -1) |
|
2268 continue; |
|
2269 |
|
2270 // Is class rule |
|
2271 if (rule.indexOf('.') != -1) { |
|
2272 var cssClass = rule.substring(rule.indexOf('.') + 1); |
|
2273 var addClass = true; |
|
2274 |
|
2275 for (var p=0; p<inst.cssClasses.length && addClass; p++) { |
|
2276 if (inst.cssClasses[p] == cssClass) |
|
2277 addClass = false; |
|
2278 } |
|
2279 |
|
2280 if (addClass) |
|
2281 inst.cssClasses[inst.cssClasses.length] = cssClass; |
|
2282 } |
|
2283 } |
|
2284 } |
|
2285 } |
|
2286 } |
|
2287 } |
|
2288 } |
|
2289 |
|
2290 return inst.cssClasses; |
|
2291 }, |
|
2292 |
|
2293 regexpReplace : function(in_str, reg_exp, replace_str, opts) { |
|
2294 if (in_str == null) |
|
2295 return in_str; |
|
2296 |
|
2297 if (typeof(opts) == "undefined") |
|
2298 opts = 'g'; |
|
2299 |
|
2300 var re = new RegExp(reg_exp, opts); |
|
2301 return in_str.replace(re, replace_str); |
|
2302 }, |
|
2303 |
|
2304 trim : function(s) { |
|
2305 return s.replace(/^\s*|\s*$/g, ""); |
|
2306 }, |
|
2307 |
|
2308 cleanupEventStr : function(s) { |
|
2309 s = "" + s; |
|
2310 s = s.replace('function anonymous()\n{\n', ''); |
|
2311 s = s.replace('\n}', ''); |
|
2312 s = s.replace(/^return true;/gi, ''); // Remove event blocker |
|
2313 |
|
2314 return s; |
|
2315 }, |
|
2316 |
|
2317 getControlHTML : function(c) { |
|
2318 var i, l, n, o, v, rtl = tinyMCE.getLang('lang_dir') == 'rtl'; |
|
2319 |
|
2320 l = tinyMCE.plugins; |
|
2321 for (n in l) { |
|
2322 o = l[n]; |
|
2323 |
|
2324 if (o.getControlHTML && (v = o.getControlHTML(c)) != '') { |
|
2325 if (rtl) |
|
2326 return '<span dir="rtl">' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '</span>'; |
|
2327 |
|
2328 return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); |
|
2329 } |
|
2330 } |
|
2331 |
|
2332 o = tinyMCE.themes[tinyMCE.settings['theme']]; |
|
2333 if (o.getControlHTML && (v = o.getControlHTML(c)) != '') { |
|
2334 if (rtl) |
|
2335 return '<span dir="rtl">' + v + '</span>'; |
|
2336 |
|
2337 return v; |
|
2338 } |
|
2339 |
|
2340 return ''; |
|
2341 }, |
|
2342 |
|
2343 evalFunc : function(f, idx, a, o) { |
|
2344 o = !o ? window : o; |
|
2345 f = typeof(f) == 'function' ? f : o[f]; |
|
2346 |
|
2347 return f.apply(o, Array.prototype.slice.call(a, idx)); |
|
2348 }, |
|
2349 |
|
2350 dispatchCallback : function(i, p, n) { |
|
2351 return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments); |
|
2352 }, |
|
2353 |
|
2354 executeCallback : function(i, p, n) { |
|
2355 return this.callFunc(i, p, n, 1, this.executeCallback.arguments); |
|
2356 }, |
|
2357 |
|
2358 execCommandCallback : function(i, p, n) { |
|
2359 return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments); |
|
2360 }, |
|
2361 |
|
2362 callFunc : function(ins, p, n, m, a) { |
|
2363 var l, i, on, o, s, v; |
|
2364 |
|
2365 s = m == 2; |
|
2366 |
|
2367 l = tinyMCE.getParam(p, ''); |
|
2368 |
|
2369 if (l != '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0) |
|
2370 return true; |
|
2371 |
|
2372 if (ins != null) { |
|
2373 for (i=0, l = ins.plugins; i<l.length; i++) { |
|
2374 o = tinyMCE.plugins[l[i]]; |
|
2375 |
|
2376 if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) |
|
2377 return true; |
|
2378 } |
|
2379 } |
|
2380 |
|
2381 l = tinyMCE.themes; |
|
2382 for (on in l) { |
|
2383 o = l[on]; |
|
2384 |
|
2385 if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) |
|
2386 return true; |
|
2387 } |
|
2388 |
|
2389 return false; |
|
2390 }, |
|
2391 |
|
2392 xmlEncode : function(s, skip_apos) { |
|
2393 return s ? ('' + s).replace(!skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe, function (c, b) { |
|
2394 switch (c) { |
|
2395 case '&': |
|
2396 return '&'; |
|
2397 |
|
2398 case '"': |
|
2399 return '"'; |
|
2400 |
|
2401 case '\'': |
|
2402 return '''; // ' is not working in MSIE |
|
2403 |
|
2404 case '<': |
|
2405 return '<'; |
|
2406 |
|
2407 case '>': |
|
2408 return '>'; |
|
2409 } |
|
2410 |
|
2411 return c; |
|
2412 }) : s; |
|
2413 }, |
|
2414 |
|
2415 extend : function(p, np) { |
|
2416 var o = {}; |
|
2417 |
|
2418 o.parent = p; |
|
2419 |
|
2420 for (n in p) |
|
2421 o[n] = p[n]; |
|
2422 |
|
2423 for (n in np) |
|
2424 o[n] = np[n]; |
|
2425 |
|
2426 return o; |
|
2427 }, |
|
2428 |
|
2429 hideMenus : function() { |
|
2430 var e = tinyMCE.lastSelectedMenuBtn; |
|
2431 |
|
2432 if (tinyMCE.lastMenu) { |
|
2433 tinyMCE.lastMenu.hide(); |
|
2434 tinyMCE.lastMenu = null; |
|
2435 } |
|
2436 |
|
2437 if (e) { |
|
2438 tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass); |
|
2439 tinyMCE.lastSelectedMenuBtn = null; |
|
2440 } |
|
2441 } |
|
2442 |
|
2443 }; |
|
2444 |
|
2445 // Global instances |
|
2446 var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors |
|
2447 var tinyMCE = new TinyMCE_Engine(); |
|
2448 var tinyMCELang = {}; |
|
2449 |
|
2450 /* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */ |
|
2451 |
|
2452 function TinyMCE_Control(settings) { |
|
2453 var t, i, to, fu, p, x, fn, fu, pn, s = settings; |
|
2454 |
|
2455 this.undoRedoLevel = true; |
|
2456 this.isTinyMCE_Control = true; |
|
2457 |
|
2458 // Default settings |
|
2459 this.settings = s; |
|
2460 this.settings['theme'] = tinyMCE.getParam("theme", "default"); |
|
2461 this.settings['width'] = tinyMCE.getParam("width", -1); |
|
2462 this.settings['height'] = tinyMCE.getParam("height", -1); |
|
2463 this.selection = new TinyMCE_Selection(this); |
|
2464 this.undoRedo = new TinyMCE_UndoRedo(this); |
|
2465 this.cleanup = new TinyMCE_Cleanup(); |
|
2466 this.shortcuts = new Array(); |
|
2467 this.hasMouseMoved = false; |
|
2468 this.foreColor = this.backColor = "#999999"; |
|
2469 this.data = {}; |
|
2470 this.cssClasses = []; |
|
2471 |
|
2472 this.cleanup.init({ |
|
2473 valid_elements : s.valid_elements, |
|
2474 extended_valid_elements : s.extended_valid_elements, |
|
2475 valid_child_elements : s.valid_child_elements, |
|
2476 entities : s.entities, |
|
2477 entity_encoding : s.entity_encoding, |
|
2478 debug : s.cleanup_debug, |
|
2479 indent : s.apply_source_formatting, |
|
2480 invalid_elements : s.invalid_elements, |
|
2481 verify_html : s.verify_html, |
|
2482 fix_content_duplication : s.fix_content_duplication, |
|
2483 convert_fonts_to_spans : s.convert_fonts_to_spans |
|
2484 }); |
|
2485 |
|
2486 // Wrap old theme |
|
2487 t = this.settings['theme']; |
|
2488 if (!tinyMCE.hasTheme(t)) { |
|
2489 fn = tinyMCE.callbacks; |
|
2490 to = {}; |
|
2491 |
|
2492 for (i=0; i<fn.length; i++) { |
|
2493 if ((fu = window['TinyMCE_' + t + "_" + fn[i]])) |
|
2494 to[fn[i]] = fu; |
|
2495 } |
|
2496 |
|
2497 tinyMCE.addTheme(t, to); |
|
2498 } |
|
2499 |
|
2500 // Wrap old plugins |
|
2501 this.plugins = new Array(); |
|
2502 p = tinyMCE.getParam('plugins', '', true, ','); |
|
2503 if (p.length > 0) { |
|
2504 for (i=0; i<p.length; i++) { |
|
2505 pn = p[i]; |
|
2506 |
|
2507 if (pn.charAt(0) == '-') |
|
2508 pn = pn.substring(1); |
|
2509 |
|
2510 if (!tinyMCE.hasPlugin(pn)) { |
|
2511 fn = tinyMCE.callbacks; |
|
2512 to = {}; |
|
2513 |
|
2514 for (x=0; x<fn.length; x++) { |
|
2515 if ((fu = window['TinyMCE_' + pn + "_" + fn[x]])) |
|
2516 to[fn[x]] = fu; |
|
2517 } |
|
2518 |
|
2519 tinyMCE.addPlugin(pn, to); |
|
2520 } |
|
2521 |
|
2522 this.plugins[this.plugins.length] = pn; |
|
2523 } |
|
2524 } |
|
2525 }; |
|
2526 |
|
2527 TinyMCE_Control.prototype = { |
|
2528 selection : null, |
|
2529 |
|
2530 settings : null, |
|
2531 |
|
2532 cleanup : null, |
|
2533 |
|
2534 getData : function(na) { |
|
2535 var o = this.data[na]; |
|
2536 |
|
2537 if (!o) |
|
2538 o = this.data[na] = {}; |
|
2539 |
|
2540 return o; |
|
2541 }, |
|
2542 |
|
2543 hasPlugin : function(n) { |
|
2544 var i; |
|
2545 |
|
2546 for (i=0; i<this.plugins.length; i++) { |
|
2547 if (this.plugins[i] == n) |
|
2548 return true; |
|
2549 } |
|
2550 |
|
2551 return false; |
|
2552 }, |
|
2553 |
|
2554 addPlugin : function(n, p) { |
|
2555 if (!this.hasPlugin(n)) { |
|
2556 tinyMCE.addPlugin(n, p); |
|
2557 this.plugins[this.plugins.length] = n; |
|
2558 } |
|
2559 }, |
|
2560 |
|
2561 repaint : function() { |
|
2562 var s, b, ex; |
|
2563 |
|
2564 if (tinyMCE.isRealIE) |
|
2565 return; |
|
2566 |
|
2567 try { |
|
2568 s = this.selection; |
|
2569 b = s.getBookmark(true); |
|
2570 this.getBody().style.display = 'none'; |
|
2571 this.getDoc().execCommand('selectall', false, null); |
|
2572 this.getSel().collapseToStart(); |
|
2573 this.getBody().style.display = 'block'; |
|
2574 s.moveToBookmark(b); |
|
2575 } catch (ex) { |
|
2576 // Ignore |
|
2577 } |
|
2578 }, |
|
2579 |
|
2580 switchSettings : function() { |
|
2581 if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) { |
|
2582 tinyMCE.settings = this.settings; |
|
2583 tinyMCE.currentConfig = this.settings['index']; |
|
2584 } |
|
2585 }, |
|
2586 |
|
2587 select : function() { |
|
2588 var oldInst = tinyMCE.selectedInstance; |
|
2589 |
|
2590 if (oldInst != this) { |
|
2591 if (oldInst) |
|
2592 oldInst.execCommand('mceEndTyping'); |
|
2593 |
|
2594 tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst); |
|
2595 tinyMCE.selectedInstance = this; |
|
2596 } |
|
2597 }, |
|
2598 |
|
2599 getBody : function() { |
|
2600 return this.contentBody ? this.contentBody : this.getDoc().body; |
|
2601 }, |
|
2602 |
|
2603 getDoc : function() { |
|
2604 // return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ? |
|
2605 return this.contentWindow.document; |
|
2606 }, |
|
2607 |
|
2608 getWin : function() { |
|
2609 return this.contentWindow; |
|
2610 }, |
|
2611 |
|
2612 getContainerWin : function() { |
|
2613 return this.containerWindow ? this.containerWindow : window; |
|
2614 }, |
|
2615 |
|
2616 getViewPort : function() { |
|
2617 return tinyMCE.getViewPort(this.getWin()); |
|
2618 }, |
|
2619 |
|
2620 getParentNode : function(n, f) { |
|
2621 return tinyMCE.getParentNode(n, f, this.getBody()); |
|
2622 }, |
|
2623 |
|
2624 getParentElement : function(n, na, f) { |
|
2625 return tinyMCE.getParentElement(n, na, f, this.getBody()); |
|
2626 }, |
|
2627 |
|
2628 getParentBlockElement : function(n) { |
|
2629 return tinyMCE.getParentBlockElement(n, this.getBody()); |
|
2630 }, |
|
2631 |
|
2632 resizeToContent : function() { |
|
2633 var d = this.getDoc(), b = d.body, de = d.documentElement; |
|
2634 |
|
2635 this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px'; |
|
2636 }, |
|
2637 |
|
2638 addShortcut : function(m, k, d, cmd, ui, va) { |
|
2639 var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts; |
|
2640 |
|
2641 if (!tinyMCE.getParam('custom_shortcuts')) |
|
2642 return false; |
|
2643 |
|
2644 m = m.toLowerCase(); |
|
2645 k = ie && !n ? k.toUpperCase() : k; |
|
2646 c = n ? null : k.charCodeAt(0); |
|
2647 d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d; |
|
2648 |
|
2649 sc = { |
|
2650 alt : m.indexOf('alt') != -1, |
|
2651 ctrl : m.indexOf('ctrl') != -1, |
|
2652 shift : m.indexOf('shift') != -1, |
|
2653 charCode : c, |
|
2654 keyCode : n ? k : (ie ? c : null), |
|
2655 desc : d, |
|
2656 cmd : cmd, |
|
2657 ui : ui, |
|
2658 val : va |
|
2659 }; |
|
2660 |
|
2661 for (i=0; i<scl.length; i++) { |
|
2662 if (sc.alt == scl[i].alt && sc.ctrl == scl[i].ctrl && sc.shift == scl[i].shift |
|
2663 && sc.charCode == scl[i].charCode && sc.keyCode == scl[i].keyCode) { |
|
2664 return false; |
|
2665 } |
|
2666 } |
|
2667 |
|
2668 scl[scl.length] = sc; |
|
2669 |
|
2670 return true; |
|
2671 }, |
|
2672 |
|
2673 handleShortcut : function(e) { |
|
2674 var i, s, o; |
|
2675 |
|
2676 // Normal key press, then ignore it |
|
2677 if (!e.altKey && !e.ctrlKey) |
|
2678 return false; |
|
2679 |
|
2680 s = this.shortcuts; |
|
2681 |
|
2682 for (i=0; i<s.length; i++) { |
|
2683 o = s[i]; |
|
2684 |
|
2685 if (o.alt == e.altKey && o.ctrl == e.ctrlKey && (o.keyCode == e.keyCode || o.charCode == e.charCode)) { |
|
2686 if (o.cmd && (e.type == "keydown" || (e.type == "keypress" && !tinyMCE.isOpera))) |
|
2687 tinyMCE.execCommand(o.cmd, o.ui, o.val); |
|
2688 |
|
2689 tinyMCE.cancelEvent(e); |
|
2690 return true; |
|
2691 } |
|
2692 } |
|
2693 |
|
2694 return false; |
|
2695 }, |
|
2696 |
|
2697 autoResetDesignMode : function() { |
|
2698 // Add fix for tab/style.display none/block problems in Gecko |
|
2699 if (!tinyMCE.isIE && this.isHidden() && tinyMCE.getParam('auto_reset_designmode')) |
|
2700 eval('try { this.getDoc().designMode = "On"; this.useCSS = false; } catch(e) {}'); |
|
2701 }, |
|
2702 |
|
2703 isHidden : function() { |
|
2704 var s; |
|
2705 |
|
2706 if (tinyMCE.isIE) |
|
2707 return false; |
|
2708 |
|
2709 s = this.getSel(); |
|
2710 |
|
2711 // Weird, wheres that cursor selection? |
|
2712 return (!s || !s.rangeCount || s.rangeCount == 0); |
|
2713 }, |
|
2714 |
|
2715 isDirty : function() { |
|
2716 // Is content modified and not in a submit procedure |
|
2717 return tinyMCE.trim(this.startContent) != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty; |
|
2718 }, |
|
2719 |
|
2720 _mergeElements : function(scmd, pa, ch, override) { |
|
2721 if (scmd == "removeformat") { |
|
2722 pa.className = ""; |
|
2723 pa.style.cssText = ""; |
|
2724 ch.className = ""; |
|
2725 ch.style.cssText = ""; |
|
2726 return; |
|
2727 } |
|
2728 |
|
2729 var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style")); |
|
2730 var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style")); |
|
2731 var className = tinyMCE.getAttrib(pa, "class"); |
|
2732 |
|
2733 // Removed class adding due to bug #1478272 |
|
2734 className = tinyMCE.getAttrib(ch, "class"); |
|
2735 |
|
2736 if (override) { |
|
2737 for (var n in st) { |
|
2738 if (typeof(st[n]) == 'function') |
|
2739 continue; |
|
2740 |
|
2741 stc[n] = st[n]; |
|
2742 } |
|
2743 } else { |
|
2744 for (var n in stc) { |
|
2745 if (typeof(stc[n]) == 'function') |
|
2746 continue; |
|
2747 |
|
2748 st[n] = stc[n]; |
|
2749 } |
|
2750 } |
|
2751 |
|
2752 tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st)); |
|
2753 tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className)); |
|
2754 ch.className = ""; |
|
2755 ch.style.cssText = ""; |
|
2756 ch.removeAttribute("class"); |
|
2757 ch.removeAttribute("style"); |
|
2758 }, |
|
2759 |
|
2760 _setUseCSS : function(b) { |
|
2761 var d = this.getDoc(); |
|
2762 |
|
2763 try {d.execCommand("useCSS", false, !b);} catch (ex) {} |
|
2764 try {d.execCommand("styleWithCSS", false, b);} catch (ex) {} |
|
2765 |
|
2766 if (!tinyMCE.getParam("table_inline_editing")) |
|
2767 try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {} |
|
2768 |
|
2769 if (!tinyMCE.getParam("object_resizing")) |
|
2770 try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {} |
|
2771 }, |
|
2772 |
|
2773 execCommand : function(command, user_interface, value) { |
|
2774 var doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement(); |
|
2775 |
|
2776 // Is not a undo specific command |
|
2777 if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) |
|
2778 this.undoBookmark = null; |
|
2779 |
|
2780 // Mozilla issue |
|
2781 if (!tinyMCE.isIE && !this.useCSS) { |
|
2782 this._setUseCSS(false); |
|
2783 this.useCSS = true; |
|
2784 } |
|
2785 |
|
2786 //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value); |
|
2787 this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks |
|
2788 |
|
2789 // Don't dispatch key commands |
|
2790 if (!/mceStartTyping|mceEndTyping/.test(command)) { |
|
2791 if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) |
|
2792 return; |
|
2793 } |
|
2794 |
|
2795 // Fix align on images |
|
2796 if (focusElm && focusElm.nodeName == "IMG") { |
|
2797 var align = focusElm.getAttribute('align'); |
|
2798 var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm; |
|
2799 |
|
2800 switch (command) { |
|
2801 case "JustifyLeft": |
|
2802 if (align == 'left') |
|
2803 img.removeAttribute('align'); |
|
2804 else |
|
2805 img.setAttribute('align', 'left'); |
|
2806 |
|
2807 // Remove the div |
|
2808 var div = focusElm.parentNode; |
|
2809 if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) |
|
2810 div.parentNode.replaceChild(img, div); |
|
2811 |
|
2812 this.selection.selectNode(img); |
|
2813 this.repaint(); |
|
2814 tinyMCE.triggerNodeChange(); |
|
2815 return; |
|
2816 |
|
2817 case "JustifyCenter": |
|
2818 img.removeAttribute('align'); |
|
2819 |
|
2820 // Is centered |
|
2821 var div = tinyMCE.getParentElement(focusElm, "div"); |
|
2822 if (div && div.style.textAlign == "center") { |
|
2823 // Remove div |
|
2824 if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) |
|
2825 div.parentNode.replaceChild(img, div); |
|
2826 } else { |
|
2827 // Add div |
|
2828 var div = this.getDoc().createElement("div"); |
|
2829 div.style.textAlign = 'center'; |
|
2830 div.appendChild(img); |
|
2831 focusElm.parentNode.replaceChild(div, focusElm); |
|
2832 } |
|
2833 |
|
2834 this.selection.selectNode(img); |
|
2835 this.repaint(); |
|
2836 tinyMCE.triggerNodeChange(); |
|
2837 return; |
|
2838 |
|
2839 case "JustifyRight": |
|
2840 if (align == 'right') |
|
2841 img.removeAttribute('align'); |
|
2842 else |
|
2843 img.setAttribute('align', 'right'); |
|
2844 |
|
2845 // Remove the div |
|
2846 var div = focusElm.parentNode; |
|
2847 if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) |
|
2848 div.parentNode.replaceChild(img, div); |
|
2849 |
|
2850 this.selection.selectNode(img); |
|
2851 this.repaint(); |
|
2852 tinyMCE.triggerNodeChange(); |
|
2853 return; |
|
2854 } |
|
2855 } |
|
2856 |
|
2857 if (tinyMCE.settings['force_br_newlines']) { |
|
2858 var alignValue = ""; |
|
2859 |
|
2860 if (doc.selection.type != "Control") { |
|
2861 switch (command) { |
|
2862 case "JustifyLeft": |
|
2863 alignValue = "left"; |
|
2864 break; |
|
2865 |
|
2866 case "JustifyCenter": |
|
2867 alignValue = "center"; |
|
2868 break; |
|
2869 |
|
2870 case "JustifyFull": |
|
2871 alignValue = "justify"; |
|
2872 break; |
|
2873 |
|
2874 case "JustifyRight": |
|
2875 alignValue = "right"; |
|
2876 break; |
|
2877 } |
|
2878 |
|
2879 if (alignValue != "") { |
|
2880 var rng = doc.selection.createRange(); |
|
2881 |
|
2882 if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null) |
|
2883 divElm.setAttribute("align", alignValue); |
|
2884 else if (rng.pasteHTML && rng.htmlText.length > 0) |
|
2885 rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>"); |
|
2886 |
|
2887 tinyMCE.triggerNodeChange(); |
|
2888 return; |
|
2889 } |
|
2890 } |
|
2891 } |
|
2892 |
|
2893 switch (command) { |
|
2894 case "mceRepaint": |
|
2895 this.repaint(); |
|
2896 return true; |
|
2897 |
|
2898 case "unlink": |
|
2899 // Unlink if caret is inside link |
|
2900 if (tinyMCE.isGecko && this.getSel().isCollapsed) { |
|
2901 focusElm = tinyMCE.getParentElement(focusElm, 'A'); |
|
2902 |
|
2903 if (focusElm) |
|
2904 this.selection.selectNode(focusElm, false); |
|
2905 } |
|
2906 |
|
2907 this.getDoc().execCommand(command, user_interface, value); |
|
2908 |
|
2909 tinyMCE.isGecko && this.getSel().collapseToEnd(); |
|
2910 |
|
2911 tinyMCE.triggerNodeChange(); |
|
2912 |
|
2913 return true; |
|
2914 |
|
2915 case "InsertUnorderedList": |
|
2916 case "InsertOrderedList": |
|
2917 this.getDoc().execCommand(command, user_interface, value); |
|
2918 tinyMCE.triggerNodeChange(); |
|
2919 break; |
|
2920 |
|
2921 case "Strikethrough": |
|
2922 this.getDoc().execCommand(command, user_interface, value); |
|
2923 tinyMCE.triggerNodeChange(); |
|
2924 break; |
|
2925 |
|
2926 case "mceSelectNode": |
|
2927 this.selection.selectNode(value); |
|
2928 tinyMCE.triggerNodeChange(); |
|
2929 tinyMCE.selectedNode = value; |
|
2930 break; |
|
2931 |
|
2932 case "FormatBlock": |
|
2933 if (value == null || value == "") { |
|
2934 var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp"); |
|
2935 |
|
2936 if (elm) |
|
2937 this.execCommand("mceRemoveNode", false, elm); |
|
2938 } else { |
|
2939 if (!this.cleanup.isValid(value)) |
|
2940 return true; |
|
2941 |
|
2942 if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) |
|
2943 value = value.replace(/[^a-z]/gi, ''); |
|
2944 |
|
2945 if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) { |
|
2946 var b = this.selection.getBookmark(); |
|
2947 this.getDoc().execCommand("FormatBlock", false, '<p>'); |
|
2948 tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value); |
|
2949 this.selection.moveToBookmark(b); |
|
2950 } else |
|
2951 this.getDoc().execCommand("FormatBlock", false, value); |
|
2952 } |
|
2953 |
|
2954 tinyMCE.triggerNodeChange(); |
|
2955 |
|
2956 break; |
|
2957 |
|
2958 case "mceRemoveNode": |
|
2959 if (!value) |
|
2960 value = tinyMCE.getParentElement(this.getFocusElement()); |
|
2961 |
|
2962 if (tinyMCE.isIE) { |
|
2963 value.outerHTML = value.innerHTML; |
|
2964 } else { |
|
2965 var rng = value.ownerDocument.createRange(); |
|
2966 rng.setStartBefore(value); |
|
2967 rng.setEndAfter(value); |
|
2968 rng.deleteContents(); |
|
2969 rng.insertNode(rng.createContextualFragment(value.innerHTML)); |
|
2970 } |
|
2971 |
|
2972 tinyMCE.triggerNodeChange(); |
|
2973 |
|
2974 break; |
|
2975 |
|
2976 case "mceSelectNodeDepth": |
|
2977 var parentNode = this.getFocusElement(); |
|
2978 for (var i=0; parentNode; i++) { |
|
2979 if (parentNode.nodeName.toLowerCase() == "body") |
|
2980 break; |
|
2981 |
|
2982 if (parentNode.nodeName.toLowerCase() == "#text") { |
|
2983 i--; |
|
2984 parentNode = parentNode.parentNode; |
|
2985 continue; |
|
2986 } |
|
2987 |
|
2988 if (i == value) { |
|
2989 this.selection.selectNode(parentNode, false); |
|
2990 tinyMCE.triggerNodeChange(); |
|
2991 tinyMCE.selectedNode = parentNode; |
|
2992 return; |
|
2993 } |
|
2994 |
|
2995 parentNode = parentNode.parentNode; |
|
2996 } |
|
2997 |
|
2998 break; |
|
2999 |
|
3000 case "mceSetStyleInfo": |
|
3001 case "SetStyleInfo": |
|
3002 var rng = this.getRng(); |
|
3003 var sel = this.getSel(); |
|
3004 var scmd = value['command']; |
|
3005 var sname = value['name']; |
|
3006 var svalue = value['value'] == null ? '' : value['value']; |
|
3007 //var svalue = value['value'] == null ? '' : value['value']; |
|
3008 var wrapper = value['wrapper'] ? value['wrapper'] : "span"; |
|
3009 var parentElm = null; |
|
3010 var invalidRe = new RegExp("^BODY|HTML$", "g"); |
|
3011 var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null; |
|
3012 |
|
3013 // Whole element selected check |
|
3014 if (tinyMCE.isIE) { |
|
3015 // Control range |
|
3016 if (rng.item) |
|
3017 parentElm = rng.item(0); |
|
3018 else { |
|
3019 var pelm = rng.parentElement(); |
|
3020 var prng = doc.selection.createRange(); |
|
3021 prng.moveToElementText(pelm); |
|
3022 |
|
3023 if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) { |
|
3024 if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName)) |
|
3025 parentElm = pelm; |
|
3026 } |
|
3027 } |
|
3028 } else { |
|
3029 var felm = this.getFocusElement(); |
|
3030 if (sel.isCollapsed || (new RegExp('td|tr|tbody|table', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode)) |
|
3031 parentElm = felm; |
|
3032 } |
|
3033 |
|
3034 // Whole element selected |
|
3035 if (parentElm && !invalidRe.test(parentElm.nodeName)) { |
|
3036 if (scmd == "setstyle") |
|
3037 tinyMCE.setStyleAttrib(parentElm, sname, svalue); |
|
3038 |
|
3039 if (scmd == "setattrib") |
|
3040 tinyMCE.setAttrib(parentElm, sname, svalue); |
|
3041 |
|
3042 if (scmd == "removeformat") { |
|
3043 parentElm.style.cssText = ''; |
|
3044 tinyMCE.setAttrib(parentElm, 'class', ''); |
|
3045 } |
|
3046 |
|
3047 // Remove style/attribs from all children |
|
3048 var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1); |
|
3049 for (var z=0; z<ch.length; z++) { |
|
3050 if (ch[z] == parentElm) |
|
3051 continue; |
|
3052 |
|
3053 if (scmd == "setstyle") |
|
3054 tinyMCE.setStyleAttrib(ch[z], sname, ''); |
|
3055 |
|
3056 if (scmd == "setattrib") |
|
3057 tinyMCE.setAttrib(ch[z], sname, ''); |
|
3058 |
|
3059 if (scmd == "removeformat") { |
|
3060 ch[z].style.cssText = ''; |
|
3061 tinyMCE.setAttrib(ch[z], 'class', ''); |
|
3062 } |
|
3063 } |
|
3064 } else { |
|
3065 this._setUseCSS(false); // Bug in FF when running in fullscreen |
|
3066 doc.execCommand("FontName", false, "#mce_temp_font#"); |
|
3067 var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#"); |
|
3068 |
|
3069 // Change them all |
|
3070 for (var x=0; x<elementArray.length; x++) { |
|
3071 elm = elementArray[x]; |
|
3072 if (elm) { |
|
3073 var spanElm = doc.createElement(wrapper); |
|
3074 |
|
3075 if (scmd == "setstyle") |
|
3076 tinyMCE.setStyleAttrib(spanElm, sname, svalue); |
|
3077 |
|
3078 if (scmd == "setattrib") |
|
3079 tinyMCE.setAttrib(spanElm, sname, svalue); |
|
3080 |
|
3081 if (scmd == "removeformat") { |
|
3082 spanElm.style.cssText = ''; |
|
3083 tinyMCE.setAttrib(spanElm, 'class', ''); |
|
3084 } |
|
3085 |
|
3086 if (elm.hasChildNodes()) { |
|
3087 for (var i=0; i<elm.childNodes.length; i++) |
|
3088 spanElm.appendChild(elm.childNodes[i].cloneNode(true)); |
|
3089 } |
|
3090 |
|
3091 spanElm.setAttribute("mce_new", "true"); |
|
3092 elm.parentNode.replaceChild(spanElm, elm); |
|
3093 |
|
3094 // Remove style/attribs from all children |
|
3095 var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1); |
|
3096 for (var z=0; z<ch.length; z++) { |
|
3097 if (ch[z] == spanElm) |
|
3098 continue; |
|
3099 |
|
3100 if (scmd == "setstyle") |
|
3101 tinyMCE.setStyleAttrib(ch[z], sname, ''); |
|
3102 |
|
3103 if (scmd == "setattrib") |
|
3104 tinyMCE.setAttrib(ch[z], sname, ''); |
|
3105 |
|
3106 if (scmd == "removeformat") { |
|
3107 ch[z].style.cssText = ''; |
|
3108 tinyMCE.setAttrib(ch[z], 'class', ''); |
|
3109 } |
|
3110 } |
|
3111 } |
|
3112 } |
|
3113 } |
|
3114 |
|
3115 // Cleaup wrappers |
|
3116 var nodes = doc.getElementsByTagName(wrapper); |
|
3117 for (var i=nodes.length-1; i>=0; i--) { |
|
3118 var elm = nodes[i]; |
|
3119 var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true"; |
|
3120 |
|
3121 elm.removeAttribute("mce_new"); |
|
3122 |
|
3123 // Is only child a element |
|
3124 if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) { |
|
3125 //tinyMCE.debug("merge1" + isNew); |
|
3126 this._mergeElements(scmd, elm, elm.childNodes[0], isNew); |
|
3127 continue; |
|
3128 } |
|
3129 |
|
3130 // Is I the only child |
|
3131 if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) { |
|
3132 //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName); |
|
3133 if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName)) |
|
3134 this._mergeElements(scmd, elm.parentNode, elm, false); |
|
3135 } |
|
3136 } |
|
3137 |
|
3138 // Remove empty wrappers |
|
3139 var nodes = doc.getElementsByTagName(wrapper); |
|
3140 for (var i=nodes.length-1; i>=0; i--) { |
|
3141 var elm = nodes[i]; |
|
3142 var isEmpty = true; |
|
3143 |
|
3144 // Check if it has any attribs |
|
3145 var tmp = doc.createElement("body"); |
|
3146 tmp.appendChild(elm.cloneNode(false)); |
|
3147 |
|
3148 // Is empty span, remove it |
|
3149 tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), ''); |
|
3150 //tinyMCE.debug(tmp.innerHTML); |
|
3151 if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) { |
|
3152 for (var x=0; x<elm.childNodes.length; x++) { |
|
3153 if (elm.parentNode != null) |
|
3154 elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm); |
|
3155 } |
|
3156 |
|
3157 elm.parentNode.removeChild(elm); |
|
3158 } |
|
3159 } |
|
3160 |
|
3161 // Re add the visual aids |
|
3162 if (scmd == "removeformat") |
|
3163 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); |
|
3164 |
|
3165 tinyMCE.triggerNodeChange(); |
|
3166 |
|
3167 break; |
|
3168 |
|
3169 case "FontName": |
|
3170 if (value == null) { |
|
3171 var s = this.getSel(); |
|
3172 |
|
3173 // Find font and select it |
|
3174 if (tinyMCE.isGecko && s.isCollapsed) { |
|
3175 var f = tinyMCE.getParentElement(this.getFocusElement(), "font"); |
|
3176 |
|
3177 if (f != null) |
|
3178 this.selection.selectNode(f, false); |
|
3179 } |
|
3180 |
|
3181 // Remove format |
|
3182 this.getDoc().execCommand("RemoveFormat", false, null); |
|
3183 |
|
3184 // Collapse range if font was found |
|
3185 if (f != null && tinyMCE.isGecko) { |
|
3186 var r = this.getRng().cloneRange(); |
|
3187 r.collapse(true); |
|
3188 s.removeAllRanges(); |
|
3189 s.addRange(r); |
|
3190 } |
|
3191 } else |
|
3192 this.getDoc().execCommand('FontName', false, value); |
|
3193 |
|
3194 if (tinyMCE.isGecko) |
|
3195 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); |
|
3196 |
|
3197 return; |
|
3198 |
|
3199 case "FontSize": |
|
3200 this.getDoc().execCommand('FontSize', false, value); |
|
3201 |
|
3202 if (tinyMCE.isGecko) |
|
3203 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); |
|
3204 |
|
3205 return; |
|
3206 |
|
3207 case "forecolor": |
|
3208 value = value == null ? this.foreColor : value; |
|
3209 value = tinyMCE.trim(value); |
|
3210 value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value; |
|
3211 |
|
3212 this.foreColor = value; |
|
3213 this.getDoc().execCommand('forecolor', false, value); |
|
3214 break; |
|
3215 |
|
3216 case "HiliteColor": |
|
3217 value = value == null ? this.backColor : value; |
|
3218 value = tinyMCE.trim(value); |
|
3219 value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value; |
|
3220 this.backColor = value; |
|
3221 |
|
3222 if (tinyMCE.isGecko) { |
|
3223 this._setUseCSS(true); |
|
3224 this.getDoc().execCommand('hilitecolor', false, value); |
|
3225 this._setUseCSS(false); |
|
3226 } else |
|
3227 this.getDoc().execCommand('BackColor', false, value); |
|
3228 break; |
|
3229 |
|
3230 case "Cut": |
|
3231 case "Copy": |
|
3232 case "Paste": |
|
3233 var cmdFailed = false; |
|
3234 |
|
3235 // Try executing command |
|
3236 eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}'); |
|
3237 |
|
3238 if (tinyMCE.isOpera && cmdFailed) |
|
3239 alert('Currently not supported by your browser, use keyboard shortcuts instead.'); |
|
3240 |
|
3241 // Alert error in gecko if command failed |
|
3242 if (tinyMCE.isGecko && cmdFailed) { |
|
3243 // Confirm more info |
|
3244 if (confirm(tinyMCE.entityDecode(tinyMCE.getLang('lang_clipboard_msg')))) |
|
3245 window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal'); |
|
3246 |
|
3247 return; |
|
3248 } else |
|
3249 tinyMCE.triggerNodeChange(); |
|
3250 break; |
|
3251 |
|
3252 case "mceSetContent": |
|
3253 if (!value) |
|
3254 value = ""; |
|
3255 |
|
3256 // Call custom cleanup code |
|
3257 value = tinyMCE.storeAwayURLs(value); |
|
3258 value = tinyMCE._customCleanup(this, "insert_to_editor", value); |
|
3259 |
|
3260 if (this.getBody().nodeName == 'BODY') |
|
3261 tinyMCE._setHTML(doc, value); |
|
3262 else |
|
3263 this.getBody().innerHTML = value; |
|
3264 |
|
3265 tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, doc, this.settings, this.getBody(), false, false, false, true)); |
|
3266 tinyMCE.convertAllRelativeURLs(this.getBody()); |
|
3267 |
|
3268 // Cleanup any mess left from storyAwayURLs |
|
3269 tinyMCE._removeInternal(this.getBody()); |
|
3270 |
|
3271 // When editing always use fonts internaly |
|
3272 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
3273 tinyMCE.convertSpansToFonts(doc); |
|
3274 |
|
3275 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); |
|
3276 tinyMCE._setEventsEnabled(this.getBody(), false); |
|
3277 return true; |
|
3278 |
|
3279 case "mceCleanup": |
|
3280 var b = this.selection.getBookmark(); |
|
3281 tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML); |
|
3282 tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid)); |
|
3283 tinyMCE.convertAllRelativeURLs(doc.body); |
|
3284 |
|
3285 // When editing always use fonts internaly |
|
3286 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
3287 tinyMCE.convertSpansToFonts(doc); |
|
3288 |
|
3289 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); |
|
3290 tinyMCE._setEventsEnabled(this.getBody(), false); |
|
3291 this.repaint(); |
|
3292 this.selection.moveToBookmark(b); |
|
3293 tinyMCE.triggerNodeChange(); |
|
3294 break; |
|
3295 |
|
3296 case "mceReplaceContent": |
|
3297 // Force empty string |
|
3298 if (!value) |
|
3299 value = ''; |
|
3300 |
|
3301 this.getWin().focus(); |
|
3302 |
|
3303 var selectedText = ""; |
|
3304 |
|
3305 if (tinyMCE.isIE) { |
|
3306 var rng = doc.selection.createRange(); |
|
3307 selectedText = rng.text; |
|
3308 } else |
|
3309 selectedText = this.getSel().toString(); |
|
3310 |
|
3311 if (selectedText.length > 0) { |
|
3312 value = tinyMCE.replaceVar(value, "selection", selectedText); |
|
3313 tinyMCE.execCommand('mceInsertContent', false, value); |
|
3314 } |
|
3315 |
|
3316 tinyMCE.triggerNodeChange(); |
|
3317 break; |
|
3318 |
|
3319 case "mceSetAttribute": |
|
3320 if (typeof(value) == 'object') { |
|
3321 var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets']; |
|
3322 var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms); |
|
3323 |
|
3324 if (targetNode) { |
|
3325 targetNode.setAttribute(value['name'], value['value']); |
|
3326 tinyMCE.triggerNodeChange(); |
|
3327 } |
|
3328 } |
|
3329 break; |
|
3330 |
|
3331 case "mceSetCSSClass": |
|
3332 this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value}); |
|
3333 break; |
|
3334 |
|
3335 case "mceInsertRawHTML": |
|
3336 var key = 'tiny_mce_marker'; |
|
3337 |
|
3338 this.execCommand('mceBeginUndoLevel'); |
|
3339 |
|
3340 // Insert marker key |
|
3341 this.execCommand('mceInsertContent', false, key); |
|
3342 |
|
3343 // Store away scroll pos |
|
3344 var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft; |
|
3345 var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop; |
|
3346 |
|
3347 // Find marker and replace with RAW HTML |
|
3348 var html = this.getBody().innerHTML; |
|
3349 if ((pos = html.indexOf(key)) != -1) |
|
3350 tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length)); |
|
3351 |
|
3352 // Restore scoll pos |
|
3353 this.contentWindow.scrollTo(scrollX, scrollY); |
|
3354 |
|
3355 this.execCommand('mceEndUndoLevel'); |
|
3356 |
|
3357 break; |
|
3358 |
|
3359 case "mceInsertContent": |
|
3360 // Force empty string |
|
3361 if (!value) |
|
3362 value = ''; |
|
3363 |
|
3364 var insertHTMLFailed = false; |
|
3365 |
|
3366 // Removed since it produced problems in IE |
|
3367 // this.getWin().focus(); |
|
3368 |
|
3369 if (tinyMCE.isGecko || tinyMCE.isOpera) { |
|
3370 try { |
|
3371 // Is plain text or HTML, &, etc will be encoded wrong in FF |
|
3372 if (value.indexOf('<') == -1 && !value.match(/(&| |<|>)/g)) { |
|
3373 var r = this.getRng(); |
|
3374 var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value)); |
|
3375 var s = this.getSel(); |
|
3376 var r2 = r.cloneRange(); |
|
3377 |
|
3378 // Insert text at cursor position |
|
3379 s.removeAllRanges(); |
|
3380 r.deleteContents(); |
|
3381 r.insertNode(n); |
|
3382 |
|
3383 // Move the cursor to the end of text |
|
3384 r2.selectNode(n); |
|
3385 r2.collapse(false); |
|
3386 s.removeAllRanges(); |
|
3387 s.addRange(r2); |
|
3388 } else { |
|
3389 value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value); |
|
3390 this.getDoc().execCommand('inserthtml', false, value); |
|
3391 tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); |
|
3392 } |
|
3393 } catch (ex) { |
|
3394 insertHTMLFailed = true; |
|
3395 } |
|
3396 |
|
3397 if (!insertHTMLFailed) { |
|
3398 tinyMCE.triggerNodeChange(); |
|
3399 return; |
|
3400 } |
|
3401 } |
|
3402 |
|
3403 if (!tinyMCE.isIE) { |
|
3404 var isHTML = value.indexOf('<') != -1; |
|
3405 var sel = this.getSel(); |
|
3406 var rng = this.getRng(); |
|
3407 |
|
3408 if (isHTML) { |
|
3409 if (tinyMCE.isSafari) { |
|
3410 var tmpRng = this.getDoc().createRange(); |
|
3411 |
|
3412 tmpRng.setStart(this.getBody(), 0); |
|
3413 tmpRng.setEnd(this.getBody(), 0); |
|
3414 |
|
3415 value = tmpRng.createContextualFragment(value); |
|
3416 } else |
|
3417 value = rng.createContextualFragment(value); |
|
3418 } else { |
|
3419 // Setup text node |
|
3420 var el = document.createElement("div"); |
|
3421 el.innerHTML = value; |
|
3422 value = el.firstChild.nodeValue; |
|
3423 value = doc.createTextNode(value); |
|
3424 } |
|
3425 |
|
3426 // Insert plain text in Safari |
|
3427 if (tinyMCE.isSafari && !isHTML) { |
|
3428 this.execCommand('InsertText', false, value.nodeValue); |
|
3429 tinyMCE.triggerNodeChange(); |
|
3430 return true; |
|
3431 } else if (tinyMCE.isSafari && isHTML) { |
|
3432 rng.deleteContents(); |
|
3433 rng.insertNode(value); |
|
3434 tinyMCE.triggerNodeChange(); |
|
3435 return true; |
|
3436 } |
|
3437 |
|
3438 rng.deleteContents(); |
|
3439 |
|
3440 // If target node is text do special treatment, (Mozilla 1.3 fix) |
|
3441 if (rng.startContainer.nodeType == 3) { |
|
3442 var node = rng.startContainer.splitText(rng.startOffset); |
|
3443 node.parentNode.insertBefore(value, node); |
|
3444 } else |
|
3445 rng.insertNode(value); |
|
3446 |
|
3447 if (!isHTML) { |
|
3448 // Removes weird selection trails |
|
3449 sel.selectAllChildren(doc.body); |
|
3450 sel.removeAllRanges(); |
|
3451 |
|
3452 // Move cursor to end of content |
|
3453 var rng = doc.createRange(); |
|
3454 |
|
3455 rng.selectNode(value); |
|
3456 rng.collapse(false); |
|
3457 |
|
3458 sel.addRange(rng); |
|
3459 } else |
|
3460 rng.collapse(false); |
|
3461 |
|
3462 tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); |
|
3463 } else { |
|
3464 var rng = doc.selection.createRange(), tmpRng = null; |
|
3465 var c = value.indexOf('<!--') != -1; |
|
3466 |
|
3467 // Fix comment bug, add tag before comments |
|
3468 if (c) |
|
3469 value = tinyMCE.uniqueTag + value; |
|
3470 |
|
3471 // tmpRng = rng.duplicate(); // Store away range (Fixes Undo bookmark bug in IE) |
|
3472 |
|
3473 if (rng.item) |
|
3474 rng.item(0).outerHTML = value; |
|
3475 else |
|
3476 rng.pasteHTML(value); |
|
3477 |
|
3478 //if (tmpRng) |
|
3479 // tmpRng.select(); // Restore range (Fixes Undo bookmark bug in IE) |
|
3480 |
|
3481 // Remove unique tag |
|
3482 if (c) { |
|
3483 var e = this.getDoc().getElementById('mceTMPElement'); |
|
3484 e.parentNode.removeChild(e); |
|
3485 } |
|
3486 } |
|
3487 |
|
3488 tinyMCE.execCommand("mceAddUndoLevel"); |
|
3489 tinyMCE.triggerNodeChange(); |
|
3490 break; |
|
3491 |
|
3492 case "mceStartTyping": |
|
3493 if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex == -1) { |
|
3494 this.undoRedo.typingUndoIndex = this.undoRedo.undoIndex; |
|
3495 tinyMCE.typingUndoIndex = tinyMCE.undoIndex; |
|
3496 this.execCommand('mceAddUndoLevel'); |
|
3497 } |
|
3498 break; |
|
3499 |
|
3500 case "mceEndTyping": |
|
3501 if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex != -1) { |
|
3502 this.execCommand('mceAddUndoLevel'); |
|
3503 this.undoRedo.typingUndoIndex = -1; |
|
3504 } |
|
3505 |
|
3506 tinyMCE.typingUndoIndex = -1; |
|
3507 break; |
|
3508 |
|
3509 case "mceBeginUndoLevel": |
|
3510 this.undoRedoLevel = false; |
|
3511 break; |
|
3512 |
|
3513 case "mceEndUndoLevel": |
|
3514 this.undoRedoLevel = true; |
|
3515 this.execCommand('mceAddUndoLevel'); |
|
3516 break; |
|
3517 |
|
3518 case "mceAddUndoLevel": |
|
3519 if (tinyMCE.settings['custom_undo_redo'] && this.undoRedoLevel) { |
|
3520 if (this.undoRedo.add()) |
|
3521 tinyMCE.triggerNodeChange(false); |
|
3522 } |
|
3523 break; |
|
3524 |
|
3525 case "Undo": |
|
3526 if (tinyMCE.settings['custom_undo_redo']) { |
|
3527 tinyMCE.execCommand("mceEndTyping"); |
|
3528 this.undoRedo.undo(); |
|
3529 tinyMCE.triggerNodeChange(); |
|
3530 } else |
|
3531 this.getDoc().execCommand(command, user_interface, value); |
|
3532 break; |
|
3533 |
|
3534 case "Redo": |
|
3535 if (tinyMCE.settings['custom_undo_redo']) { |
|
3536 tinyMCE.execCommand("mceEndTyping"); |
|
3537 this.undoRedo.redo(); |
|
3538 tinyMCE.triggerNodeChange(); |
|
3539 } else |
|
3540 this.getDoc().execCommand(command, user_interface, value); |
|
3541 break; |
|
3542 |
|
3543 case "mceToggleVisualAid": |
|
3544 this.visualAid = !this.visualAid; |
|
3545 tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this); |
|
3546 tinyMCE.triggerNodeChange(); |
|
3547 break; |
|
3548 |
|
3549 case "Indent": |
|
3550 this.getDoc().execCommand(command, user_interface, value); |
|
3551 tinyMCE.triggerNodeChange(); |
|
3552 |
|
3553 if (tinyMCE.isIE) { |
|
3554 var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote"); |
|
3555 do { |
|
3556 if (n && n.nodeName == "BLOCKQUOTE") { |
|
3557 n.removeAttribute("dir"); |
|
3558 n.removeAttribute("style"); |
|
3559 } |
|
3560 } while (n != null && (n = n.parentNode) != null); |
|
3561 } |
|
3562 break; |
|
3563 |
|
3564 case "RemoveFormat": |
|
3565 case "removeformat": |
|
3566 var text = this.selection.getSelectedText(); |
|
3567 |
|
3568 if (tinyMCE.isOpera) { |
|
3569 this.getDoc().execCommand("RemoveFormat", false, null); |
|
3570 return; |
|
3571 } |
|
3572 |
|
3573 if (tinyMCE.isIE) { |
|
3574 try { |
|
3575 var rng = doc.selection.createRange(); |
|
3576 rng.execCommand("RemoveFormat", false, null); |
|
3577 } catch (e) { |
|
3578 // Do nothing |
|
3579 } |
|
3580 |
|
3581 this.execCommand("mceSetStyleInfo", false, {command : "removeformat"}); |
|
3582 } else { |
|
3583 this.getDoc().execCommand(command, user_interface, value); |
|
3584 |
|
3585 this.execCommand("mceSetStyleInfo", false, {command : "removeformat"}); |
|
3586 } |
|
3587 |
|
3588 // Remove class |
|
3589 if (text.length == 0) |
|
3590 this.execCommand("mceSetCSSClass", false, ""); |
|
3591 |
|
3592 tinyMCE.triggerNodeChange(); |
|
3593 break; |
|
3594 |
|
3595 default: |
|
3596 this.getDoc().execCommand(command, user_interface, value); |
|
3597 |
|
3598 if (tinyMCE.isGecko) |
|
3599 window.setTimeout('tinyMCE.triggerNodeChange(false);', 1); |
|
3600 else |
|
3601 tinyMCE.triggerNodeChange(); |
|
3602 } |
|
3603 |
|
3604 // Add undo level after modification |
|
3605 if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping") |
|
3606 tinyMCE.execCommand("mceAddUndoLevel"); |
|
3607 }, |
|
3608 |
|
3609 queryCommandValue : function(c) { |
|
3610 try { |
|
3611 return this.getDoc().queryCommandValue(c); |
|
3612 } catch (e) { |
|
3613 return null; |
|
3614 } |
|
3615 }, |
|
3616 |
|
3617 queryCommandState : function(c) { |
|
3618 return this.getDoc().queryCommandState(c); |
|
3619 }, |
|
3620 |
|
3621 _onAdd : function(replace_element, form_element_name, target_document) { |
|
3622 var hc, th, to, editorTemplate; |
|
3623 |
|
3624 th = this.settings['theme']; |
|
3625 to = tinyMCE.themes[th]; |
|
3626 |
|
3627 var targetDoc = target_document ? target_document : document; |
|
3628 |
|
3629 this.targetDoc = targetDoc; |
|
3630 |
|
3631 tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme']; |
|
3632 this.settings['themeurl'] = tinyMCE.themeURL; |
|
3633 |
|
3634 if (!replace_element) { |
|
3635 alert("Error: Could not find the target element."); |
|
3636 return false; |
|
3637 } |
|
3638 |
|
3639 if (to.getEditorTemplate) |
|
3640 editorTemplate = to.getEditorTemplate(this.settings, this.editorId); |
|
3641 |
|
3642 var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0; |
|
3643 var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0; |
|
3644 var html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate['html']; |
|
3645 |
|
3646 html = tinyMCE.replaceVar(html, "editor_id", this.editorId); |
|
3647 this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm"; |
|
3648 |
|
3649 this.settings['old_width'] = this.settings['width']; |
|
3650 this.settings['old_height'] = this.settings['height']; |
|
3651 |
|
3652 // Set default width, height |
|
3653 if (this.settings['width'] == -1) |
|
3654 this.settings['width'] = replace_element.offsetWidth; |
|
3655 |
|
3656 if (this.settings['height'] == -1) |
|
3657 this.settings['height'] = replace_element.offsetHeight; |
|
3658 |
|
3659 // Try the style width |
|
3660 if (this.settings['width'] == 0) |
|
3661 this.settings['width'] = replace_element.style.width; |
|
3662 |
|
3663 // Try the style height |
|
3664 if (this.settings['height'] == 0) |
|
3665 this.settings['height'] = replace_element.style.height; |
|
3666 |
|
3667 // If no width/height then default to 320x240, better than nothing |
|
3668 if (this.settings['width'] == 0) |
|
3669 this.settings['width'] = 320; |
|
3670 |
|
3671 if (this.settings['height'] == 0) |
|
3672 this.settings['height'] = 240; |
|
3673 |
|
3674 this.settings['area_width'] = parseInt(this.settings['width']); |
|
3675 this.settings['area_height'] = parseInt(this.settings['height']); |
|
3676 this.settings['area_width'] += deltaWidth; |
|
3677 this.settings['area_height'] += deltaHeight; |
|
3678 |
|
3679 this.settings['width_style'] = "" + this.settings['width']; |
|
3680 this.settings['height_style'] = "" + this.settings['height']; |
|
3681 |
|
3682 // Special % handling |
|
3683 if (("" + this.settings['width']).indexOf('%') != -1) |
|
3684 this.settings['area_width'] = "100%"; |
|
3685 else |
|
3686 this.settings['width_style'] += 'px'; |
|
3687 |
|
3688 if (("" + this.settings['height']).indexOf('%') != -1) |
|
3689 this.settings['area_height'] = "100%"; |
|
3690 else |
|
3691 this.settings['height_style'] += 'px'; |
|
3692 |
|
3693 if (("" + replace_element.style.width).indexOf('%') != -1) { |
|
3694 this.settings['width'] = replace_element.style.width; |
|
3695 this.settings['area_width'] = "100%"; |
|
3696 this.settings['width_style'] = "100%"; |
|
3697 } |
|
3698 |
|
3699 if (("" + replace_element.style.height).indexOf('%') != -1) { |
|
3700 this.settings['height'] = replace_element.style.height; |
|
3701 this.settings['area_height'] = "100%"; |
|
3702 this.settings['height_style'] = "100%"; |
|
3703 } |
|
3704 |
|
3705 html = tinyMCE.applyTemplate(html); |
|
3706 |
|
3707 this.settings['width'] = this.settings['old_width']; |
|
3708 this.settings['height'] = this.settings['old_height']; |
|
3709 |
|
3710 this.visualAid = this.settings['visual']; |
|
3711 this.formTargetElementId = form_element_name; |
|
3712 |
|
3713 // Get replace_element contents |
|
3714 if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT") |
|
3715 this.startContent = replace_element.value; |
|
3716 else |
|
3717 this.startContent = replace_element.innerHTML; |
|
3718 |
|
3719 // If not text area or input |
|
3720 if (replace_element.nodeName != "TEXTAREA" && replace_element.nodeName != "INPUT") { |
|
3721 this.oldTargetElement = replace_element; |
|
3722 |
|
3723 // Debug mode |
|
3724 if (tinyMCE.settings['debug']) { |
|
3725 hc = '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>'; |
|
3726 } else { |
|
3727 hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />'; |
|
3728 this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline'); |
|
3729 this.oldTargetElement.style.display = "none"; |
|
3730 } |
|
3731 |
|
3732 html += '</span>'; |
|
3733 |
|
3734 if (tinyMCE.isGecko) |
|
3735 html = hc + html; |
|
3736 else |
|
3737 html += hc; |
|
3738 |
|
3739 // Output HTML and set editable |
|
3740 if (tinyMCE.isGecko) { |
|
3741 var rng = replace_element.ownerDocument.createRange(); |
|
3742 rng.setStartBefore(replace_element); |
|
3743 |
|
3744 var fragment = rng.createContextualFragment(html); |
|
3745 tinyMCE.insertAfter(fragment, replace_element); |
|
3746 } else |
|
3747 replace_element.insertAdjacentHTML("beforeBegin", html); |
|
3748 } else { |
|
3749 html += '</span>'; |
|
3750 |
|
3751 // Just hide the textarea element |
|
3752 this.oldTargetElement = replace_element; |
|
3753 |
|
3754 if (!tinyMCE.settings['debug']) { |
|
3755 this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline'); |
|
3756 this.oldTargetElement.style.display = "none"; |
|
3757 } |
|
3758 |
|
3759 // Output HTML and set editable |
|
3760 if (tinyMCE.isGecko) { |
|
3761 var rng = replace_element.ownerDocument.createRange(); |
|
3762 rng.setStartBefore(replace_element); |
|
3763 |
|
3764 var fragment = rng.createContextualFragment(html); |
|
3765 tinyMCE.insertAfter(fragment, replace_element); |
|
3766 } else |
|
3767 replace_element.insertAdjacentHTML("beforeBegin", html); |
|
3768 } |
|
3769 |
|
3770 // Setup iframe |
|
3771 var dynamicIFrame = false; |
|
3772 var tElm = targetDoc.getElementById(this.editorId); |
|
3773 |
|
3774 if (!tinyMCE.isIE) { |
|
3775 // Node case is preserved in XML strict mode |
|
3776 if (tElm && (tElm.nodeName == "SPAN" || tElm.nodeName == "span")) { |
|
3777 tElm = tinyMCE._createIFrame(tElm, targetDoc); |
|
3778 dynamicIFrame = true; |
|
3779 } |
|
3780 |
|
3781 this.targetElement = tElm; |
|
3782 this.iframeElement = tElm; |
|
3783 this.contentDocument = tElm.contentDocument; |
|
3784 this.contentWindow = tElm.contentWindow; |
|
3785 |
|
3786 //this.getDoc().designMode = "on"; |
|
3787 } else { |
|
3788 if (tElm && tElm.nodeName == "SPAN") |
|
3789 tElm = tinyMCE._createIFrame(tElm, targetDoc, targetDoc.parentWindow); |
|
3790 else |
|
3791 tElm = targetDoc.frames[this.editorId]; |
|
3792 |
|
3793 this.targetElement = tElm; |
|
3794 this.iframeElement = targetDoc.getElementById(this.editorId); |
|
3795 |
|
3796 if (tinyMCE.isOpera) { |
|
3797 this.contentDocument = this.iframeElement.contentDocument; |
|
3798 this.contentWindow = this.iframeElement.contentWindow; |
|
3799 dynamicIFrame = true; |
|
3800 } else { |
|
3801 this.contentDocument = tElm.window.document; |
|
3802 this.contentWindow = tElm.window; |
|
3803 } |
|
3804 |
|
3805 this.getDoc().designMode = "on"; |
|
3806 } |
|
3807 |
|
3808 // Setup base HTML |
|
3809 var doc = this.contentDocument; |
|
3810 if (dynamicIFrame) { |
|
3811 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>'; |
|
3812 |
|
3813 try { |
|
3814 if (!this.isHidden()) |
|
3815 this.getDoc().designMode = "on"; |
|
3816 |
|
3817 doc.open(); |
|
3818 //alert('docwrite 3'); |
|
3819 doc.write(html); |
|
3820 doc.close(); |
|
3821 } catch (e) { |
|
3822 // Failed Mozilla 1.3 |
|
3823 this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm"; |
|
3824 } |
|
3825 } |
|
3826 |
|
3827 // This timeout is needed in MSIE 5.5 for some odd reason |
|
3828 // it seems that the document.frames isn't initialized yet? |
|
3829 if (tinyMCE.isIE) |
|
3830 window.setTimeout("tinyMCE.addEventHandlers(tinyMCE.instances[\"" + this.editorId + "\"]);", 1); |
|
3831 |
|
3832 // Setup element references |
|
3833 var parentElm = this.targetDoc.getElementById(this.editorId + '_parent'); |
|
3834 this.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling; |
|
3835 |
|
3836 tinyMCE.setupContent(this.editorId, true); |
|
3837 |
|
3838 return true; |
|
3839 }, |
|
3840 |
|
3841 setBaseHREF : function(u) { |
|
3842 var h, b, d, nl; |
|
3843 |
|
3844 d = this.getDoc(); |
|
3845 nl = d.getElementsByTagName("base"); |
|
3846 b = nl.length > 0 ? nl[0] : null; |
|
3847 |
|
3848 if (!b) { |
|
3849 nl = d.getElementsByTagName("head"); |
|
3850 h = nl.length > 0 ? nl[0] : null; |
|
3851 |
|
3852 b = d.createElement("base"); |
|
3853 b.setAttribute('href', u); |
|
3854 h.appendChild(b); |
|
3855 } else { |
|
3856 if (u == "" || u == null) |
|
3857 b.parentNode.removeChild(b); |
|
3858 else |
|
3859 b.setAttribute('href', u); |
|
3860 } |
|
3861 }, |
|
3862 |
|
3863 getHTML : function(r) { |
|
3864 var h, d = this.getDoc(), b = this.getBody(); |
|
3865 |
|
3866 if (r) |
|
3867 return b.innerHTML; |
|
3868 |
|
3869 h = tinyMCE._cleanupHTML(this, d, this.settings, b, false, true, false, true); |
|
3870 |
|
3871 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
3872 tinyMCE.convertSpansToFonts(d); |
|
3873 |
|
3874 return h; |
|
3875 }, |
|
3876 |
|
3877 setHTML : function(h) { |
|
3878 this.execCommand('mceSetContent', false, h); |
|
3879 this.repaint(); |
|
3880 }, |
|
3881 |
|
3882 getFocusElement : function() { |
|
3883 return this.selection.getFocusElement(); |
|
3884 }, |
|
3885 |
|
3886 getSel : function() { |
|
3887 return this.selection.getSel(); |
|
3888 }, |
|
3889 |
|
3890 getRng : function() { |
|
3891 return this.selection.getRng(); |
|
3892 }, |
|
3893 |
|
3894 triggerSave : function(skip_cleanup, skip_callback) { |
|
3895 var e, nl = [], i, s; |
|
3896 |
|
3897 this.switchSettings(); |
|
3898 s = tinyMCE.settings; |
|
3899 |
|
3900 // Force hidden tabs visible while serializing |
|
3901 if (tinyMCE.isRealIE) { |
|
3902 e = this.iframeElement; |
|
3903 |
|
3904 do { |
|
3905 if (e.style && e.style.display == 'none') { |
|
3906 e.style.display = 'block'; |
|
3907 nl[nl.length] = {elm : e, type : 'style'}; |
|
3908 } |
|
3909 |
|
3910 if (e.style && s.hidden_tab_class.length > 0 && e.className.indexOf(s.hidden_tab_class) != -1) { |
|
3911 e.className = s.display_tab_class; |
|
3912 nl[nl.length] = {elm : e, type : 'class'}; |
|
3913 } |
|
3914 } while ((e = e.parentNode) != null) |
|
3915 } |
|
3916 |
|
3917 tinyMCE.settings['preformatted'] = false; |
|
3918 |
|
3919 // Default to false |
|
3920 if (typeof(skip_cleanup) == "undefined") |
|
3921 skip_cleanup = false; |
|
3922 |
|
3923 // Default to false |
|
3924 if (typeof(skip_callback) == "undefined") |
|
3925 skip_callback = false; |
|
3926 |
|
3927 tinyMCE._setHTML(this.getDoc(), this.getBody().innerHTML); |
|
3928 |
|
3929 // Remove visual aids when cleanup is disabled |
|
3930 if (this.settings['cleanup'] == false) { |
|
3931 tinyMCE.handleVisualAid(this.getBody(), true, false, this); |
|
3932 tinyMCE._setEventsEnabled(this.getBody(), true); |
|
3933 } |
|
3934 |
|
3935 tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body); |
|
3936 var htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true); |
|
3937 htm = tinyMCE._customCleanup(this, "submit_content", htm); |
|
3938 |
|
3939 if (!skip_callback && tinyMCE.settings['save_callback'] != "") |
|
3940 var content = eval(tinyMCE.settings['save_callback'] + "(this.formTargetElementId,htm,this.getBody());"); |
|
3941 |
|
3942 // Use callback content if available |
|
3943 if ((typeof(content) != "undefined") && content != null) |
|
3944 htm = content; |
|
3945 |
|
3946 // Replace some weird entities (Bug: #1056343) |
|
3947 htm = tinyMCE.regexpReplace(htm, "(", "(", "gi"); |
|
3948 htm = tinyMCE.regexpReplace(htm, ")", ")", "gi"); |
|
3949 htm = tinyMCE.regexpReplace(htm, ";", ";", "gi"); |
|
3950 htm = tinyMCE.regexpReplace(htm, """, """, "gi"); |
|
3951 htm = tinyMCE.regexpReplace(htm, "^", "^", "gi"); |
|
3952 |
|
3953 if (this.formElement) |
|
3954 this.formElement.value = htm; |
|
3955 |
|
3956 if (tinyMCE.isSafari && this.formElement) |
|
3957 this.formElement.innerText = htm; |
|
3958 |
|
3959 // Hide them again (tabs in MSIE) |
|
3960 for (i=0; i<nl.length; i++) { |
|
3961 if (nl[i].type == 'style') |
|
3962 nl[i].elm.style.display = 'none'; |
|
3963 else |
|
3964 nl[i].elm.className = s.hidden_tab_class; |
|
3965 } |
|
3966 } |
|
3967 |
|
3968 }; |
|
3969 |
|
3970 /* file:jscripts/tiny_mce/classes/TinyMCE_Cleanup.class.js */ |
|
3971 |
|
3972 TinyMCE_Engine.prototype.cleanupHTMLCode = function(s) { |
|
3973 s = s.replace(new RegExp('<p \\/>', 'gi'), '<p> </p>'); |
|
3974 s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p> </p>'); |
|
3975 |
|
3976 // Fix close BR elements |
|
3977 s = s.replace(new RegExp('<br>\\s*<\\/br>', 'gi'), '<br />'); |
|
3978 |
|
3979 // Open closed tags like <b/> to <b></b> |
|
3980 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>'); |
|
3981 |
|
3982 // Remove trailing space <b > to <b> |
|
3983 s = s.replace(new RegExp('\\s+></', 'gi'), '></'); |
|
3984 |
|
3985 // Close tags <img></img> to <img/> |
|
3986 s = s.replace(new RegExp('<(img|br|hr)([^>]*)><\\/(img|br|hr)>', 'gi'), '<$1$2 />'); |
|
3987 |
|
3988 // Weird MSIE bug, <p><hr /></p> breaks runtime? |
|
3989 if (tinyMCE.isIE) |
|
3990 s = s.replace(new RegExp('<p><hr \\/><\\/p>', 'gi'), "<hr>"); |
|
3991 |
|
3992 // Weird tags will make IE error #bug: 1538495 |
|
3993 if (tinyMCE.isIE) |
|
3994 s = s.replace(/<!(\s*)\/>/g, ''); |
|
3995 |
|
3996 // Convert relative anchors to absolute URLs ex: #something to file.htm#something |
|
3997 // Removed: Since local document anchors should never be forced absolute example edit.php?id=something |
|
3998 //if (tinyMCE.getParam('convert_urls')) |
|
3999 // s = s.replace(new RegExp('(href=\"{0,1})(\\s*#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#"); |
|
4000 |
|
4001 return s; |
|
4002 }; |
|
4003 |
|
4004 TinyMCE_Engine.prototype.parseStyle = function(str) { |
|
4005 var ar = new Array(); |
|
4006 |
|
4007 if (str == null) |
|
4008 return ar; |
|
4009 |
|
4010 var st = str.split(';'); |
|
4011 |
|
4012 tinyMCE.clearArray(ar); |
|
4013 |
|
4014 for (var i=0; i<st.length; i++) { |
|
4015 if (st[i] == '') |
|
4016 continue; |
|
4017 |
|
4018 var re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$'); |
|
4019 var pa = st[i].replace(re, '$1||$2').split('||'); |
|
4020 //tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2')); |
|
4021 if (pa.length == 2) |
|
4022 ar[pa[0].toLowerCase()] = pa[1]; |
|
4023 } |
|
4024 |
|
4025 return ar; |
|
4026 }; |
|
4027 |
|
4028 TinyMCE_Engine.prototype.compressStyle = function(ar, pr, sf, res) { |
|
4029 var box = new Array(); |
|
4030 |
|
4031 box[0] = ar[pr + '-top' + sf]; |
|
4032 box[1] = ar[pr + '-left' + sf]; |
|
4033 box[2] = ar[pr + '-right' + sf]; |
|
4034 box[3] = ar[pr + '-bottom' + sf]; |
|
4035 |
|
4036 for (var i=0; i<box.length; i++) { |
|
4037 if (box[i] == null) |
|
4038 return; |
|
4039 |
|
4040 for (var a=0; a<box.length; a++) { |
|
4041 if (box[a] != box[i]) |
|
4042 return; |
|
4043 } |
|
4044 } |
|
4045 |
|
4046 // They are all the same |
|
4047 ar[res] = box[0]; |
|
4048 ar[pr + '-top' + sf] = null; |
|
4049 ar[pr + '-left' + sf] = null; |
|
4050 ar[pr + '-right' + sf] = null; |
|
4051 ar[pr + '-bottom' + sf] = null; |
|
4052 }; |
|
4053 |
|
4054 TinyMCE_Engine.prototype.serializeStyle = function(ar) { |
|
4055 var str = ""; |
|
4056 |
|
4057 // Compress box |
|
4058 tinyMCE.compressStyle(ar, "border", "", "border"); |
|
4059 tinyMCE.compressStyle(ar, "border", "-width", "border-width"); |
|
4060 tinyMCE.compressStyle(ar, "border", "-color", "border-color"); |
|
4061 tinyMCE.compressStyle(ar, "border", "-style", "border-style"); |
|
4062 tinyMCE.compressStyle(ar, "padding", "", "padding"); |
|
4063 tinyMCE.compressStyle(ar, "margin", "", "margin"); |
|
4064 |
|
4065 for (var key in ar) { |
|
4066 var val = ar[key]; |
|
4067 |
|
4068 if (typeof(val) == 'function') |
|
4069 continue; |
|
4070 |
|
4071 if (key.indexOf('mso-') == 0) |
|
4072 continue; |
|
4073 |
|
4074 if (val != null && val != '') { |
|
4075 val = '' + val; // Force string |
|
4076 |
|
4077 // Fix style URL |
|
4078 val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')"); |
|
4079 |
|
4080 // Convert URL |
|
4081 if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) { |
|
4082 var m = new RegExp("url\\('(.*?)'\\)").exec(val); |
|
4083 |
|
4084 if (m.length > 1) |
|
4085 val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')"; |
|
4086 } |
|
4087 |
|
4088 // Force HEX colors |
|
4089 if (tinyMCE.getParam("force_hex_style_colors")) |
|
4090 val = tinyMCE.convertRGBToHex(val, true); |
|
4091 |
|
4092 val = val.replace(/\"/g, '\''); |
|
4093 |
|
4094 if (val != "url('')") |
|
4095 str += key.toLowerCase() + ": " + val + "; "; |
|
4096 } |
|
4097 } |
|
4098 |
|
4099 if (new RegExp('; $').test(str)) |
|
4100 str = str.substring(0, str.length - 2); |
|
4101 |
|
4102 return str; |
|
4103 }; |
|
4104 |
|
4105 TinyMCE_Engine.prototype.convertRGBToHex = function(s, k) { |
|
4106 if (s.toLowerCase().indexOf('rgb') != -1) { |
|
4107 var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi"); |
|
4108 var rgb = s.replace(re, "$1,$2,$3,$4,$5").split(','); |
|
4109 if (rgb.length == 5) { |
|
4110 r = parseInt(rgb[1]).toString(16); |
|
4111 g = parseInt(rgb[2]).toString(16); |
|
4112 b = parseInt(rgb[3]).toString(16); |
|
4113 |
|
4114 r = r.length == 1 ? '0' + r : r; |
|
4115 g = g.length == 1 ? '0' + g : g; |
|
4116 b = b.length == 1 ? '0' + b : b; |
|
4117 |
|
4118 s = "#" + r + g + b; |
|
4119 |
|
4120 if (k) |
|
4121 s = rgb[0] + s + rgb[4]; |
|
4122 } |
|
4123 } |
|
4124 |
|
4125 return s; |
|
4126 }; |
|
4127 |
|
4128 TinyMCE_Engine.prototype.convertHexToRGB = function(s) { |
|
4129 if (s.indexOf('#') != -1) { |
|
4130 s = s.replace(new RegExp('[^0-9A-F]', 'gi'), ''); |
|
4131 return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")"; |
|
4132 } |
|
4133 |
|
4134 return s; |
|
4135 }; |
|
4136 |
|
4137 TinyMCE_Engine.prototype.convertSpansToFonts = function(doc) { |
|
4138 var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(','); |
|
4139 |
|
4140 /*var h = doc.body.innerHTML; |
|
4141 h = h.replace(/<span/gi, '<font'); |
|
4142 h = h.replace(/<\/span/gi, '</font'); |
|
4143 tinyMCE.setInnerHTML(doc.body, h);*/ |
|
4144 |
|
4145 var s = tinyMCE.selectElements(doc, 'span,font'); |
|
4146 for (var i=0; i<s.length; i++) { |
|
4147 var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase(); |
|
4148 var fSize = 0; |
|
4149 |
|
4150 for (var x=0; x<sizes.length; x++) { |
|
4151 if (sizes[x] == size) { |
|
4152 fSize = x + 1; |
|
4153 break; |
|
4154 } |
|
4155 } |
|
4156 |
|
4157 if (fSize > 0) { |
|
4158 tinyMCE.setAttrib(s[i], 'size', fSize); |
|
4159 s[i].style.fontSize = ''; |
|
4160 } |
|
4161 |
|
4162 var fFace = s[i].style.fontFamily; |
|
4163 if (fFace != null && fFace != "") { |
|
4164 tinyMCE.setAttrib(s[i], 'face', fFace); |
|
4165 s[i].style.fontFamily = ''; |
|
4166 } |
|
4167 |
|
4168 var fColor = s[i].style.color; |
|
4169 if (fColor != null && fColor != "") { |
|
4170 tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor)); |
|
4171 s[i].style.color = ''; |
|
4172 } |
|
4173 } |
|
4174 }; |
|
4175 |
|
4176 TinyMCE_Engine.prototype.convertFontsToSpans = function(doc) { |
|
4177 var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(','); |
|
4178 |
|
4179 /* var h = doc.body.innerHTML; |
|
4180 h = h.replace(/<font/gi, '<span'); |
|
4181 h = h.replace(/<\/font/gi, '</span'); |
|
4182 tinyMCE.setInnerHTML(doc.body, h);*/ |
|
4183 |
|
4184 var fsClasses = tinyMCE.getParam('font_size_classes'); |
|
4185 if (fsClasses != '') |
|
4186 fsClasses = fsClasses.replace(/\s+/, '').split(','); |
|
4187 else |
|
4188 fsClasses = null; |
|
4189 |
|
4190 var s = tinyMCE.selectElements(doc, 'span,font'); |
|
4191 for (var i=0; i<s.length; i++) { |
|
4192 var fSize, fFace, fColor; |
|
4193 |
|
4194 fSize = tinyMCE.getAttrib(s[i], 'size'); |
|
4195 fFace = tinyMCE.getAttrib(s[i], 'face'); |
|
4196 fColor = tinyMCE.getAttrib(s[i], 'color'); |
|
4197 |
|
4198 if (fSize != "") { |
|
4199 fSize = parseInt(fSize); |
|
4200 |
|
4201 if (fSize > 0 && fSize < 8) { |
|
4202 if (fsClasses != null) |
|
4203 tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]); |
|
4204 else |
|
4205 s[i].style.fontSize = sizes[fSize-1]; |
|
4206 } |
|
4207 |
|
4208 s[i].removeAttribute('size'); |
|
4209 } |
|
4210 |
|
4211 if (fFace != "") { |
|
4212 s[i].style.fontFamily = fFace; |
|
4213 s[i].removeAttribute('face'); |
|
4214 } |
|
4215 |
|
4216 if (fColor != "") { |
|
4217 s[i].style.color = fColor; |
|
4218 s[i].removeAttribute('color'); |
|
4219 } |
|
4220 } |
|
4221 }; |
|
4222 |
|
4223 TinyMCE_Engine.prototype.cleanupAnchors = function(doc) { |
|
4224 var i, cn, x, an = doc.getElementsByTagName("a"); |
|
4225 |
|
4226 // Loops backwards due to bug #1467987 |
|
4227 for (i=an.length-1; i>=0; i--) { |
|
4228 if (tinyMCE.getAttrib(an[i], "name") != "" && tinyMCE.getAttrib(an[i], "href") == "") { |
|
4229 cn = an[i].childNodes; |
|
4230 |
|
4231 for (x=cn.length-1; x>=0; x--) |
|
4232 tinyMCE.insertAfter(cn[x], an[i]); |
|
4233 } |
|
4234 } |
|
4235 }; |
|
4236 |
|
4237 TinyMCE_Engine.prototype.getContent = function(editor_id) { |
|
4238 if (typeof(editor_id) != "undefined") |
|
4239 tinyMCE.getInstanceById(editor_id).select(); |
|
4240 |
|
4241 if (tinyMCE.selectedInstance) |
|
4242 return tinyMCE.selectedInstance.getHTML(); |
|
4243 |
|
4244 return null; |
|
4245 }; |
|
4246 |
|
4247 TinyMCE_Engine.prototype._fixListElements = function(d) { |
|
4248 var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np; |
|
4249 |
|
4250 for (x=0; x<a.length; x++) { |
|
4251 nl = d.getElementsByTagName(a[x]); |
|
4252 |
|
4253 for (i=0; i<nl.length; i++) { |
|
4254 n = nl[i]; |
|
4255 p = n.parentNode; |
|
4256 |
|
4257 if (r.test(p.nodeName)) { |
|
4258 np = tinyMCE.prevNode(n, 'LI'); |
|
4259 |
|
4260 if (!np) { |
|
4261 np = d.createElement('li'); |
|
4262 np.innerHTML = ' '; |
|
4263 np.appendChild(n); |
|
4264 p.insertBefore(np, p.firstChild); |
|
4265 } else |
|
4266 np.appendChild(n); |
|
4267 } |
|
4268 } |
|
4269 } |
|
4270 }; |
|
4271 |
|
4272 TinyMCE_Engine.prototype._fixTables = function(d) { |
|
4273 var nl, i, n, p, np, x, t; |
|
4274 |
|
4275 nl = d.getElementsByTagName('table'); |
|
4276 for (i=0; i<nl.length; i++) { |
|
4277 n = nl[i]; |
|
4278 |
|
4279 if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) { |
|
4280 np = p.cloneNode(false); |
|
4281 np.removeAttribute('id'); |
|
4282 |
|
4283 t = n; |
|
4284 |
|
4285 while ((n = n.nextSibling)) |
|
4286 np.appendChild(n); |
|
4287 |
|
4288 tinyMCE.insertAfter(np, p); |
|
4289 tinyMCE.insertAfter(t, p); |
|
4290 } |
|
4291 } |
|
4292 }; |
|
4293 |
|
4294 TinyMCE_Engine.prototype._cleanupHTML = function(inst, doc, config, elm, visual, on_save, on_submit, inn) { |
|
4295 var h, d, t1, t2, t3, t4, t5, c, s, nb; |
|
4296 |
|
4297 if (!tinyMCE.getParam('cleanup')) |
|
4298 return elm.innerHTML; |
|
4299 |
|
4300 on_save = typeof(on_save) == 'undefined' ? false : on_save; |
|
4301 |
|
4302 c = inst.cleanup; |
|
4303 s = inst.settings; |
|
4304 d = c.settings.debug; |
|
4305 |
|
4306 if (d) |
|
4307 t1 = new Date().getTime(); |
|
4308 |
|
4309 if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
4310 tinyMCE.convertFontsToSpans(doc); |
|
4311 |
|
4312 if (tinyMCE.getParam("fix_list_elements")) |
|
4313 tinyMCE._fixListElements(doc); |
|
4314 |
|
4315 if (tinyMCE.getParam("fix_table_elements")) |
|
4316 tinyMCE._fixTables(doc); |
|
4317 |
|
4318 // Call custom cleanup code |
|
4319 tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body); |
|
4320 |
|
4321 if (d) |
|
4322 t2 = new Date().getTime(); |
|
4323 |
|
4324 c.settings.on_save = on_save; |
|
4325 //for (var i=0; i<100; i++) |
|
4326 |
|
4327 c.idCount = 0; |
|
4328 c.serializationId++; |
|
4329 c.serializedNodes = new Array(); |
|
4330 c.sourceIndex = -1; |
|
4331 |
|
4332 if (s.cleanup_serializer == "xml") |
|
4333 h = c.serializeNodeAsXML(elm, inn); |
|
4334 else |
|
4335 h = c.serializeNodeAsHTML(elm, inn); |
|
4336 |
|
4337 if (d) |
|
4338 t3 = new Date().getTime(); |
|
4339 |
|
4340 // Post processing |
|
4341 nb = tinyMCE.getParam('entity_encoding') == 'numeric' ? ' ' : ' '; |
|
4342 h = h.replace(/<\/?(body|head|html)[^>]*>/gi, ''); |
|
4343 h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), ''); |
|
4344 h = h.replace(/<p><hr \/><\/p>/g, '<hr />'); |
|
4345 h = h.replace(/<p>( | )<\/p><hr \/><p>( | )<\/p>/g, '<hr />'); |
|
4346 h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>' + nb + '</td>'); |
|
4347 h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>'); |
|
4348 h = h.replace(/<br \/>$/, ''); // Remove last BR for Gecko |
|
4349 h = h.replace(/<br \/><\/p>/g, '</p>'); // Remove last BR in P tags for Gecko |
|
4350 h = h.replace(/<p>\s*( | )\s*<br \/>\s*( | )\s*<\/p>/g, '<p>' + nb + '</p>'); |
|
4351 h = h.replace(/<p>\s*( | )\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>'); |
|
4352 h = h.replace(/<p>\s*<br \/>\s* \s*<\/p>/g, '<p>' + nb + '</p>'); |
|
4353 h = h.replace(new RegExp('<a>(.*?)<\\/a>', 'g'), '$1'); |
|
4354 h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>' + nb + '</p>'); |
|
4355 |
|
4356 // Clean body |
|
4357 if (/^\s*(<br \/>|<p> <\/p>|<p> <\/p>|<p><\/p>)\s*$/.test(h)) |
|
4358 h = ''; |
|
4359 |
|
4360 // If preformatted |
|
4361 if (s.preformatted) { |
|
4362 h = h.replace(/^<pre>/, ''); |
|
4363 h = h.replace(/<\/pre>$/, ''); |
|
4364 h = '<pre>' + h + '</pre>'; |
|
4365 } |
|
4366 |
|
4367 // Gecko specific processing |
|
4368 if (tinyMCE.isGecko) { |
|
4369 h = h.replace(/<o:p _moz-userdefined="" \/>/g, ''); |
|
4370 h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>' + nb + '</td>'); |
|
4371 } |
|
4372 |
|
4373 if (s.force_br_newlines) |
|
4374 h = h.replace(/<p>( | )<\/p>/g, '<br />'); |
|
4375 |
|
4376 // Call custom cleanup code |
|
4377 h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h); |
|
4378 |
|
4379 // Remove internal classes |
|
4380 if (on_save) { |
|
4381 h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), ''); |
|
4382 h = h.replace(new RegExp(' ?class=""', 'g'), ''); |
|
4383 } |
|
4384 |
|
4385 if (s.remove_linebreaks && !c.settings.indent) |
|
4386 h = h.replace(/\n|\r/g, ' '); |
|
4387 |
|
4388 if (d) |
|
4389 t4 = new Date().getTime(); |
|
4390 |
|
4391 if (on_save && c.settings.indent) |
|
4392 h = c.formatHTML(h); |
|
4393 |
|
4394 // If encoding (not recommended option) |
|
4395 if (on_submit && (s.encoding == "xml" || s.encoding == "html")) |
|
4396 h = c.xmlEncode(h); |
|
4397 |
|
4398 if (d) |
|
4399 t5 = new Date().getTime(); |
|
4400 |
|
4401 if (c.settings.debug) |
|
4402 tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + "."); |
|
4403 |
|
4404 return h; |
|
4405 }; |
|
4406 |
|
4407 function TinyMCE_Cleanup() { |
|
4408 this.isIE = (navigator.appName == "Microsoft Internet Explorer"); |
|
4409 this.rules = tinyMCE.clearArray(new Array()); |
|
4410 |
|
4411 // Default config |
|
4412 this.settings = { |
|
4413 indent_elements : 'head,table,tbody,thead,tfoot,form,tr,ul,ol,blockquote,object', |
|
4414 newline_before_elements : 'h1,h2,h3,h4,h5,h6,pre,address,div,ul,ol,li,meta,option,area,title,link,base,script,td', |
|
4415 newline_after_elements : 'br,hr,p,pre,address,div,ul,ol,meta,option,area,link,base,script', |
|
4416 newline_before_after_elements : 'html,head,body,table,thead,tbody,tfoot,tr,form,ul,ol,blockquote,p,object,param,hr,div', |
|
4417 indent_char : '\t', |
|
4418 indent_levels : 1, |
|
4419 entity_encoding : 'raw', |
|
4420 valid_elements : '*[*]', |
|
4421 entities : '', |
|
4422 url_converter : '', |
|
4423 invalid_elements : '', |
|
4424 verify_html : false |
|
4425 }; |
|
4426 |
|
4427 this.vElements = tinyMCE.clearArray(new Array()); |
|
4428 this.vElementsRe = ''; |
|
4429 this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|AREA)$/; |
|
4430 this.codeElementsRe = /^(SCRIPT|STYLE)$/; |
|
4431 this.serializationId = 0; |
|
4432 this.mceAttribs = { |
|
4433 href : 'mce_href', |
|
4434 src : 'mce_src', |
|
4435 type : 'mce_type' |
|
4436 }; |
|
4437 } |
|
4438 |
|
4439 TinyMCE_Cleanup.prototype = { |
|
4440 init : function(s) { |
|
4441 var n, a, i, ir, or, st; |
|
4442 |
|
4443 for (n in s) |
|
4444 this.settings[n] = s[n]; |
|
4445 |
|
4446 // Setup code formating |
|
4447 s = this.settings; |
|
4448 |
|
4449 // Setup regexps |
|
4450 this.inRe = this._arrayToRe(s.indent_elements.split(','), '', '^<(', ')[^>]*'); |
|
4451 this.ouRe = this._arrayToRe(s.indent_elements.split(','), '', '^<\\/(', ')[^>]*'); |
|
4452 this.nlBeforeRe = this._arrayToRe(s.newline_before_elements.split(','), 'gi', '<(', ')([^>]*)>'); |
|
4453 this.nlAfterRe = this._arrayToRe(s.newline_after_elements.split(','), 'gi', '<(', ')([^>]*)>'); |
|
4454 this.nlBeforeAfterRe = this._arrayToRe(s.newline_before_after_elements.split(','), 'gi', '<(\\/?)(', ')([^>]*)>'); |
|
4455 this.serializedNodes = []; |
|
4456 |
|
4457 if (s.invalid_elements != '') |
|
4458 this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$'); |
|
4459 else |
|
4460 this.iveRe = null; |
|
4461 |
|
4462 // Setup separator |
|
4463 st = ''; |
|
4464 for (i=0; i<s.indent_levels; i++) |
|
4465 st += s.indent_char; |
|
4466 |
|
4467 this.inStr = st; |
|
4468 |
|
4469 // If verify_html if false force *[*] |
|
4470 if (!s.verify_html) { |
|
4471 s.valid_elements = '*[*]'; |
|
4472 s.extended_valid_elements = ''; |
|
4473 } |
|
4474 |
|
4475 this.fillStr = s.entity_encoding == "named" ? " " : " "; |
|
4476 this.idCount = 0; |
|
4477 this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g'); |
|
4478 this.xmlEncodeAposRe = new RegExp('[\u007F-\uFFFF<>&"\']', 'g'); |
|
4479 }, |
|
4480 |
|
4481 addRuleStr : function(s) { |
|
4482 var r = this.parseRuleStr(s); |
|
4483 var n; |
|
4484 |
|
4485 for (n in r) { |
|
4486 if (r[n]) |
|
4487 this.rules[n] = r[n]; |
|
4488 } |
|
4489 |
|
4490 this.vElements = tinyMCE.clearArray(new Array()); |
|
4491 |
|
4492 for (n in this.rules) { |
|
4493 if (this.rules[n]) |
|
4494 this.vElements[this.vElements.length] = this.rules[n].tag; |
|
4495 } |
|
4496 |
|
4497 this.vElementsRe = this._arrayToRe(this.vElements, ''); |
|
4498 }, |
|
4499 |
|
4500 isValid : function(n) { |
|
4501 this._setupRules(); // Will initialize cleanup rules |
|
4502 |
|
4503 // Empty is true since it removes formatting |
|
4504 if (!n) |
|
4505 return true; |
|
4506 |
|
4507 // Clean the name up a bit |
|
4508 n = n.replace(/[^a-z0-9]+/gi, '').toUpperCase(); |
|
4509 |
|
4510 return !tinyMCE.getParam('cleanup') || this.vElementsRe.test(n); |
|
4511 }, |
|
4512 |
|
4513 addChildRemoveRuleStr : function(s) { |
|
4514 var x, y, p, i, t, tn, ta, cl, r; |
|
4515 |
|
4516 if (!s) |
|
4517 return; |
|
4518 |
|
4519 ta = s.split(','); |
|
4520 for (x=0; x<ta.length; x++) { |
|
4521 s = ta[x]; |
|
4522 |
|
4523 // Split tag/children |
|
4524 p = this.split(/\[|\]/, s); |
|
4525 if (p == null || p.length < 1) |
|
4526 t = s.toUpperCase(); |
|
4527 else |
|
4528 t = p[0].toUpperCase(); |
|
4529 |
|
4530 // Handle all tag names |
|
4531 tn = this.split('/', t); |
|
4532 for (y=0; y<tn.length; y++) { |
|
4533 r = "^("; |
|
4534 |
|
4535 // Build regex |
|
4536 cl = this.split(/\|/, p[1]); |
|
4537 for (i=0; i<cl.length; i++) { |
|
4538 if (cl[i] == '%istrict') |
|
4539 r += tinyMCE.inlineStrict; |
|
4540 else if (cl[i] == '%itrans') |
|
4541 r += tinyMCE.inlineTransitional; |
|
4542 else if (cl[i] == '%istrict_na') |
|
4543 r += tinyMCE.inlineStrict.substring(2); |
|
4544 else if (cl[i] == '%itrans_na') |
|
4545 r += tinyMCE.inlineTransitional.substring(2); |
|
4546 else if (cl[i] == '%btrans') |
|
4547 r += tinyMCE.blockElms; |
|
4548 else if (cl[i] == '%strict') |
|
4549 r += tinyMCE.blockStrict; |
|
4550 else |
|
4551 r += (cl[i].charAt(0) != '#' ? cl[i].toUpperCase() : cl[i]); |
|
4552 |
|
4553 r += (i != cl.length - 1 ? '|' : ''); |
|
4554 } |
|
4555 |
|
4556 r += ')$'; |
|
4557 //tinyMCE.debug(t + "=" + r); |
|
4558 if (this.childRules == null) |
|
4559 this.childRules = tinyMCE.clearArray(new Array()); |
|
4560 |
|
4561 this.childRules[tn[y]] = new RegExp(r); |
|
4562 |
|
4563 if (p.length > 1) |
|
4564 this.childRules[tn[y]].wrapTag = p[2]; |
|
4565 } |
|
4566 } |
|
4567 }, |
|
4568 |
|
4569 parseRuleStr : function(s) { |
|
4570 var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray(new Array()), dv; |
|
4571 |
|
4572 if (s == null || s.length == 0) |
|
4573 return or; |
|
4574 |
|
4575 ta = s.split(','); |
|
4576 for (x=0; x<ta.length; x++) { |
|
4577 s = ta[x]; |
|
4578 if (s.length == 0) |
|
4579 continue; |
|
4580 |
|
4581 // Split tag/attrs |
|
4582 p = this.split(/\[|\]/, s); |
|
4583 if (p == null || p.length < 1) |
|
4584 t = s.toUpperCase(); |
|
4585 else |
|
4586 t = p[0].toUpperCase(); |
|
4587 |
|
4588 // Handle all tag names |
|
4589 tn = this.split('/', t); |
|
4590 for (y=0; y<tn.length; y++) { |
|
4591 r = {}; |
|
4592 |
|
4593 r.tag = tn[y]; |
|
4594 r.forceAttribs = null; |
|
4595 r.defaultAttribs = null; |
|
4596 r.validAttribValues = null; |
|
4597 |
|
4598 // Handle prefixes |
|
4599 px = r.tag.charAt(0); |
|
4600 r.forceOpen = px == '+'; |
|
4601 r.removeEmpty = px == '-'; |
|
4602 r.fill = px == '#'; |
|
4603 r.tag = r.tag.replace(/\+|-|#/g, ''); |
|
4604 r.oTagName = tn[0].replace(/\+|-|#/g, '').toLowerCase(); |
|
4605 r.isWild = new RegExp('\\*|\\?|\\+', 'g').test(r.tag); |
|
4606 r.validRe = new RegExp(this._wildcardToRe('^' + r.tag + '$')); |
|
4607 |
|
4608 // Setup valid attributes |
|
4609 if (p.length > 1) { |
|
4610 r.vAttribsRe = '^('; |
|
4611 a = this.split(/\|/, p[1]); |
|
4612 |
|
4613 for (i=0; i<a.length; i++) { |
|
4614 t = a[i]; |
|
4615 |
|
4616 if (t.charAt(0) == '!') { |
|
4617 a[i] = t = t.substring(1); |
|
4618 |
|
4619 if (!r.reqAttribsRe) |
|
4620 r.reqAttribsRe = '\\s+(' + t; |
|
4621 else |
|
4622 r.reqAttribsRe += '|' + t; |
|
4623 } |
|
4624 |
|
4625 av = new RegExp('(=|:|<)(.*?)$').exec(t); |
|
4626 t = t.replace(new RegExp('(=|:|<).*?$'), ''); |
|
4627 if (av && av.length > 0) { |
|
4628 if (av[0].charAt(0) == ':') { |
|
4629 if (!r.forceAttribs) |
|
4630 r.forceAttribs = tinyMCE.clearArray(new Array()); |
|
4631 |
|
4632 r.forceAttribs[t.toLowerCase()] = av[0].substring(1); |
|
4633 } else if (av[0].charAt(0) == '=') { |
|
4634 if (!r.defaultAttribs) |
|
4635 r.defaultAttribs = tinyMCE.clearArray(new Array()); |
|
4636 |
|
4637 dv = av[0].substring(1); |
|
4638 |
|
4639 r.defaultAttribs[t.toLowerCase()] = dv == "" ? "mce_empty" : dv; |
|
4640 } else if (av[0].charAt(0) == '<') { |
|
4641 if (!r.validAttribValues) |
|
4642 r.validAttribValues = tinyMCE.clearArray(new Array()); |
|
4643 |
|
4644 r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), 'i'); |
|
4645 } |
|
4646 } |
|
4647 |
|
4648 r.vAttribsRe += '' + t.toLowerCase() + (i != a.length - 1 ? '|' : ''); |
|
4649 |
|
4650 a[i] = t.toLowerCase(); |
|
4651 } |
|
4652 |
|
4653 if (r.reqAttribsRe) |
|
4654 r.reqAttribsRe = new RegExp(r.reqAttribsRe + ')=\"', 'g'); |
|
4655 |
|
4656 r.vAttribsRe += ')$'; |
|
4657 r.vAttribsRe = this._wildcardToRe(r.vAttribsRe); |
|
4658 r.vAttribsReIsWild = new RegExp('\\*|\\?|\\+', 'g').test(r.vAttribsRe); |
|
4659 r.vAttribsRe = new RegExp(r.vAttribsRe); |
|
4660 r.vAttribs = a.reverse(); |
|
4661 |
|
4662 //tinyMCE.debug(r.tag, r.oTagName, r.vAttribsRe, r.vAttribsReWC); |
|
4663 } else { |
|
4664 r.vAttribsRe = ''; |
|
4665 r.vAttribs = tinyMCE.clearArray(new Array()); |
|
4666 r.vAttribsReIsWild = false; |
|
4667 } |
|
4668 |
|
4669 or[r.tag] = r; |
|
4670 } |
|
4671 } |
|
4672 |
|
4673 return or; |
|
4674 }, |
|
4675 |
|
4676 serializeNodeAsXML : function(n) { |
|
4677 var s, b; |
|
4678 |
|
4679 if (!this.xmlDoc) { |
|
4680 if (this.isIE) { |
|
4681 try {this.xmlDoc = new ActiveXObject('MSXML2.DOMDocument');} catch (e) {} |
|
4682 |
|
4683 if (!this.xmlDoc) |
|
4684 try {this.xmlDoc = new ActiveXObject('Microsoft.XmlDom');} catch (e) {} |
|
4685 } else |
|
4686 this.xmlDoc = document.implementation.createDocument('', '', null); |
|
4687 |
|
4688 if (!this.xmlDoc) |
|
4689 alert("Error XML Parser could not be found."); |
|
4690 } |
|
4691 |
|
4692 if (this.xmlDoc.firstChild) |
|
4693 this.xmlDoc.removeChild(this.xmlDoc.firstChild); |
|
4694 |
|
4695 b = this.xmlDoc.createElement("html"); |
|
4696 b = this.xmlDoc.appendChild(b); |
|
4697 |
|
4698 this._convertToXML(n, b); |
|
4699 |
|
4700 if (this.isIE) |
|
4701 return this.xmlDoc.xml; |
|
4702 else |
|
4703 return new XMLSerializer().serializeToString(this.xmlDoc); |
|
4704 }, |
|
4705 |
|
4706 _convertToXML : function(n, xn) { |
|
4707 var xd, el, i, l, cn, at, no, hc = false; |
|
4708 |
|
4709 if (tinyMCE.isRealIE && this._isDuplicate(n)) |
|
4710 return; |
|
4711 |
|
4712 xd = this.xmlDoc; |
|
4713 |
|
4714 switch (n.nodeType) { |
|
4715 case 1: // Element |
|
4716 hc = n.hasChildNodes(); |
|
4717 |
|
4718 el = xd.createElement(n.nodeName.toLowerCase()); |
|
4719 |
|
4720 at = n.attributes; |
|
4721 for (i=at.length-1; i>-1; i--) { |
|
4722 no = at[i]; |
|
4723 |
|
4724 if (no.specified && no.nodeValue) |
|
4725 el.setAttribute(no.nodeName.toLowerCase(), no.nodeValue); |
|
4726 } |
|
4727 |
|
4728 if (!hc && !this.closeElementsRe.test(n.nodeName)) |
|
4729 el.appendChild(xd.createTextNode("")); |
|
4730 |
|
4731 xn = xn.appendChild(el); |
|
4732 break; |
|
4733 |
|
4734 case 3: // Text |
|
4735 xn.appendChild(xd.createTextNode(n.nodeValue)); |
|
4736 return; |
|
4737 |
|
4738 case 8: // Comment |
|
4739 xn.appendChild(xd.createComment(n.nodeValue)); |
|
4740 return; |
|
4741 } |
|
4742 |
|
4743 if (hc) { |
|
4744 cn = n.childNodes; |
|
4745 |
|
4746 for (i=0, l=cn.length; i<l; i++) |
|
4747 this._convertToXML(cn[i], xn); |
|
4748 } |
|
4749 }, |
|
4750 |
|
4751 serializeNodeAsHTML : function(n, inn) { |
|
4752 var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn; |
|
4753 |
|
4754 this._setupRules(); // Will initialize cleanup rules |
|
4755 |
|
4756 if (tinyMCE.isRealIE && this._isDuplicate(n)) |
|
4757 return ''; |
|
4758 |
|
4759 // Skip non valid child elements |
|
4760 if (n.parentNode && this.childRules != null) { |
|
4761 cr = this.childRules[n.parentNode.nodeName]; |
|
4762 |
|
4763 if (typeof(cr) != "undefined" && !cr.test(n.nodeName)) { |
|
4764 st = true; |
|
4765 t = null; |
|
4766 } |
|
4767 } |
|
4768 |
|
4769 switch (n.nodeType) { |
|
4770 case 1: // Element |
|
4771 hc = n.hasChildNodes(); |
|
4772 |
|
4773 if (st) |
|
4774 break; |
|
4775 |
|
4776 // MSIE sometimes produces <//tag> |
|
4777 if ((tinyMCE.isRealIE) && n.nodeName.indexOf('/') != -1) |
|
4778 break; |
|
4779 |
|
4780 nn = n.nodeName; |
|
4781 |
|
4782 // Convert fonts to spans |
|
4783 if (this.settings.convert_fonts_to_spans) { |
|
4784 // On get content FONT -> SPAN |
|
4785 if (this.settings.on_save && nn == 'FONT') |
|
4786 nn = 'SPAN'; |
|
4787 |
|
4788 // On insert content SPAN -> FONT |
|
4789 if (!this.settings.on_save && nn == 'SPAN') |
|
4790 nn = 'FONT'; |
|
4791 } |
|
4792 |
|
4793 if (this.vElementsRe.test(nn) && (!this.iveRe || !this.iveRe.test(nn)) && !inn) { |
|
4794 va = true; |
|
4795 |
|
4796 r = this.rules[nn]; |
|
4797 if (!r) { |
|
4798 at = this.rules; |
|
4799 for (no in at) { |
|
4800 if (at[no] && at[no].validRe.test(nn)) { |
|
4801 r = at[no]; |
|
4802 break; |
|
4803 } |
|
4804 } |
|
4805 } |
|
4806 |
|
4807 en = r.isWild ? nn.toLowerCase() : r.oTagName; |
|
4808 f = r.fill; |
|
4809 |
|
4810 if (r.removeEmpty && !hc) |
|
4811 return ""; |
|
4812 |
|
4813 t = '<' + en; |
|
4814 |
|
4815 if (r.vAttribsReIsWild) { |
|
4816 // Serialize wildcard attributes |
|
4817 at = n.attributes; |
|
4818 for (i=at.length-1; i>-1; i--) { |
|
4819 no = at[i]; |
|
4820 if (no.specified && r.vAttribsRe.test(no.nodeName)) |
|
4821 t += this._serializeAttribute(n, r, no.nodeName); |
|
4822 } |
|
4823 } else { |
|
4824 // Serialize specific attributes |
|
4825 for (i=r.vAttribs.length-1; i>-1; i--) |
|
4826 t += this._serializeAttribute(n, r, r.vAttribs[i]); |
|
4827 } |
|
4828 |
|
4829 // Serialize mce_ atts |
|
4830 if (!this.settings.on_save) { |
|
4831 at = this.mceAttribs; |
|
4832 |
|
4833 for (no in at) { |
|
4834 if (at[no]) |
|
4835 t += this._serializeAttribute(n, r, at[no]); |
|
4836 } |
|
4837 } |
|
4838 |
|
4839 // Check for required attribs |
|
4840 if (r.reqAttribsRe && !t.match(r.reqAttribsRe)) |
|
4841 t = null; |
|
4842 |
|
4843 // Close these |
|
4844 if (t != null && this.closeElementsRe.test(nn)) |
|
4845 return t + ' />'; |
|
4846 |
|
4847 if (t != null) |
|
4848 h += t + '>'; |
|
4849 |
|
4850 if (this.isIE && this.codeElementsRe.test(nn)) |
|
4851 h += n.innerHTML; |
|
4852 } |
|
4853 break; |
|
4854 |
|
4855 case 3: // Text |
|
4856 if (st) |
|
4857 break; |
|
4858 |
|
4859 if (n.parentNode && this.codeElementsRe.test(n.parentNode.nodeName)) |
|
4860 return this.isIE ? '' : n.nodeValue; |
|
4861 |
|
4862 return this.xmlEncode(n.nodeValue); |
|
4863 |
|
4864 case 8: // Comment |
|
4865 if (st) |
|
4866 break; |
|
4867 |
|
4868 return "<!--" + this._trimComment(n.nodeValue) + "-->"; |
|
4869 } |
|
4870 |
|
4871 if (hc) { |
|
4872 cn = n.childNodes; |
|
4873 |
|
4874 for (i=0, l=cn.length; i<l; i++) |
|
4875 h += this.serializeNodeAsHTML(cn[i]); |
|
4876 } |
|
4877 |
|
4878 // Fill empty nodes |
|
4879 if (f && !hc) |
|
4880 h += this.fillStr; |
|
4881 |
|
4882 // End element |
|
4883 if (t != null && va) |
|
4884 h += '</' + en + '>'; |
|
4885 |
|
4886 return h; |
|
4887 }, |
|
4888 |
|
4889 _serializeAttribute : function(n, r, an) { |
|
4890 var av = '', t, os = this.settings.on_save; |
|
4891 |
|
4892 if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0)) |
|
4893 return ''; |
|
4894 |
|
4895 if (os && this.mceAttribs[an]) |
|
4896 av = this._getAttrib(n, this.mceAttribs[an]); |
|
4897 |
|
4898 if (av.length == 0) |
|
4899 av = this._getAttrib(n, an); |
|
4900 |
|
4901 if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) { |
|
4902 av = t; |
|
4903 |
|
4904 if (av == "mce_empty") |
|
4905 return " " + an + '=""'; |
|
4906 } |
|
4907 |
|
4908 if (r.forceAttribs && (t = r.forceAttribs[an])) |
|
4909 av = t; |
|
4910 |
|
4911 if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an)) |
|
4912 av = this._urlConverter(this, n, av); |
|
4913 |
|
4914 if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av)) |
|
4915 return ""; |
|
4916 |
|
4917 if (av.length != 0 && av == "{$uid}") |
|
4918 av = "uid_" + (this.idCount++); |
|
4919 |
|
4920 if (av.length != 0) { |
|
4921 if (an.indexOf('on') != 0) |
|
4922 av = this.xmlEncode(av, 1); |
|
4923 |
|
4924 return " " + an + "=" + '"' + av + '"'; |
|
4925 } |
|
4926 |
|
4927 return ""; |
|
4928 }, |
|
4929 |
|
4930 formatHTML : function(h) { |
|
4931 var s = this.settings, p = '', i = 0, li = 0, o = '', l; |
|
4932 |
|
4933 // Replace BR in pre elements to \n |
|
4934 h = h.replace(/<pre([^>]*)>(.*?)<\/pre>/gi, function (a, b, c) { |
|
4935 c = c.replace(/<br\s*\/>/gi, '\n'); |
|
4936 return '<pre' + b + '>' + c + '</pre>'; |
|
4937 }); |
|
4938 |
|
4939 h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :) |
|
4940 h = '\n' + h; |
|
4941 h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting |
|
4942 h = h.replace(this.nlBeforeRe, '\n<$1$2>'); |
|
4943 h = h.replace(this.nlAfterRe, '<$1$2>\n'); |
|
4944 h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n'); |
|
4945 h += '\n'; |
|
4946 |
|
4947 //tinyMCE.debug(h); |
|
4948 |
|
4949 while ((i = h.indexOf('\n', i + 1)) != -1) { |
|
4950 if ((l = h.substring(li + 1, i)).length != 0) { |
|
4951 if (this.ouRe.test(l) && p.length >= s.indent_levels) |
|
4952 p = p.substring(s.indent_levels); |
|
4953 |
|
4954 o += p + l + '\n'; |
|
4955 |
|
4956 if (this.inRe.test(l)) |
|
4957 p += this.inStr; |
|
4958 } |
|
4959 |
|
4960 li = i; |
|
4961 } |
|
4962 |
|
4963 //tinyMCE.debug(h); |
|
4964 |
|
4965 return o; |
|
4966 }, |
|
4967 |
|
4968 xmlEncode : function(s, skip_apos) { |
|
4969 var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe; |
|
4970 |
|
4971 this._setupEntities(); // Will intialize lookup table |
|
4972 |
|
4973 switch (this.settings.entity_encoding) { |
|
4974 case "raw": |
|
4975 return tinyMCE.xmlEncode(s, skip_apos); |
|
4976 |
|
4977 case "named": |
|
4978 return s.replace(re, function (c, b) { |
|
4979 b = cl.entities[c.charCodeAt(0)]; |
|
4980 |
|
4981 return b ? '&' + b + ';' : c; |
|
4982 }); |
|
4983 |
|
4984 case "numeric": |
|
4985 return s.replace(re, function (c, b) { |
|
4986 return b ? '&#' + c.charCodeAt(0) + ';' : c; |
|
4987 }); |
|
4988 } |
|
4989 |
|
4990 return s; |
|
4991 }, |
|
4992 |
|
4993 split : function(re, s) { |
|
4994 var c = s.split(re); |
|
4995 var i, l, o = new Array(); |
|
4996 |
|
4997 for (i=0, l=c.length; i<l; i++) { |
|
4998 if (c[i] != '') |
|
4999 o[i] = c[i]; |
|
5000 } |
|
5001 |
|
5002 return o; |
|
5003 }, |
|
5004 |
|
5005 _trimComment : function(s) { |
|
5006 // Remove mce_src, mce_href |
|
5007 s = s.replace(new RegExp('\\smce_src=\"[^\"]*\"', 'gi'), ""); |
|
5008 s = s.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), ""); |
|
5009 |
|
5010 return s; |
|
5011 }, |
|
5012 |
|
5013 _getAttrib : function(e, n, d) { |
|
5014 var v, ex, nn; |
|
5015 |
|
5016 if (typeof(d) == "undefined") |
|
5017 d = ""; |
|
5018 |
|
5019 if (!e || e.nodeType != 1) |
|
5020 return d; |
|
5021 |
|
5022 try { |
|
5023 v = e.getAttribute(n, 0); |
|
5024 } catch (ex) { |
|
5025 // IE 7 may cast exception on invalid attributes |
|
5026 v = e.getAttribute(n, 2); |
|
5027 } |
|
5028 |
|
5029 if (n == "class" && !v) |
|
5030 v = e.className; |
|
5031 |
|
5032 if (this.isIE) { |
|
5033 if (n == "http-equiv") |
|
5034 v = e.httpEquiv; |
|
5035 |
|
5036 nn = e.nodeName; |
|
5037 |
|
5038 // Skip the default values that IE returns |
|
5039 if (nn == "FORM" && n == "enctype" && v == "application/x-www-form-urlencoded") |
|
5040 v = ""; |
|
5041 |
|
5042 if (nn == "INPUT" && n == "size" && v == "20") |
|
5043 v = ""; |
|
5044 |
|
5045 if (nn == "INPUT" && n == "maxlength" && v == "2147483647") |
|
5046 v = ""; |
|
5047 } |
|
5048 |
|
5049 if (n == 'style' && v) { |
|
5050 if (!tinyMCE.isOpera) |
|
5051 v = e.style.cssText; |
|
5052 |
|
5053 v = tinyMCE.serializeStyle(tinyMCE.parseStyle(v)); |
|
5054 } |
|
5055 |
|
5056 if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v != "") |
|
5057 v = tinyMCE.cleanupEventStr(v); |
|
5058 |
|
5059 return (v && v != "") ? '' + v : d; |
|
5060 }, |
|
5061 |
|
5062 _urlConverter : function(c, n, v) { |
|
5063 if (!c.settings.on_save) |
|
5064 return tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, v); |
|
5065 else if (tinyMCE.getParam('convert_urls')) { |
|
5066 if (!this.urlConverter) |
|
5067 this.urlConverter = eval(tinyMCE.settings.urlconverter_callback); |
|
5068 |
|
5069 return this.urlConverter(v, n, true); |
|
5070 } |
|
5071 |
|
5072 return v; |
|
5073 }, |
|
5074 |
|
5075 _arrayToRe : function(a, op, be, af) { |
|
5076 var i, r; |
|
5077 |
|
5078 op = typeof(op) == "undefined" ? "gi" : op; |
|
5079 be = typeof(be) == "undefined" ? "^(" : be; |
|
5080 af = typeof(af) == "undefined" ? ")$" : af; |
|
5081 |
|
5082 r = be; |
|
5083 |
|
5084 for (i=0; i<a.length; i++) |
|
5085 r += this._wildcardToRe(a[i]) + (i != a.length-1 ? "|" : ""); |
|
5086 |
|
5087 r += af; |
|
5088 |
|
5089 return new RegExp(r, op); |
|
5090 }, |
|
5091 |
|
5092 _wildcardToRe : function(s) { |
|
5093 s = s.replace(/\?/g, '(\\S?)'); |
|
5094 s = s.replace(/\+/g, '(\\S+)'); |
|
5095 s = s.replace(/\*/g, '(\\S*)'); |
|
5096 |
|
5097 return s; |
|
5098 }, |
|
5099 |
|
5100 _setupEntities : function() { |
|
5101 var n, a, i, s = this.settings; |
|
5102 |
|
5103 // Setup entities |
|
5104 if (!this.entitiesDone) { |
|
5105 if (s.entity_encoding == "named") { |
|
5106 n = tinyMCE.clearArray(new Array()); |
|
5107 a = this.split(',', s.entities); |
|
5108 for (i=0; i<a.length; i+=2) |
|
5109 n[a[i]] = a[i+1]; |
|
5110 |
|
5111 this.entities = n; |
|
5112 } |
|
5113 |
|
5114 this.entitiesDone = true; |
|
5115 } |
|
5116 }, |
|
5117 |
|
5118 _setupRules : function() { |
|
5119 var s = this.settings; |
|
5120 |
|
5121 // Setup default rule |
|
5122 if (!this.rulesDone) { |
|
5123 this.addRuleStr(s.valid_elements); |
|
5124 this.addRuleStr(s.extended_valid_elements); |
|
5125 this.addChildRemoveRuleStr(s.valid_child_elements); |
|
5126 |
|
5127 this.rulesDone = true; |
|
5128 } |
|
5129 }, |
|
5130 |
|
5131 _isDuplicate : function(n) { |
|
5132 var i; |
|
5133 |
|
5134 if (!this.settings.fix_content_duplication) |
|
5135 return false; |
|
5136 |
|
5137 if (tinyMCE.isRealIE && n.nodeType == 1) { |
|
5138 // Mark elements |
|
5139 if (n.mce_serialized == this.serializationId) |
|
5140 return true; |
|
5141 |
|
5142 n.setAttribute('mce_serialized', this.serializationId); |
|
5143 } else { |
|
5144 // Search lookup table for text nodes and comments |
|
5145 for (i=0; i<this.serializedNodes.length; i++) { |
|
5146 if (this.serializedNodes[i] == n) |
|
5147 return true; |
|
5148 } |
|
5149 |
|
5150 this.serializedNodes[this.serializedNodes.length] = n; |
|
5151 } |
|
5152 |
|
5153 return false; |
|
5154 } |
|
5155 |
|
5156 }; |
|
5157 |
|
5158 /* file:jscripts/tiny_mce/classes/TinyMCE_DOMUtils.class.js */ |
|
5159 |
|
5160 TinyMCE_Engine.prototype.createTagHTML = function(tn, a, h) { |
|
5161 var o = '', f = tinyMCE.xmlEncode; |
|
5162 |
|
5163 o = '<' + tn; |
|
5164 |
|
5165 if (a) { |
|
5166 for (n in a) { |
|
5167 if (typeof(a[n]) != 'function' && a[n] != null) |
|
5168 o += ' ' + f(n) + '="' + f('' + a[n]) + '"'; |
|
5169 } |
|
5170 } |
|
5171 |
|
5172 o += !h ? ' />' : '>' + h + '</' + tn + '>'; |
|
5173 |
|
5174 return o; |
|
5175 }; |
|
5176 |
|
5177 TinyMCE_Engine.prototype.createTag = function(d, tn, a, h) { |
|
5178 var o = d.createElement(tn); |
|
5179 |
|
5180 if (a) { |
|
5181 for (n in a) { |
|
5182 if (typeof(a[n]) != 'function' && a[n] != null) |
|
5183 tinyMCE.setAttrib(o, n, a[n]); |
|
5184 } |
|
5185 } |
|
5186 |
|
5187 if (h) |
|
5188 o.innerHTML = h; |
|
5189 |
|
5190 return o; |
|
5191 }; |
|
5192 |
|
5193 TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) { |
|
5194 return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0]; |
|
5195 }; |
|
5196 |
|
5197 TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) { |
|
5198 var i, nl = n.getElementsByTagName(e), o = new Array(); |
|
5199 |
|
5200 for (i=0; i<nl.length; i++) { |
|
5201 if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1) |
|
5202 o[o.length] = nl[i]; |
|
5203 } |
|
5204 |
|
5205 return o; |
|
5206 }; |
|
5207 |
|
5208 TinyMCE_Engine.prototype.isBlockElement = function(n) { |
|
5209 return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName); |
|
5210 }; |
|
5211 |
|
5212 TinyMCE_Engine.prototype.getParentBlockElement = function(n, r) { |
|
5213 return this.getParentNode(n, function(n) { |
|
5214 return tinyMCE.isBlockElement(n); |
|
5215 }, r); |
|
5216 |
|
5217 return null; |
|
5218 }; |
|
5219 |
|
5220 TinyMCE_Engine.prototype.insertAfter = function(n, r){ |
|
5221 if (r.nextSibling) |
|
5222 r.parentNode.insertBefore(n, r.nextSibling); |
|
5223 else |
|
5224 r.parentNode.appendChild(n); |
|
5225 }; |
|
5226 |
|
5227 TinyMCE_Engine.prototype.setInnerHTML = function(e, h) { |
|
5228 var i, nl, n; |
|
5229 |
|
5230 // Convert all strong/em to b/i in Gecko |
|
5231 if (tinyMCE.isGecko) { |
|
5232 h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>'); |
|
5233 h = h.replace(/<em([^>]*)>/gi, '<i$1>'); |
|
5234 h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>'); |
|
5235 h = h.replace(/<strong([^>]*)>/gi, '<b$1>'); |
|
5236 h = h.replace(/<\/strong>/gi, '</b>'); |
|
5237 h = h.replace(/<\/em>/gi, '</i>'); |
|
5238 } |
|
5239 |
|
5240 if (tinyMCE.isRealIE) { |
|
5241 // Since MSIE handles invalid HTML better that valid XHTML we |
|
5242 // need to make some things invalid. <hr /> gets converted to <hr>. |
|
5243 h = h.replace(/\s\/>/g, '>'); |
|
5244 |
|
5245 // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones |
|
5246 h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true"> </p>'); // Keep empty paragraphs |
|
5247 h = h.replace(/<p([^>]*)>\s* \s*<\/p>/gi, '<p$1 mce_keep="true"> </p>'); // Keep empty paragraphs |
|
5248 h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true"> </p>'); // Keep empty paragraphs |
|
5249 |
|
5250 // Remove first comment |
|
5251 e.innerHTML = tinyMCE.uniqueTag + h; |
|
5252 e.firstChild.removeNode(true); |
|
5253 |
|
5254 // Remove weird auto generated empty paragraphs unless it's supposed to be there |
|
5255 nl = e.getElementsByTagName("p"); |
|
5256 for (i=nl.length-1; i>=0; i--) { |
|
5257 n = nl[i]; |
|
5258 |
|
5259 if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep) |
|
5260 n.parentNode.removeChild(n); |
|
5261 } |
|
5262 } else { |
|
5263 h = this.fixGeckoBaseHREFBug(1, e, h); |
|
5264 e.innerHTML = h; |
|
5265 this.fixGeckoBaseHREFBug(2, e, h); |
|
5266 } |
|
5267 }; |
|
5268 |
|
5269 TinyMCE_Engine.prototype.getOuterHTML = function(e) { |
|
5270 if (tinyMCE.isIE) |
|
5271 return e.outerHTML; |
|
5272 |
|
5273 var d = e.ownerDocument.createElement("body"); |
|
5274 d.appendChild(e.cloneNode(true)); |
|
5275 return d.innerHTML; |
|
5276 }; |
|
5277 |
|
5278 TinyMCE_Engine.prototype.setOuterHTML = function(e, h, d) { |
|
5279 var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t; |
|
5280 |
|
5281 if (tinyMCE.isIE && e.nodeType == 1) |
|
5282 e.outerHTML = h; |
|
5283 else { |
|
5284 t = d.createElement("body"); |
|
5285 t.innerHTML = h; |
|
5286 |
|
5287 for (i=0, nl=t.childNodes; i<nl.length; i++) |
|
5288 e.parentNode.insertBefore(nl[i].cloneNode(true), e); |
|
5289 |
|
5290 e.parentNode.removeChild(e); |
|
5291 } |
|
5292 }; |
|
5293 |
|
5294 TinyMCE_Engine.prototype._getElementById = function(id, d) { |
|
5295 var e, i, j, f; |
|
5296 |
|
5297 if (typeof(d) == "undefined") |
|
5298 d = document; |
|
5299 |
|
5300 e = d.getElementById(id); |
|
5301 if (!e) { |
|
5302 f = d.forms; |
|
5303 |
|
5304 for (i=0; i<f.length; i++) { |
|
5305 for (j=0; j<f[i].elements.length; j++) { |
|
5306 if (f[i].elements[j].name == id) { |
|
5307 e = f[i].elements[j]; |
|
5308 break; |
|
5309 } |
|
5310 } |
|
5311 } |
|
5312 } |
|
5313 |
|
5314 return e; |
|
5315 }; |
|
5316 |
|
5317 TinyMCE_Engine.prototype.getNodeTree = function(n, na, t, nn) { |
|
5318 return this.selectNodes(n, function(n) { |
|
5319 return (!t || n.nodeType == t) && (!nn || n.nodeName == nn); |
|
5320 }, na ? na : new Array()); |
|
5321 }; |
|
5322 |
|
5323 TinyMCE_Engine.prototype.getParentElement = function(n, na, f, r) { |
|
5324 var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v; |
|
5325 |
|
5326 // Compatiblity with old scripts where f param was a attribute string |
|
5327 if (f && typeof(f) == 'string') |
|
5328 return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) != '';}); |
|
5329 |
|
5330 return this.getParentNode(n, function(n) { |
|
5331 return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n)); |
|
5332 }, r); |
|
5333 }; |
|
5334 |
|
5335 TinyMCE_Engine.prototype.getParentNode = function(n, f, r) { |
|
5336 while (n) { |
|
5337 if (n == r) |
|
5338 return null; |
|
5339 |
|
5340 if (f(n)) |
|
5341 return n; |
|
5342 |
|
5343 n = n.parentNode; |
|
5344 } |
|
5345 |
|
5346 return null; |
|
5347 }; |
|
5348 |
|
5349 TinyMCE_Engine.prototype.getAttrib = function(elm, name, dv) { |
|
5350 var v; |
|
5351 |
|
5352 if (typeof(dv) == "undefined") |
|
5353 dv = ""; |
|
5354 |
|
5355 // Not a element |
|
5356 if (!elm || elm.nodeType != 1) |
|
5357 return dv; |
|
5358 |
|
5359 try { |
|
5360 v = elm.getAttribute(name, 0); |
|
5361 } catch (ex) { |
|
5362 // IE 7 may cast exception on invalid attributes |
|
5363 v = elm.getAttribute(name, 2); |
|
5364 } |
|
5365 |
|
5366 // Try className for class attrib |
|
5367 if (name == "class" && !v) |
|
5368 v = elm.className; |
|
5369 |
|
5370 // Workaround for a issue with Firefox 1.5rc2+ |
|
5371 if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "") |
|
5372 v = elm.src; |
|
5373 |
|
5374 // Workaround for a issue with Firefox 1.5rc2+ |
|
5375 if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "") |
|
5376 v = elm.href; |
|
5377 |
|
5378 if (name == "http-equiv" && tinyMCE.isIE) |
|
5379 v = elm.httpEquiv; |
|
5380 |
|
5381 if (name == "style" && !tinyMCE.isOpera) |
|
5382 v = elm.style.cssText; |
|
5383 |
|
5384 return (v && v != "") ? v : dv; |
|
5385 }; |
|
5386 |
|
5387 TinyMCE_Engine.prototype.setAttrib = function(el, name, va, fix) { |
|
5388 if (typeof(va) == "number" && va != null) |
|
5389 va = "" + va; |
|
5390 |
|
5391 if (fix) { |
|
5392 if (va == null) |
|
5393 va = ""; |
|
5394 |
|
5395 va = va.replace(/[^0-9%]/g, ''); |
|
5396 } |
|
5397 |
|
5398 if (name == "style") |
|
5399 el.style.cssText = va; |
|
5400 |
|
5401 if (name == "class") |
|
5402 el.className = va; |
|
5403 |
|
5404 if (va != null && va != "" && va != -1) |
|
5405 el.setAttribute(name, va); |
|
5406 else |
|
5407 el.removeAttribute(name); |
|
5408 }; |
|
5409 |
|
5410 TinyMCE_Engine.prototype.setStyleAttrib = function(e, n, v) { |
|
5411 e.style[n] = v; |
|
5412 |
|
5413 // Style attrib deleted in IE |
|
5414 if (tinyMCE.isIE && v == null || v == '') { |
|
5415 v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText)); |
|
5416 e.style.cssText = v; |
|
5417 e.setAttribute("style", v); |
|
5418 } |
|
5419 }; |
|
5420 |
|
5421 TinyMCE_Engine.prototype.switchClass = function(ei, c) { |
|
5422 var e; |
|
5423 |
|
5424 if (tinyMCE.switchClassCache[ei]) |
|
5425 e = tinyMCE.switchClassCache[ei]; |
|
5426 else |
|
5427 e = tinyMCE.switchClassCache[ei] = document.getElementById(ei); |
|
5428 |
|
5429 if (e) { |
|
5430 // Keep tile mode |
|
5431 if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0) |
|
5432 c = 'mceTiledButton ' + c; |
|
5433 |
|
5434 e.className = c; |
|
5435 } |
|
5436 }; |
|
5437 |
|
5438 TinyMCE_Engine.prototype.getAbsPosition = function(n, cn) { |
|
5439 var l = 0, t = 0; |
|
5440 |
|
5441 while (n && n != cn) { |
|
5442 l += n.offsetLeft; |
|
5443 t += n.offsetTop; |
|
5444 n = n.offsetParent; |
|
5445 } |
|
5446 |
|
5447 return {absLeft : l, absTop : t}; |
|
5448 }; |
|
5449 |
|
5450 TinyMCE_Engine.prototype.prevNode = function(e, n) { |
|
5451 var a = n.split(','), i; |
|
5452 |
|
5453 while ((e = e.previousSibling) != null) { |
|
5454 for (i=0; i<a.length; i++) { |
|
5455 if (e.nodeName == a[i]) |
|
5456 return e; |
|
5457 } |
|
5458 } |
|
5459 |
|
5460 return null; |
|
5461 }; |
|
5462 |
|
5463 TinyMCE_Engine.prototype.nextNode = function(e, n) { |
|
5464 var a = n.split(','), i; |
|
5465 |
|
5466 while ((e = e.nextSibling) != null) { |
|
5467 for (i=0; i<a.length; i++) { |
|
5468 if (e.nodeName == a[i]) |
|
5469 return e; |
|
5470 } |
|
5471 } |
|
5472 |
|
5473 return null; |
|
5474 }; |
|
5475 |
|
5476 TinyMCE_Engine.prototype.selectElements = function(n, na, f) { |
|
5477 var i, a = [], nl, x; |
|
5478 |
|
5479 for (x=0, na = na.split(','); x<na.length; x++) |
|
5480 for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++) |
|
5481 (!f || f(nl[i])) && a.push(nl[i]); |
|
5482 |
|
5483 return a; |
|
5484 }; |
|
5485 |
|
5486 TinyMCE_Engine.prototype.selectNodes = function(n, f, a) { |
|
5487 var i; |
|
5488 |
|
5489 if (!a) |
|
5490 a = new Array(); |
|
5491 |
|
5492 if (f(n)) |
|
5493 a[a.length] = n; |
|
5494 |
|
5495 if (n.hasChildNodes()) { |
|
5496 for (i=0; i<n.childNodes.length; i++) |
|
5497 tinyMCE.selectNodes(n.childNodes[i], f, a); |
|
5498 } |
|
5499 |
|
5500 return a; |
|
5501 }; |
|
5502 |
|
5503 TinyMCE_Engine.prototype.addCSSClass = function(e, c, b) { |
|
5504 var o = this.removeCSSClass(e, c); |
|
5505 return e.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c; |
|
5506 }; |
|
5507 |
|
5508 TinyMCE_Engine.prototype.removeCSSClass = function(e, c) { |
|
5509 c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' '); |
|
5510 return e.className = c != ' ' ? c : ''; |
|
5511 }; |
|
5512 |
|
5513 TinyMCE_Engine.prototype.hasCSSClass = function(n, c) { |
|
5514 return new RegExp('\\b' + c + '\\b', 'g').test(n.className); |
|
5515 }; |
|
5516 |
|
5517 TinyMCE_Engine.prototype.renameElement = function(e, n, d) { |
|
5518 var ne, i, ar; |
|
5519 |
|
5520 d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d; |
|
5521 |
|
5522 if (e) { |
|
5523 ne = d.createElement(n); |
|
5524 |
|
5525 ar = e.attributes; |
|
5526 for (i=ar.length-1; i>-1; i--) { |
|
5527 if (ar[i].specified && ar[i].nodeValue) |
|
5528 ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue); |
|
5529 } |
|
5530 |
|
5531 ar = e.childNodes; |
|
5532 for (i=0; i<ar.length; i++) |
|
5533 ne.appendChild(ar[i].cloneNode(true)); |
|
5534 |
|
5535 e.parentNode.replaceChild(ne, e); |
|
5536 } |
|
5537 }; |
|
5538 |
|
5539 TinyMCE_Engine.prototype.getViewPort = function(w) { |
|
5540 var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement; |
|
5541 |
|
5542 return { |
|
5543 left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft), |
|
5544 top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop), |
|
5545 width : w.innerWidth || (m ? de.clientWidth : b.clientWidth), |
|
5546 height : w.innerHeight || (m ? de.clientHeight : b.clientHeight) |
|
5547 }; |
|
5548 }; |
|
5549 |
|
5550 TinyMCE_Engine.prototype.getStyle = function(n, na, d) { |
|
5551 if (!n) |
|
5552 return false; |
|
5553 |
|
5554 // Gecko |
|
5555 if (tinyMCE.isGecko && n.ownerDocument.defaultView) { |
|
5556 try { |
|
5557 return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na); |
|
5558 } catch (n) { |
|
5559 // Old safari might fail |
|
5560 return null; |
|
5561 } |
|
5562 } |
|
5563 |
|
5564 // Camelcase it, if needed |
|
5565 na = na.replace(/-(\D)/g, function(a, b){ |
|
5566 return b.toUpperCase(); |
|
5567 }); |
|
5568 |
|
5569 // IE & Opera |
|
5570 if (n.currentStyle) |
|
5571 return n.currentStyle[na]; |
|
5572 |
|
5573 return false; |
|
5574 }; |
|
5575 |
|
5576 /* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */ |
|
5577 |
|
5578 TinyMCE_Engine.prototype.parseURL = function(url_str) { |
|
5579 var urlParts = new Array(); |
|
5580 |
|
5581 if (url_str) { |
|
5582 var pos, lastPos; |
|
5583 |
|
5584 // Parse protocol part |
|
5585 pos = url_str.indexOf('://'); |
|
5586 if (pos != -1) { |
|
5587 urlParts['protocol'] = url_str.substring(0, pos); |
|
5588 lastPos = pos + 3; |
|
5589 } |
|
5590 |
|
5591 // Find port or path start |
|
5592 for (var i=lastPos; i<url_str.length; i++) { |
|
5593 var chr = url_str.charAt(i); |
|
5594 |
|
5595 if (chr == ':') |
|
5596 break; |
|
5597 |
|
5598 if (chr == '/') |
|
5599 break; |
|
5600 } |
|
5601 pos = i; |
|
5602 |
|
5603 // Get host |
|
5604 urlParts['host'] = url_str.substring(lastPos, pos); |
|
5605 |
|
5606 // Get port |
|
5607 urlParts['port'] = ""; |
|
5608 lastPos = pos; |
|
5609 if (url_str.charAt(pos) == ':') { |
|
5610 pos = url_str.indexOf('/', lastPos); |
|
5611 urlParts['port'] = url_str.substring(lastPos+1, pos); |
|
5612 } |
|
5613 |
|
5614 // Get path |
|
5615 lastPos = pos; |
|
5616 pos = url_str.indexOf('?', lastPos); |
|
5617 |
|
5618 if (pos == -1) |
|
5619 pos = url_str.indexOf('#', lastPos); |
|
5620 |
|
5621 if (pos == -1) |
|
5622 pos = url_str.length; |
|
5623 |
|
5624 urlParts['path'] = url_str.substring(lastPos, pos); |
|
5625 |
|
5626 // Get query |
|
5627 lastPos = pos; |
|
5628 if (url_str.charAt(pos) == '?') { |
|
5629 pos = url_str.indexOf('#'); |
|
5630 pos = (pos == -1) ? url_str.length : pos; |
|
5631 urlParts['query'] = url_str.substring(lastPos+1, pos); |
|
5632 } |
|
5633 |
|
5634 // Get anchor |
|
5635 lastPos = pos; |
|
5636 if (url_str.charAt(pos) == '#') { |
|
5637 pos = url_str.length; |
|
5638 urlParts['anchor'] = url_str.substring(lastPos+1, pos); |
|
5639 } |
|
5640 } |
|
5641 |
|
5642 return urlParts; |
|
5643 }; |
|
5644 |
|
5645 TinyMCE_Engine.prototype.serializeURL = function(up) { |
|
5646 var o = ""; |
|
5647 |
|
5648 if (up['protocol']) |
|
5649 o += up['protocol'] + "://"; |
|
5650 |
|
5651 if (up['host']) |
|
5652 o += up['host']; |
|
5653 |
|
5654 if (up['port']) |
|
5655 o += ":" + up['port']; |
|
5656 |
|
5657 if (up['path']) |
|
5658 o += up['path']; |
|
5659 |
|
5660 if (up['query']) |
|
5661 o += "?" + up['query']; |
|
5662 |
|
5663 if (up['anchor']) |
|
5664 o += "#" + up['anchor']; |
|
5665 |
|
5666 return o; |
|
5667 }; |
|
5668 |
|
5669 TinyMCE_Engine.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) { |
|
5670 var baseURL = this.parseURL(base_url); |
|
5671 var targetURL = this.parseURL(url_to_relative); |
|
5672 var strTok1; |
|
5673 var strTok2; |
|
5674 var breakPoint = 0; |
|
5675 var outPath = ""; |
|
5676 var forceSlash = false; |
|
5677 |
|
5678 if (targetURL.path == "") |
|
5679 targetURL.path = "/"; |
|
5680 else |
|
5681 forceSlash = true; |
|
5682 |
|
5683 // Crop away last path part |
|
5684 base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/')); |
|
5685 strTok1 = base_url.split('/'); |
|
5686 strTok2 = targetURL.path.split('/'); |
|
5687 |
|
5688 if (strTok1.length >= strTok2.length) { |
|
5689 for (var i=0; i<strTok1.length; i++) { |
|
5690 if (i >= strTok2.length || strTok1[i] != strTok2[i]) { |
|
5691 breakPoint = i + 1; |
|
5692 break; |
|
5693 } |
|
5694 } |
|
5695 } |
|
5696 |
|
5697 if (strTok1.length < strTok2.length) { |
|
5698 for (var i=0; i<strTok2.length; i++) { |
|
5699 if (i >= strTok1.length || strTok1[i] != strTok2[i]) { |
|
5700 breakPoint = i + 1; |
|
5701 break; |
|
5702 } |
|
5703 } |
|
5704 } |
|
5705 |
|
5706 if (breakPoint == 1) |
|
5707 return targetURL.path; |
|
5708 |
|
5709 for (var i=0; i<(strTok1.length-(breakPoint-1)); i++) |
|
5710 outPath += "../"; |
|
5711 |
|
5712 for (var i=breakPoint-1; i<strTok2.length; i++) { |
|
5713 if (i != (breakPoint-1)) |
|
5714 outPath += "/" + strTok2[i]; |
|
5715 else |
|
5716 outPath += strTok2[i]; |
|
5717 } |
|
5718 |
|
5719 targetURL.protocol = null; |
|
5720 targetURL.host = null; |
|
5721 targetURL.port = null; |
|
5722 targetURL.path = outPath == "" && forceSlash ? "/" : outPath; |
|
5723 |
|
5724 // Remove document prefix from local anchors |
|
5725 var fileName = baseURL.path; |
|
5726 var pos; |
|
5727 |
|
5728 if ((pos = fileName.lastIndexOf('/')) != -1) |
|
5729 fileName = fileName.substring(pos + 1); |
|
5730 |
|
5731 // Is local anchor |
|
5732 if (fileName == targetURL.path && targetURL.anchor != "") |
|
5733 targetURL.path = ""; |
|
5734 |
|
5735 // If empty and not local anchor force filename or slash |
|
5736 if (targetURL.path == "" && !targetURL.anchor) |
|
5737 targetURL.path = fileName != "" ? fileName : "/"; |
|
5738 |
|
5739 return this.serializeURL(targetURL); |
|
5740 }; |
|
5741 |
|
5742 TinyMCE_Engine.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) { |
|
5743 var baseURL = this.parseURL(base_url), baseURLParts, relURLParts; |
|
5744 var relURL = this.parseURL(relative_url); |
|
5745 |
|
5746 if (relative_url == "" || relative_url.indexOf('://') != -1 || /^(mailto:|javascript:|#|\/)/.test(relative_url)) |
|
5747 return relative_url; |
|
5748 |
|
5749 // Split parts |
|
5750 baseURLParts = baseURL['path'].split('/'); |
|
5751 relURLParts = relURL['path'].split('/'); |
|
5752 |
|
5753 // Remove empty chunks |
|
5754 var newBaseURLParts = new Array(); |
|
5755 for (var i=baseURLParts.length-1; i>=0; i--) { |
|
5756 if (baseURLParts[i].length == 0) |
|
5757 continue; |
|
5758 |
|
5759 newBaseURLParts[newBaseURLParts.length] = baseURLParts[i]; |
|
5760 } |
|
5761 baseURLParts = newBaseURLParts.reverse(); |
|
5762 |
|
5763 // Merge relURLParts chunks |
|
5764 var newRelURLParts = new Array(); |
|
5765 var numBack = 0; |
|
5766 for (var i=relURLParts.length-1; i>=0; i--) { |
|
5767 if (relURLParts[i].length == 0 || relURLParts[i] == ".") |
|
5768 continue; |
|
5769 |
|
5770 if (relURLParts[i] == '..') { |
|
5771 numBack++; |
|
5772 continue; |
|
5773 } |
|
5774 |
|
5775 if (numBack > 0) { |
|
5776 numBack--; |
|
5777 continue; |
|
5778 } |
|
5779 |
|
5780 newRelURLParts[newRelURLParts.length] = relURLParts[i]; |
|
5781 } |
|
5782 |
|
5783 relURLParts = newRelURLParts.reverse(); |
|
5784 |
|
5785 // Remove end from absolute path |
|
5786 var len = baseURLParts.length-numBack; |
|
5787 var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/'); |
|
5788 var start = "", end = ""; |
|
5789 |
|
5790 // Build output URL |
|
5791 relURL.protocol = baseURL.protocol; |
|
5792 relURL.host = baseURL.host; |
|
5793 relURL.port = baseURL.port; |
|
5794 |
|
5795 // Re-add trailing slash if it's removed |
|
5796 if (relURL.path.charAt(relURL.path.length-1) == "/") |
|
5797 absPath += "/"; |
|
5798 |
|
5799 relURL.path = absPath; |
|
5800 |
|
5801 return this.serializeURL(relURL); |
|
5802 }; |
|
5803 |
|
5804 TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) { |
|
5805 var prot = document.location.protocol; |
|
5806 var host = document.location.hostname; |
|
5807 var port = document.location.port; |
|
5808 |
|
5809 // Pass through file protocol |
|
5810 if (prot == "file:") |
|
5811 return url; |
|
5812 |
|
5813 // Something is wrong, remove weirdness |
|
5814 url = tinyMCE.regexpReplace(url, '(http|https):///', '/'); |
|
5815 |
|
5816 // Mailto link or anchor (Pass through) |
|
5817 if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#") |
|
5818 return url; |
|
5819 |
|
5820 // Fix relative/Mozilla |
|
5821 if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/') |
|
5822 return tinyMCE.settings['base_href'] + url; |
|
5823 |
|
5824 // Handle relative URLs |
|
5825 if (on_save && tinyMCE.getParam('relative_urls')) { |
|
5826 var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url); |
|
5827 if (curl.charAt(0) == '/') |
|
5828 curl = tinyMCE.settings['document_base_prefix'] + curl; |
|
5829 |
|
5830 var urlParts = tinyMCE.parseURL(curl); |
|
5831 var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']); |
|
5832 |
|
5833 // Force relative |
|
5834 if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port'])) |
|
5835 return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl); |
|
5836 } |
|
5837 |
|
5838 // Handle absolute URLs |
|
5839 if (!tinyMCE.getParam('relative_urls')) { |
|
5840 var urlParts = tinyMCE.parseURL(url); |
|
5841 var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']); |
|
5842 |
|
5843 // Force absolute URLs from relative URLs |
|
5844 url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url); |
|
5845 |
|
5846 // If anchor and path is the same page |
|
5847 if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path']) |
|
5848 return "#" + urlParts['anchor']; |
|
5849 } |
|
5850 |
|
5851 // Remove current domain |
|
5852 if (tinyMCE.getParam('remove_script_host')) { |
|
5853 var start = "", portPart = ""; |
|
5854 |
|
5855 if (port != "") |
|
5856 portPart = ":" + port; |
|
5857 |
|
5858 start = prot + "//" + host + portPart + "/"; |
|
5859 |
|
5860 if (url.indexOf(start) == 0) |
|
5861 url = url.substring(start.length-1); |
|
5862 } |
|
5863 |
|
5864 return url; |
|
5865 }; |
|
5866 |
|
5867 TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) { |
|
5868 var i, elms, src, href, mhref, msrc; |
|
5869 |
|
5870 // Convert all image URL:s to absolute URL |
|
5871 elms = body.getElementsByTagName("img"); |
|
5872 for (i=0; i<elms.length; i++) { |
|
5873 src = tinyMCE.getAttrib(elms[i], 'src'); |
|
5874 |
|
5875 msrc = tinyMCE.getAttrib(elms[i], 'mce_src'); |
|
5876 if (msrc != "") |
|
5877 src = msrc; |
|
5878 |
|
5879 if (src != "") { |
|
5880 src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src); |
|
5881 elms[i].setAttribute("src", src); |
|
5882 } |
|
5883 } |
|
5884 |
|
5885 // Convert all link URL:s to absolute URL |
|
5886 elms = body.getElementsByTagName("a"); |
|
5887 for (i=0; i<elms.length; i++) { |
|
5888 href = tinyMCE.getAttrib(elms[i], 'href'); |
|
5889 |
|
5890 mhref = tinyMCE.getAttrib(elms[i], 'mce_href'); |
|
5891 if (mhref != "") |
|
5892 href = mhref; |
|
5893 |
|
5894 if (href && href != "") { |
|
5895 href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], href); |
|
5896 elms[i].setAttribute("href", href); |
|
5897 } |
|
5898 } |
|
5899 }; |
|
5900 |
|
5901 /* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */ |
|
5902 |
|
5903 TinyMCE_Engine.prototype.clearArray = function(a) { |
|
5904 var n; |
|
5905 |
|
5906 for (n in a) |
|
5907 a[n] = null; |
|
5908 |
|
5909 return a; |
|
5910 }; |
|
5911 |
|
5912 TinyMCE_Engine.prototype.explode = function(d, s) { |
|
5913 var ar = s.split(d), oar = new Array(), i; |
|
5914 |
|
5915 for (i = 0; i<ar.length; i++) { |
|
5916 if (ar[i] != "") |
|
5917 oar[oar.length] = ar[i]; |
|
5918 } |
|
5919 |
|
5920 return oar; |
|
5921 }; |
|
5922 |
|
5923 /* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */ |
|
5924 |
|
5925 TinyMCE_Engine.prototype._setEventsEnabled = function(node, state) { |
|
5926 var evs, x, y, elms, i, event; |
|
5927 var events = ['onfocus','onblur','onclick','ondblclick', |
|
5928 'onmousedown','onmouseup','onmouseover','onmousemove', |
|
5929 'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup']; |
|
5930 |
|
5931 evs = tinyMCE.settings['event_elements'].split(','); |
|
5932 for (y=0; y<evs.length; y++){ |
|
5933 elms = node.getElementsByTagName(evs[y]); |
|
5934 for (i=0; i<elms.length; i++) { |
|
5935 event = ""; |
|
5936 |
|
5937 for (x=0; x<events.length; x++) { |
|
5938 if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') { |
|
5939 event = tinyMCE.cleanupEventStr("" + event); |
|
5940 |
|
5941 if (!state) |
|
5942 event = "return true;" + event; |
|
5943 else |
|
5944 event = event.replace(/^return true;/gi, ''); |
|
5945 |
|
5946 elms[i].removeAttribute(events[x]); |
|
5947 elms[i].setAttribute(events[x], event); |
|
5948 } |
|
5949 } |
|
5950 } |
|
5951 } |
|
5952 }; |
|
5953 |
|
5954 TinyMCE_Engine.prototype._eventPatch = function(editor_id) { |
|
5955 var n, inst, win, e; |
|
5956 |
|
5957 // Remove odd, error |
|
5958 if (typeof(tinyMCE) == "undefined") |
|
5959 return true; |
|
5960 |
|
5961 try { |
|
5962 // Try selected instance first |
|
5963 if (tinyMCE.selectedInstance) { |
|
5964 win = tinyMCE.selectedInstance.getWin(); |
|
5965 |
|
5966 if (win && win.event) { |
|
5967 e = win.event; |
|
5968 |
|
5969 if (!e.target) |
|
5970 e.target = e.srcElement; |
|
5971 |
|
5972 TinyMCE_Engine.prototype.handleEvent(e); |
|
5973 return; |
|
5974 } |
|
5975 } |
|
5976 |
|
5977 // Search for it |
|
5978 for (n in tinyMCE.instances) { |
|
5979 inst = tinyMCE.instances[n]; |
|
5980 |
|
5981 if (!tinyMCE.isInstance(inst)) |
|
5982 continue; |
|
5983 |
|
5984 inst.select(); |
|
5985 win = inst.getWin(); |
|
5986 |
|
5987 if (win && win.event) { |
|
5988 e = win.event; |
|
5989 |
|
5990 if (!e.target) |
|
5991 e.target = e.srcElement; |
|
5992 |
|
5993 TinyMCE_Engine.prototype.handleEvent(e); |
|
5994 return; |
|
5995 } |
|
5996 } |
|
5997 } catch (ex) { |
|
5998 // Ignore error if iframe is pointing to external URL |
|
5999 } |
|
6000 }; |
|
6001 |
|
6002 TinyMCE_Engine.prototype.findEvent = function(e) { |
|
6003 var n, inst; |
|
6004 |
|
6005 if (e) |
|
6006 return e; |
|
6007 |
|
6008 for (n in tinyMCE.instances) { |
|
6009 inst = tinyMCE.instances[n]; |
|
6010 |
|
6011 if (tinyMCE.isInstance(inst) && inst.getWin().event) |
|
6012 return inst.getWin().event; |
|
6013 } |
|
6014 |
|
6015 return null; |
|
6016 }; |
|
6017 |
|
6018 TinyMCE_Engine.prototype.unloadHandler = function() { |
|
6019 tinyMCE.triggerSave(true, true); |
|
6020 }; |
|
6021 |
|
6022 TinyMCE_Engine.prototype.addEventHandlers = function(inst) { |
|
6023 this.setEventHandlers(inst, 1); |
|
6024 }; |
|
6025 |
|
6026 TinyMCE_Engine.prototype.setEventHandlers = function(inst, s) { |
|
6027 var doc = inst.getDoc(), ie, ot, i, f = s ? tinyMCE.addEvent : tinyMCE.removeEvent; |
|
6028 |
|
6029 ie = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'controlselect', 'dblclick']; |
|
6030 ot = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'focus', 'blur', 'dragdrop']; |
|
6031 |
|
6032 inst.switchSettings(); |
|
6033 |
|
6034 if (tinyMCE.isIE) { |
|
6035 for (i=0; i<ie.length; i++) |
|
6036 f(doc, ie[i], TinyMCE_Engine.prototype._eventPatch); |
|
6037 } else { |
|
6038 for (i=0; i<ot.length; i++) |
|
6039 f(doc, ot[i], tinyMCE.handleEvent); |
|
6040 |
|
6041 // Force designmode |
|
6042 try { |
|
6043 doc.designMode = "On"; |
|
6044 } catch (e) { |
|
6045 // Ignore |
|
6046 } |
|
6047 } |
|
6048 }; |
|
6049 |
|
6050 TinyMCE_Engine.prototype.onMouseMove = function() { |
|
6051 var inst, lh; |
|
6052 |
|
6053 // Fix for IE7 bug where it's not restoring hover on anchors correctly |
|
6054 if (tinyMCE.lastHover) { |
|
6055 lh = tinyMCE.lastHover; |
|
6056 |
|
6057 // Call out on menus and refresh class on normal buttons |
|
6058 if (lh.className.indexOf('mceMenu') != -1) |
|
6059 tinyMCE._menuButtonEvent('out', lh); |
|
6060 else |
|
6061 lh.className = lh.className; |
|
6062 |
|
6063 tinyMCE.lastHover = null; |
|
6064 } |
|
6065 |
|
6066 if (!tinyMCE.hasMouseMoved) { |
|
6067 inst = tinyMCE.selectedInstance; |
|
6068 |
|
6069 // Workaround for bug #1437457 (Odd MSIE bug) |
|
6070 if (inst.isFocused) { |
|
6071 inst.undoBookmark = inst.selection.getBookmark(); |
|
6072 tinyMCE.hasMouseMoved = true; |
|
6073 } |
|
6074 } |
|
6075 |
|
6076 // tinyMCE.cancelEvent(inst.getWin().event); |
|
6077 // return false; |
|
6078 }; |
|
6079 |
|
6080 TinyMCE_Engine.prototype.cancelEvent = function(e) { |
|
6081 if (!e) |
|
6082 return false; |
|
6083 |
|
6084 if (tinyMCE.isIE) { |
|
6085 e.returnValue = false; |
|
6086 e.cancelBubble = true; |
|
6087 } else { |
|
6088 e.preventDefault(); |
|
6089 e.stopPropagation && e.stopPropagation(); |
|
6090 } |
|
6091 |
|
6092 return false; |
|
6093 }; |
|
6094 |
|
6095 TinyMCE_Engine.prototype.addEvent = function(o, n, h) { |
|
6096 // Add cleanup for all non unload events |
|
6097 if (n != 'unload') { |
|
6098 function clean() { |
|
6099 var ex; |
|
6100 |
|
6101 try { |
|
6102 tinyMCE.removeEvent(o, n, h); |
|
6103 tinyMCE.removeEvent(window, 'unload', clean); |
|
6104 o = n = h = null; |
|
6105 } catch (ex) { |
|
6106 // IE may produce access denied exception on unload |
|
6107 } |
|
6108 } |
|
6109 |
|
6110 // Add memory cleaner |
|
6111 tinyMCE.addEvent(window, 'unload', clean); |
|
6112 } |
|
6113 |
|
6114 if (o.attachEvent) |
|
6115 o.attachEvent("on" + n, h); |
|
6116 else |
|
6117 o.addEventListener(n, h, false); |
|
6118 }; |
|
6119 |
|
6120 TinyMCE_Engine.prototype.removeEvent = function(o, n, h) { |
|
6121 if (o.detachEvent) |
|
6122 o.detachEvent("on" + n, h); |
|
6123 else |
|
6124 o.removeEventListener(n, h, false); |
|
6125 }; |
|
6126 |
|
6127 TinyMCE_Engine.prototype.addSelectAccessibility = function(e, s, w) { |
|
6128 // Add event handlers |
|
6129 if (!s._isAccessible) { |
|
6130 s.onkeydown = tinyMCE.accessibleEventHandler; |
|
6131 s.onblur = tinyMCE.accessibleEventHandler; |
|
6132 s._isAccessible = true; |
|
6133 s._win = w; |
|
6134 } |
|
6135 |
|
6136 return false; |
|
6137 }; |
|
6138 |
|
6139 TinyMCE_Engine.prototype.accessibleEventHandler = function(e) { |
|
6140 var win = this._win; |
|
6141 e = tinyMCE.isIE ? win.event : e; |
|
6142 var elm = tinyMCE.isIE ? e.srcElement : e.target; |
|
6143 |
|
6144 // Unpiggyback onchange on blur |
|
6145 if (e.type == "blur") { |
|
6146 if (elm.oldonchange) { |
|
6147 elm.onchange = elm.oldonchange; |
|
6148 elm.oldonchange = null; |
|
6149 } |
|
6150 |
|
6151 return true; |
|
6152 } |
|
6153 |
|
6154 // Piggyback onchange |
|
6155 if (elm.nodeName == "SELECT" && !elm.oldonchange) { |
|
6156 elm.oldonchange = elm.onchange; |
|
6157 elm.onchange = null; |
|
6158 } |
|
6159 |
|
6160 // Execute onchange and remove piggyback |
|
6161 if (e.keyCode == 13 || e.keyCode == 32) { |
|
6162 elm.onchange = elm.oldonchange; |
|
6163 elm.onchange(); |
|
6164 elm.oldonchange = null; |
|
6165 |
|
6166 tinyMCE.cancelEvent(e); |
|
6167 return false; |
|
6168 } |
|
6169 |
|
6170 return true; |
|
6171 }; |
|
6172 |
|
6173 TinyMCE_Engine.prototype._resetIframeHeight = function() { |
|
6174 var ife; |
|
6175 |
|
6176 if (tinyMCE.isRealIE) { |
|
6177 ife = tinyMCE.selectedInstance.iframeElement; |
|
6178 |
|
6179 /* if (ife._oldWidth) { |
|
6180 ife.style.width = ife._oldWidth; |
|
6181 ife.width = ife._oldWidth; |
|
6182 }*/ |
|
6183 |
|
6184 if (ife._oldHeight) { |
|
6185 ife.style.height = ife._oldHeight; |
|
6186 ife.height = ife._oldHeight; |
|
6187 } |
|
6188 } |
|
6189 }; |
|
6190 |
|
6191 /* file:jscripts/tiny_mce/classes/TinyMCE_Selection.class.js */ |
|
6192 |
|
6193 function TinyMCE_Selection(inst) { |
|
6194 this.instance = inst; |
|
6195 }; |
|
6196 |
|
6197 TinyMCE_Selection.prototype = { |
|
6198 getSelectedHTML : function() { |
|
6199 var inst = this.instance; |
|
6200 var e, r = this.getRng(), h; |
|
6201 |
|
6202 if (!r) |
|
6203 return null; |
|
6204 |
|
6205 e = document.createElement("body"); |
|
6206 |
|
6207 if (r.cloneContents) |
|
6208 e.appendChild(r.cloneContents()); |
|
6209 else if (typeof(r.item) != 'undefined' || typeof(r.htmlText) != 'undefined') |
|
6210 e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText; |
|
6211 else |
|
6212 e.innerHTML = r.toString(); // Failed, use text for now |
|
6213 |
|
6214 h = tinyMCE._cleanupHTML(inst, inst.contentDocument, inst.settings, e, e, false, true, false); |
|
6215 |
|
6216 // When editing always use fonts internaly |
|
6217 //if (tinyMCE.getParam("convert_fonts_to_spans")) |
|
6218 // tinyMCE.convertSpansToFonts(inst.getDoc()); |
|
6219 |
|
6220 return h; |
|
6221 }, |
|
6222 |
|
6223 getSelectedText : function() { |
|
6224 var inst = this.instance; |
|
6225 var d, r, s, t; |
|
6226 |
|
6227 if (tinyMCE.isIE) { |
|
6228 d = inst.getDoc(); |
|
6229 |
|
6230 if (d.selection.type == "Text") { |
|
6231 r = d.selection.createRange(); |
|
6232 t = r.text; |
|
6233 } else |
|
6234 t = ''; |
|
6235 } else { |
|
6236 s = this.getSel(); |
|
6237 |
|
6238 if (s && s.toString) |
|
6239 t = s.toString(); |
|
6240 else |
|
6241 t = ''; |
|
6242 } |
|
6243 |
|
6244 return t; |
|
6245 }, |
|
6246 |
|
6247 getBookmark : function(simple) { |
|
6248 var inst = this.instance; |
|
6249 var rng = this.getRng(); |
|
6250 var doc = inst.getDoc(), b = inst.getBody(); |
|
6251 var sp, le, s, e, nl, i, si, ei, w; |
|
6252 var trng, sx, sy, xx = -999999999, vp = inst.getViewPort(); |
|
6253 |
|
6254 sx = vp.left; |
|
6255 sy = vp.top; |
|
6256 |
|
6257 if (tinyMCE.isSafari || tinyMCE.isOpera || simple) |
|
6258 return {rng : rng, scrollX : sx, scrollY : sy}; |
|
6259 |
|
6260 if (tinyMCE.isIE) { |
|
6261 if (rng.item) { |
|
6262 e = rng.item(0); |
|
6263 |
|
6264 nl = b.getElementsByTagName(e.nodeName); |
|
6265 for (i=0; i<nl.length; i++) { |
|
6266 if (e == nl[i]) { |
|
6267 sp = i; |
|
6268 break; |
|
6269 } |
|
6270 } |
|
6271 |
|
6272 return { |
|
6273 tag : e.nodeName, |
|
6274 index : sp, |
|
6275 scrollX : sx, |
|
6276 scrollY : sy |
|
6277 }; |
|
6278 } else { |
|
6279 trng = doc.body.createTextRange(); |
|
6280 trng.moveToElementText(inst.getBody()); |
|
6281 trng.collapse(true); |
|
6282 bp = Math.abs(trng.move('character', xx)); |
|
6283 |
|
6284 trng = rng.duplicate(); |
|
6285 trng.collapse(true); |
|
6286 sp = Math.abs(trng.move('character', xx)); |
|
6287 |
|
6288 trng = rng.duplicate(); |
|
6289 trng.collapse(false); |
|
6290 le = Math.abs(trng.move('character', xx)) - sp; |
|
6291 |
|
6292 return { |
|
6293 start : sp - bp, |
|
6294 length : le, |
|
6295 scrollX : sx, |
|
6296 scrollY : sy |
|
6297 }; |
|
6298 } |
|
6299 } |
|
6300 |
|
6301 if (tinyMCE.isGecko) { |
|
6302 s = this.getSel(); |
|
6303 e = this.getFocusElement(); |
|
6304 |
|
6305 if (!s) |
|
6306 return null; |
|
6307 |
|
6308 if (e && e.nodeName == 'IMG') { |
|
6309 /*nl = b.getElementsByTagName('IMG'); |
|
6310 for (i=0; i<nl.length; i++) { |
|
6311 if (e == nl[i]) { |
|
6312 sp = i; |
|
6313 break; |
|
6314 } |
|
6315 }*/ |
|
6316 |
|
6317 return { |
|
6318 start : -1, |
|
6319 end : -1, |
|
6320 index : sp, |
|
6321 scrollX : sx, |
|
6322 scrollY : sy |
|
6323 }; |
|
6324 } |
|
6325 |
|
6326 // Caret or selection |
|
6327 if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) { |
|
6328 e = this._getPosText(b, s.anchorNode, s.focusNode); |
|
6329 |
|
6330 if (!e) |
|
6331 return {scrollX : sx, scrollY : sy}; |
|
6332 |
|
6333 return { |
|
6334 start : e.start + s.anchorOffset, |
|
6335 end : e.end + s.focusOffset, |
|
6336 scrollX : sx, |
|
6337 scrollY : sy |
|
6338 }; |
|
6339 } else { |
|
6340 e = this._getPosText(b, rng.startContainer, rng.endContainer); |
|
6341 |
|
6342 if (!e) |
|
6343 return {scrollX : sx, scrollY : sy}; |
|
6344 |
|
6345 return { |
|
6346 start : e.start + rng.startOffset, |
|
6347 end : e.end + rng.endOffset, |
|
6348 scrollX : sx, |
|
6349 scrollY : sy |
|
6350 }; |
|
6351 } |
|
6352 } |
|
6353 |
|
6354 return null; |
|
6355 }, |
|
6356 |
|
6357 moveToBookmark : function(bookmark) { |
|
6358 var inst = this.instance; |
|
6359 var rng, nl, i, ex, b = inst.getBody(), sd; |
|
6360 var doc = inst.getDoc(); |
|
6361 var win = inst.getWin(); |
|
6362 var sel = this.getSel(); |
|
6363 |
|
6364 if (!bookmark) |
|
6365 return false; |
|
6366 |
|
6367 if (tinyMCE.isSafari) { |
|
6368 sel.setBaseAndExtent(bookmark.rng.startContainer, bookmark.rng.startOffset, bookmark.rng.endContainer, bookmark.rng.endOffset); |
|
6369 return true; |
|
6370 } |
|
6371 |
|
6372 if (tinyMCE.isRealIE) { |
|
6373 if (bookmark.rng) { |
|
6374 try { |
|
6375 bookmark.rng.select(); |
|
6376 } catch (ex) { |
|
6377 // Ignore |
|
6378 } |
|
6379 |
|
6380 return true; |
|
6381 } |
|
6382 |
|
6383 win.focus(); |
|
6384 |
|
6385 if (bookmark.tag) { |
|
6386 rng = b.createControlRange(); |
|
6387 |
|
6388 nl = b.getElementsByTagName(bookmark.tag); |
|
6389 |
|
6390 if (nl.length > bookmark.index) { |
|
6391 try { |
|
6392 rng.addElement(nl[bookmark.index]); |
|
6393 } catch (ex) { |
|
6394 // Might be thrown if the node no longer exists |
|
6395 } |
|
6396 } |
|
6397 } else { |
|
6398 // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs |
|
6399 try { |
|
6400 // Incorrect bookmark |
|
6401 if (bookmark.start < 0) |
|
6402 return true; |
|
6403 |
|
6404 rng = inst.getSel().createRange(); |
|
6405 rng.moveToElementText(inst.getBody()); |
|
6406 rng.collapse(true); |
|
6407 rng.moveStart('character', bookmark.start); |
|
6408 rng.moveEnd('character', bookmark.length); |
|
6409 } catch (ex) { |
|
6410 return true; |
|
6411 } |
|
6412 } |
|
6413 |
|
6414 rng.select(); |
|
6415 |
|
6416 win.scrollTo(bookmark.scrollX, bookmark.scrollY); |
|
6417 return true; |
|
6418 } |
|
6419 |
|
6420 if (tinyMCE.isGecko || tinyMCE.isOpera) { |
|
6421 if (!sel) |
|
6422 return false; |
|
6423 |
|
6424 if (bookmark.rng) { |
|
6425 sel.removeAllRanges(); |
|
6426 sel.addRange(bookmark.rng); |
|
6427 } |
|
6428 |
|
6429 if (bookmark.start != -1 && bookmark.end != -1) { |
|
6430 try { |
|
6431 sd = this._getTextPos(b, bookmark.start, bookmark.end); |
|
6432 rng = doc.createRange(); |
|
6433 rng.setStart(sd.startNode, sd.startOffset); |
|
6434 rng.setEnd(sd.endNode, sd.endOffset); |
|
6435 sel.removeAllRanges(); |
|
6436 sel.addRange(rng); |
|
6437 win.focus(); |
|
6438 } catch (ex) { |
|
6439 // Ignore |
|
6440 } |
|
6441 } |
|
6442 |
|
6443 /* |
|
6444 if (typeof(bookmark.index) != 'undefined') { |
|
6445 tinyMCE.selectElements(b, 'IMG', function (n) { |
|
6446 if (bookmark.index-- == 0) { |
|
6447 // Select image in Gecko here |
|
6448 } |
|
6449 |
|
6450 return false; |
|
6451 }); |
|
6452 } |
|
6453 */ |
|
6454 |
|
6455 win.scrollTo(bookmark.scrollX, bookmark.scrollY); |
|
6456 return true; |
|
6457 } |
|
6458 |
|
6459 return false; |
|
6460 }, |
|
6461 |
|
6462 _getPosText : function(r, sn, en) { |
|
6463 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; |
|
6464 |
|
6465 while ((n = w.nextNode()) != null) { |
|
6466 if (n == sn) |
|
6467 d.start = p; |
|
6468 |
|
6469 if (n == en) { |
|
6470 d.end = p; |
|
6471 return d; |
|
6472 } |
|
6473 |
|
6474 p += n.nodeValue ? n.nodeValue.length : 0; |
|
6475 } |
|
6476 |
|
6477 return null; |
|
6478 }, |
|
6479 |
|
6480 _getTextPos : function(r, sp, ep) { |
|
6481 var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; |
|
6482 |
|
6483 while ((n = w.nextNode()) != null) { |
|
6484 p += n.nodeValue ? n.nodeValue.length : 0; |
|
6485 |
|
6486 if (p >= sp && !d.startNode) { |
|
6487 d.startNode = n; |
|
6488 d.startOffset = sp - (p - n.nodeValue.length); |
|
6489 } |
|
6490 |
|
6491 if (p >= ep) { |
|
6492 d.endNode = n; |
|
6493 d.endOffset = ep - (p - n.nodeValue.length); |
|
6494 |
|
6495 return d; |
|
6496 } |
|
6497 } |
|
6498 |
|
6499 return null; |
|
6500 }, |
|
6501 |
|
6502 selectNode : function(node, collapse, select_text_node, to_start) { |
|
6503 var inst = this.instance, sel, rng, nodes; |
|
6504 |
|
6505 if (!node) |
|
6506 return; |
|
6507 |
|
6508 if (typeof(collapse) == "undefined") |
|
6509 collapse = true; |
|
6510 |
|
6511 if (typeof(select_text_node) == "undefined") |
|
6512 select_text_node = false; |
|
6513 |
|
6514 if (typeof(to_start) == "undefined") |
|
6515 to_start = true; |
|
6516 |
|
6517 if (inst.settings.auto_resize) |
|
6518 inst.resizeToContent(); |
|
6519 |
|
6520 if (tinyMCE.isRealIE) { |
|
6521 rng = inst.getDoc().body.createTextRange(); |
|
6522 |
|
6523 try { |
|
6524 rng.moveToElementText(node); |
|
6525 |
|
6526 if (collapse) |
|
6527 rng.collapse(to_start); |
|
6528 |
|
6529 rng.select(); |
|
6530 } catch (e) { |
|
6531 // Throws illigal agrument in MSIE some times |
|
6532 } |
|
6533 } else { |
|
6534 sel = this.getSel(); |
|
6535 |
|
6536 if (!sel) |
|
6537 return; |
|
6538 |
|
6539 if (tinyMCE.isSafari) { |
|
6540 sel.setBaseAndExtent(node, 0, node, node.innerText.length); |
|
6541 |
|
6542 if (collapse) { |
|
6543 if (to_start) |
|
6544 sel.collapseToStart(); |
|
6545 else |
|
6546 sel.collapseToEnd(); |
|
6547 } |
|
6548 |
|
6549 this.scrollToNode(node); |
|
6550 |
|
6551 return; |
|
6552 } |
|
6553 |
|
6554 rng = inst.getDoc().createRange(); |
|
6555 |
|
6556 if (select_text_node) { |
|
6557 // Find first textnode in tree |
|
6558 nodes = tinyMCE.getNodeTree(node, new Array(), 3); |
|
6559 if (nodes.length > 0) |
|
6560 rng.selectNodeContents(nodes[0]); |
|
6561 else |
|
6562 rng.selectNodeContents(node); |
|
6563 } else |
|
6564 rng.selectNode(node); |
|
6565 |
|
6566 if (collapse) { |
|
6567 // Special treatment of textnode collapse |
|
6568 if (!to_start && node.nodeType == 3) { |
|
6569 rng.setStart(node, node.nodeValue.length); |
|
6570 rng.setEnd(node, node.nodeValue.length); |
|
6571 } else |
|
6572 rng.collapse(to_start); |
|
6573 } |
|
6574 |
|
6575 sel.removeAllRanges(); |
|
6576 sel.addRange(rng); |
|
6577 } |
|
6578 |
|
6579 this.scrollToNode(node); |
|
6580 |
|
6581 // Set selected element |
|
6582 tinyMCE.selectedElement = null; |
|
6583 if (node.nodeType == 1) |
|
6584 tinyMCE.selectedElement = node; |
|
6585 }, |
|
6586 |
|
6587 scrollToNode : function(node) { |
|
6588 var inst = this.instance, w = inst.getWin(), vp = inst.getViewPort(), pos = tinyMCE.getAbsPosition(node), cvp, p, cwin; |
|
6589 |
|
6590 // Only scroll if out of visible area |
|
6591 if (pos.absLeft < vp.left || pos.absLeft > vp.left + vp.width || pos.absTop < vp.top || pos.absTop > vp.top + (vp.height-25)) |
|
6592 w.scrollTo(pos.absLeft, pos.absTop - vp.height + 25); |
|
6593 |
|
6594 // Scroll container window |
|
6595 if (inst.settings.auto_resize) { |
|
6596 cwin = inst.getContainerWin(); |
|
6597 cvp = tinyMCE.getViewPort(cwin); |
|
6598 p = this.getAbsPosition(node); |
|
6599 |
|
6600 if (p.absLeft < cvp.left || p.absLeft > cvp.left + cvp.width || p.absTop < cvp.top || p.absTop > cvp.top + cvp.height) |
|
6601 cwin.scrollTo(p.absLeft, p.absTop - cvp.height + 25); |
|
6602 } |
|
6603 }, |
|
6604 |
|
6605 getAbsPosition : function(n) { |
|
6606 var pos = tinyMCE.getAbsPosition(n), ipos = tinyMCE.getAbsPosition(this.instance.iframeElement); |
|
6607 |
|
6608 return { |
|
6609 absLeft : ipos.absLeft + pos.absLeft, |
|
6610 absTop : ipos.absTop + pos.absTop |
|
6611 }; |
|
6612 }, |
|
6613 |
|
6614 getSel : function() { |
|
6615 var inst = this.instance; |
|
6616 |
|
6617 if (tinyMCE.isRealIE) |
|
6618 return inst.getDoc().selection; |
|
6619 |
|
6620 return inst.contentWindow.getSelection(); |
|
6621 }, |
|
6622 |
|
6623 getRng : function() { |
|
6624 var s = this.getSel(); |
|
6625 |
|
6626 if (s == null) |
|
6627 return null; |
|
6628 |
|
6629 if (tinyMCE.isRealIE) |
|
6630 return s.createRange(); |
|
6631 |
|
6632 if (tinyMCE.isSafari && !s.getRangeAt) |
|
6633 return '' + window.getSelection(); |
|
6634 |
|
6635 if (s.rangeCount > 0) |
|
6636 return s.getRangeAt(0); |
|
6637 |
|
6638 return null; |
|
6639 }, |
|
6640 |
|
6641 isCollapsed : function() { |
|
6642 var r = this.getRng(); |
|
6643 |
|
6644 if (r.item) |
|
6645 return false; |
|
6646 |
|
6647 return r.boundingWidth == 0 || this.getSel().isCollapsed; |
|
6648 }, |
|
6649 |
|
6650 collapse : function(b) { |
|
6651 var r = this.getRng(), s = this.getSel(); |
|
6652 |
|
6653 if (r.select) { |
|
6654 r.collapse(b); |
|
6655 r.select(); |
|
6656 } else { |
|
6657 if (b) |
|
6658 s.collapseToStart(); |
|
6659 else |
|
6660 s.collapseToEnd(); |
|
6661 } |
|
6662 }, |
|
6663 |
|
6664 getFocusElement : function() { |
|
6665 var inst = this.instance, doc, rng, sel, elm; |
|
6666 |
|
6667 if (tinyMCE.isRealIE) { |
|
6668 doc = inst.getDoc(); |
|
6669 rng = doc.selection.createRange(); |
|
6670 |
|
6671 // if (rng.collapse) |
|
6672 // rng.collapse(true); |
|
6673 |
|
6674 elm = rng.item ? rng.item(0) : rng.parentElement(); |
|
6675 } else { |
|
6676 if (!tinyMCE.isSafari && inst.isHidden()) |
|
6677 return inst.getBody(); |
|
6678 |
|
6679 sel = this.getSel(); |
|
6680 rng = this.getRng(); |
|
6681 |
|
6682 if (!sel || !rng) |
|
6683 return null; |
|
6684 |
|
6685 elm = rng.commonAncestorContainer; |
|
6686 //elm = (sel && sel.anchorNode) ? sel.anchorNode : null; |
|
6687 |
|
6688 // Handle selection a image or other control like element such as anchors |
|
6689 if (!rng.collapsed) { |
|
6690 // Is selection small |
|
6691 if (rng.startContainer == rng.endContainer) { |
|
6692 if (rng.startOffset - rng.endOffset < 2) { |
|
6693 if (rng.startContainer.hasChildNodes()) |
|
6694 elm = rng.startContainer.childNodes[rng.startOffset]; |
|
6695 } |
|
6696 } |
|
6697 } |
|
6698 |
|
6699 // Get the element parent of the node |
|
6700 elm = tinyMCE.getParentElement(elm); |
|
6701 |
|
6702 //if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") |
|
6703 // elm = tinyMCE.selectedElement; |
|
6704 } |
|
6705 |
|
6706 return elm; |
|
6707 } |
|
6708 |
|
6709 }; |
|
6710 |
|
6711 /* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */ |
|
6712 |
|
6713 function TinyMCE_UndoRedo(inst) { |
|
6714 this.instance = inst; |
|
6715 this.undoLevels = new Array(); |
|
6716 this.undoIndex = 0; |
|
6717 this.typingUndoIndex = -1; |
|
6718 this.undoRedo = true; |
|
6719 }; |
|
6720 |
|
6721 TinyMCE_UndoRedo.prototype = { |
|
6722 add : function(l) { |
|
6723 var b, customUndoLevels, newHTML, inst = this.instance, i, ul, ur; |
|
6724 |
|
6725 if (l) { |
|
6726 this.undoLevels[this.undoLevels.length] = l; |
|
6727 return true; |
|
6728 } |
|
6729 |
|
6730 if (this.typingUndoIndex != -1) { |
|
6731 this.undoIndex = this.typingUndoIndex; |
|
6732 |
|
6733 if (tinyMCE.typingUndoIndex != -1) |
|
6734 tinyMCE.undoIndex = tinyMCE.typingUndoIndex; |
|
6735 } |
|
6736 |
|
6737 newHTML = tinyMCE.trim(inst.getBody().innerHTML); |
|
6738 if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) { |
|
6739 //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content); |
|
6740 |
|
6741 tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst); |
|
6742 |
|
6743 // Time to compress |
|
6744 customUndoLevels = tinyMCE.settings['custom_undo_redo_levels']; |
|
6745 if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) { |
|
6746 for (i=0; i<this.undoLevels.length-1; i++) |
|
6747 this.undoLevels[i] = this.undoLevels[i+1]; |
|
6748 |
|
6749 this.undoLevels.length--; |
|
6750 this.undoIndex--; |
|
6751 |
|
6752 // Todo: Implement global undo/redo logic here |
|
6753 } |
|
6754 |
|
6755 b = inst.undoBookmark; |
|
6756 |
|
6757 if (!b) |
|
6758 b = inst.selection.getBookmark(); |
|
6759 |
|
6760 this.undoIndex++; |
|
6761 this.undoLevels[this.undoIndex] = { |
|
6762 content : newHTML, |
|
6763 bookmark : b |
|
6764 }; |
|
6765 |
|
6766 // Remove all above from global undo/redo |
|
6767 ul = tinyMCE.undoLevels; |
|
6768 for (i=tinyMCE.undoIndex + 1; i<ul.length; i++) { |
|
6769 ur = ul[i].undoRedo; |
|
6770 |
|
6771 if (ur.undoIndex == ur.undoLevels.length -1) |
|
6772 ur.undoIndex--; |
|
6773 |
|
6774 ur.undoLevels.length--; |
|
6775 } |
|
6776 |
|
6777 // Add global undo level |
|
6778 tinyMCE.undoLevels[tinyMCE.undoIndex++] = inst; |
|
6779 tinyMCE.undoLevels.length = tinyMCE.undoIndex; |
|
6780 |
|
6781 this.undoLevels.length = this.undoIndex + 1; |
|
6782 |
|
6783 return true; |
|
6784 } |
|
6785 |
|
6786 return false; |
|
6787 }, |
|
6788 |
|
6789 undo : function() { |
|
6790 var inst = this.instance; |
|
6791 |
|
6792 // Do undo |
|
6793 if (this.undoIndex > 0) { |
|
6794 this.undoIndex--; |
|
6795 |
|
6796 tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); |
|
6797 inst.repaint(); |
|
6798 |
|
6799 if (inst.settings.custom_undo_redo_restore_selection) |
|
6800 inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); |
|
6801 } |
|
6802 }, |
|
6803 |
|
6804 redo : function() { |
|
6805 var inst = this.instance; |
|
6806 |
|
6807 tinyMCE.execCommand("mceEndTyping"); |
|
6808 |
|
6809 if (this.undoIndex < (this.undoLevels.length-1)) { |
|
6810 this.undoIndex++; |
|
6811 |
|
6812 tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); |
|
6813 inst.repaint(); |
|
6814 |
|
6815 if (inst.settings.custom_undo_redo_restore_selection) |
|
6816 inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); |
|
6817 } |
|
6818 |
|
6819 tinyMCE.triggerNodeChange(); |
|
6820 } |
|
6821 |
|
6822 }; |
|
6823 |
|
6824 /* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */ |
|
6825 |
|
6826 var TinyMCE_ForceParagraphs = { |
|
6827 _insertPara : function(inst, e) { |
|
6828 var doc = inst.getDoc(), sel = inst.getSel(), body = inst.getBody(), win = inst.contentWindow, rng = sel.getRangeAt(0); |
|
6829 var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock; |
|
6830 var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null; |
|
6831 var paraBefore, paraAfter, startChop, endChop, contents; |
|
6832 |
|
6833 function isEmpty(para) { |
|
6834 function isEmptyHTML(html) { |
|
6835 return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == ""; |
|
6836 } |
|
6837 |
|
6838 // Check for images |
|
6839 if (para.getElementsByTagName("img").length > 0) |
|
6840 return false; |
|
6841 |
|
6842 // Check for tables |
|
6843 if (para.getElementsByTagName("table").length > 0) |
|
6844 return false; |
|
6845 |
|
6846 // Check for HRs |
|
6847 if (para.getElementsByTagName("hr").length > 0) |
|
6848 return false; |
|
6849 |
|
6850 // Check all textnodes |
|
6851 var nodes = tinyMCE.getNodeTree(para, new Array(), 3); |
|
6852 for (var i=0; i<nodes.length; i++) { |
|
6853 if (!isEmptyHTML(nodes[i].nodeValue)) |
|
6854 return false; |
|
6855 } |
|
6856 |
|
6857 // No images, no tables, no hrs, no text content then it's empty |
|
6858 return true; |
|
6859 } |
|
6860 |
|
6861 // tinyMCE.debug(body.innerHTML); |
|
6862 |
|
6863 // debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString()); |
|
6864 |
|
6865 // Setup before range |
|
6866 rngBefore = doc.createRange(); |
|
6867 rngBefore.setStart(sel.anchorNode, sel.anchorOffset); |
|
6868 rngBefore.collapse(true); |
|
6869 |
|
6870 // Setup after range |
|
6871 rngAfter = doc.createRange(); |
|
6872 rngAfter.setStart(sel.focusNode, sel.focusOffset); |
|
6873 rngAfter.collapse(true); |
|
6874 |
|
6875 // Setup start/end points |
|
6876 direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0; |
|
6877 startNode = direct ? sel.anchorNode : sel.focusNode; |
|
6878 startOffset = direct ? sel.anchorOffset : sel.focusOffset; |
|
6879 endNode = direct ? sel.focusNode : sel.anchorNode; |
|
6880 endOffset = direct ? sel.focusOffset : sel.anchorOffset; |
|
6881 |
|
6882 startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode; |
|
6883 endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode; |
|
6884 |
|
6885 // Get block elements |
|
6886 startBlock = inst.getParentBlockElement(startNode); |
|
6887 endBlock = inst.getParentBlockElement(endNode); |
|
6888 |
|
6889 // If absolute force paragraph generation within |
|
6890 if (startBlock && new RegExp('absolute|relative|static', 'gi').test(startBlock.style.position)) |
|
6891 startBlock = null; |
|
6892 |
|
6893 if (endBlock && new RegExp('absolute|relative|static', 'gi').test(endBlock.style.position)) |
|
6894 endBlock = null; |
|
6895 |
|
6896 // Use current block name |
|
6897 if (startBlock != null) { |
|
6898 blockName = startBlock.nodeName; |
|
6899 |
|
6900 // Use P instead |
|
6901 if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat))) |
|
6902 blockName = "P"; |
|
6903 } |
|
6904 |
|
6905 // Within a list use normal behaviour |
|
6906 if (tinyMCE.getParentElement(startBlock, "OL,UL", null, body) != null) |
|
6907 return false; |
|
6908 |
|
6909 // Within a table create new paragraphs |
|
6910 if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE")) |
|
6911 startBlock = endBlock = null; |
|
6912 |
|
6913 // Setup new paragraphs |
|
6914 paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName); |
|
6915 paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName); |
|
6916 |
|
6917 // Is header, then force paragraph under |
|
6918 if (/^(H[1-6])$/.test(blockName)) |
|
6919 paraAfter = doc.createElement("p"); |
|
6920 |
|
6921 // Setup chop nodes |
|
6922 startChop = startNode; |
|
6923 endChop = endNode; |
|
6924 |
|
6925 // Get startChop node |
|
6926 node = startChop; |
|
6927 do { |
|
6928 if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node)) |
|
6929 break; |
|
6930 |
|
6931 startChop = node; |
|
6932 } while ((node = node.previousSibling ? node.previousSibling : node.parentNode)); |
|
6933 |
|
6934 // Get endChop node |
|
6935 node = endChop; |
|
6936 do { |
|
6937 if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node)) |
|
6938 break; |
|
6939 |
|
6940 endChop = node; |
|
6941 } while ((node = node.nextSibling ? node.nextSibling : node.parentNode)); |
|
6942 |
|
6943 // Fix when only a image is within the TD |
|
6944 if (startChop.nodeName == "TD") |
|
6945 startChop = startChop.firstChild; |
|
6946 |
|
6947 if (endChop.nodeName == "TD") |
|
6948 endChop = endChop.lastChild; |
|
6949 |
|
6950 // If not in a block element |
|
6951 if (startBlock == null) { |
|
6952 // Delete selection |
|
6953 rng.deleteContents(); |
|
6954 |
|
6955 if (!tinyMCE.isSafari) |
|
6956 sel.removeAllRanges(); |
|
6957 |
|
6958 if (startChop != rootElm && endChop != rootElm) { |
|
6959 // Insert paragraph before |
|
6960 rngBefore = rng.cloneRange(); |
|
6961 |
|
6962 if (startChop == body) |
|
6963 rngBefore.setStart(startChop, 0); |
|
6964 else |
|
6965 rngBefore.setStartBefore(startChop); |
|
6966 |
|
6967 paraBefore.appendChild(rngBefore.cloneContents()); |
|
6968 |
|
6969 // Insert paragraph after |
|
6970 if (endChop.parentNode.nodeName == blockName) |
|
6971 endChop = endChop.parentNode; |
|
6972 |
|
6973 // If not after image |
|
6974 //if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY") |
|
6975 rng.setEndAfter(endChop); |
|
6976 |
|
6977 if (endChop.nodeName != "#text" && endChop.nodeName != "BODY") |
|
6978 rngBefore.setEndAfter(endChop); |
|
6979 |
|
6980 contents = rng.cloneContents(); |
|
6981 if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY")) |
|
6982 paraAfter.innerHTML = contents.firstChild.innerHTML; |
|
6983 else |
|
6984 paraAfter.appendChild(contents); |
|
6985 |
|
6986 // Check if it's a empty paragraph |
|
6987 if (isEmpty(paraBefore)) |
|
6988 paraBefore.innerHTML = " "; |
|
6989 |
|
6990 // Check if it's a empty paragraph |
|
6991 if (isEmpty(paraAfter)) |
|
6992 paraAfter.innerHTML = " "; |
|
6993 |
|
6994 // Delete old contents |
|
6995 rng.deleteContents(); |
|
6996 rngAfter.deleteContents(); |
|
6997 rngBefore.deleteContents(); |
|
6998 |
|
6999 // Insert new paragraphs |
|
7000 if (tinyMCE.isOpera) { |
|
7001 paraBefore.normalize(); |
|
7002 rngBefore.insertNode(paraBefore); |
|
7003 paraAfter.normalize(); |
|
7004 rngBefore.insertNode(paraAfter); |
|
7005 } else { |
|
7006 paraAfter.normalize(); |
|
7007 rngBefore.insertNode(paraAfter); |
|
7008 paraBefore.normalize(); |
|
7009 rngBefore.insertNode(paraBefore); |
|
7010 } |
|
7011 |
|
7012 //tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML); |
|
7013 } else { |
|
7014 body.innerHTML = "<" + blockName + "> </" + blockName + "><" + blockName + "> </" + blockName + ">"; |
|
7015 paraAfter = body.childNodes[1]; |
|
7016 } |
|
7017 |
|
7018 inst.selection.moveToBookmark(b); |
|
7019 inst.selection.selectNode(paraAfter, true, true); |
|
7020 |
|
7021 return true; |
|
7022 } |
|
7023 |
|
7024 // Place first part within new paragraph |
|
7025 if (startChop.nodeName == blockName) |
|
7026 rngBefore.setStart(startChop, 0); |
|
7027 else |
|
7028 rngBefore.setStartBefore(startChop); |
|
7029 |
|
7030 rngBefore.setEnd(startNode, startOffset); |
|
7031 paraBefore.appendChild(rngBefore.cloneContents()); |
|
7032 |
|
7033 // Place secound part within new paragraph |
|
7034 rngAfter.setEndAfter(endChop); |
|
7035 rngAfter.setStart(endNode, endOffset); |
|
7036 contents = rngAfter.cloneContents(); |
|
7037 |
|
7038 if (contents.firstChild && contents.firstChild.nodeName == blockName) { |
|
7039 /* var nodes = contents.firstChild.childNodes; |
|
7040 for (var i=0; i<nodes.length; i++) { |
|
7041 //tinyMCE.debug(nodes[i].nodeName); |
|
7042 if (nodes[i].nodeName != "BODY") |
|
7043 paraAfter.appendChild(nodes[i]); |
|
7044 } |
|
7045 */ |
|
7046 paraAfter.innerHTML = contents.firstChild.innerHTML; |
|
7047 } else |
|
7048 paraAfter.appendChild(contents); |
|
7049 |
|
7050 // Check if it's a empty paragraph |
|
7051 if (isEmpty(paraBefore)) |
|
7052 paraBefore.innerHTML = " "; |
|
7053 |
|
7054 // Check if it's a empty paragraph |
|
7055 if (isEmpty(paraAfter)) |
|
7056 paraAfter.innerHTML = " "; |
|
7057 |
|
7058 // Create a range around everything |
|
7059 rng = doc.createRange(); |
|
7060 |
|
7061 if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) { |
|
7062 rng.setStartBefore(startChop.parentNode); |
|
7063 } else { |
|
7064 if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0) |
|
7065 rng.setStartBefore(rngBefore.startContainer); |
|
7066 else |
|
7067 rng.setStart(rngBefore.startContainer, rngBefore.startOffset); |
|
7068 } |
|
7069 |
|
7070 if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName) |
|
7071 rng.setEndAfter(endChop.parentNode); |
|
7072 else |
|
7073 rng.setEnd(rngAfter.endContainer, rngAfter.endOffset); |
|
7074 |
|
7075 // Delete all contents and insert new paragraphs |
|
7076 rng.deleteContents(); |
|
7077 |
|
7078 if (tinyMCE.isOpera) { |
|
7079 rng.insertNode(paraBefore); |
|
7080 rng.insertNode(paraAfter); |
|
7081 } else { |
|
7082 rng.insertNode(paraAfter); |
|
7083 rng.insertNode(paraBefore); |
|
7084 } |
|
7085 |
|
7086 //tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML); |
|
7087 |
|
7088 // Normalize |
|
7089 paraAfter.normalize(); |
|
7090 paraBefore.normalize(); |
|
7091 |
|
7092 inst.selection.moveToBookmark(b); |
|
7093 inst.selection.selectNode(paraAfter, true, true); |
|
7094 |
|
7095 return true; |
|
7096 }, |
|
7097 |
|
7098 _handleBackSpace : function(inst) { |
|
7099 var r = inst.getRng(), sn = r.startContainer, nv, s = false; |
|
7100 |
|
7101 // Added body check for bug #1527787 |
|
7102 if (sn && sn.nextSibling && sn.nextSibling.nodeName == "BR" && sn.parentNode.nodeName != "BODY") { |
|
7103 nv = sn.nodeValue; |
|
7104 |
|
7105 // Handle if a backspace is pressed after a space character #bug 1466054 removed since fix for #1527787 |
|
7106 /*if (nv != null && nv.length >= r.startOffset && nv.charAt(r.startOffset - 1) == ' ') |
|
7107 s = true;*/ |
|
7108 |
|
7109 // Only remove BRs if we are at the end of line #bug 1464152 |
|
7110 if (nv != null && r.startOffset == nv.length) |
|
7111 sn.nextSibling.parentNode.removeChild(sn.nextSibling); |
|
7112 } |
|
7113 |
|
7114 if (inst.settings.auto_resize) |
|
7115 inst.resizeToContent(); |
|
7116 |
|
7117 return s; |
|
7118 } |
|
7119 |
|
7120 }; |
|
7121 |
|
7122 /* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */ |
|
7123 |
|
7124 function TinyMCE_Layer(id, bm) { |
|
7125 this.id = id; |
|
7126 this.blockerElement = null; |
|
7127 this.events = false; |
|
7128 this.element = null; |
|
7129 this.blockMode = typeof(bm) != 'undefined' ? bm : true; |
|
7130 this.doc = document; |
|
7131 }; |
|
7132 |
|
7133 TinyMCE_Layer.prototype = { |
|
7134 moveRelativeTo : function(re, p) { |
|
7135 var rep = this.getAbsPosition(re); |
|
7136 var w = parseInt(re.offsetWidth); |
|
7137 var h = parseInt(re.offsetHeight); |
|
7138 var e = this.getElement(); |
|
7139 var ew = parseInt(e.offsetWidth); |
|
7140 var eh = parseInt(e.offsetHeight); |
|
7141 var x, y; |
|
7142 |
|
7143 switch (p) { |
|
7144 case "tl": |
|
7145 x = rep.absLeft; |
|
7146 y = rep.absTop; |
|
7147 break; |
|
7148 |
|
7149 case "tr": |
|
7150 x = rep.absLeft + w; |
|
7151 y = rep.absTop; |
|
7152 break; |
|
7153 |
|
7154 case "bl": |
|
7155 x = rep.absLeft; |
|
7156 y = rep.absTop + h; |
|
7157 break; |
|
7158 |
|
7159 case "br": |
|
7160 x = rep.absLeft + w; |
|
7161 y = rep.absTop + h; |
|
7162 break; |
|
7163 |
|
7164 case "cc": |
|
7165 x = rep.absLeft + (w / 2) - (ew / 2); |
|
7166 y = rep.absTop + (h / 2) - (eh / 2); |
|
7167 break; |
|
7168 } |
|
7169 |
|
7170 this.moveTo(x, y); |
|
7171 }, |
|
7172 |
|
7173 moveBy : function(x, y) { |
|
7174 var e = this.getElement(); |
|
7175 this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y); |
|
7176 }, |
|
7177 |
|
7178 moveTo : function(x, y) { |
|
7179 var e = this.getElement(); |
|
7180 |
|
7181 e.style.left = x + "px"; |
|
7182 e.style.top = y + "px"; |
|
7183 |
|
7184 this.updateBlocker(); |
|
7185 }, |
|
7186 |
|
7187 resizeBy : function(w, h) { |
|
7188 var e = this.getElement(); |
|
7189 this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h); |
|
7190 }, |
|
7191 |
|
7192 resizeTo : function(w, h) { |
|
7193 var e = this.getElement(); |
|
7194 |
|
7195 if (w != null) |
|
7196 e.style.width = w + "px"; |
|
7197 |
|
7198 if (h != null) |
|
7199 e.style.height = h + "px"; |
|
7200 |
|
7201 this.updateBlocker(); |
|
7202 }, |
|
7203 |
|
7204 show : function() { |
|
7205 var el = this.getElement(); |
|
7206 |
|
7207 if (el) { |
|
7208 el.style.display = 'block'; |
|
7209 this.updateBlocker(); |
|
7210 } |
|
7211 }, |
|
7212 |
|
7213 hide : function() { |
|
7214 var el = this.getElement(); |
|
7215 |
|
7216 if (el) { |
|
7217 el.style.display = 'none'; |
|
7218 this.updateBlocker(); |
|
7219 } |
|
7220 }, |
|
7221 |
|
7222 isVisible : function() { |
|
7223 return this.getElement().style.display == 'block'; |
|
7224 }, |
|
7225 |
|
7226 getElement : function() { |
|
7227 if (!this.element) |
|
7228 this.element = this.doc.getElementById(this.id); |
|
7229 |
|
7230 return this.element; |
|
7231 }, |
|
7232 |
|
7233 setBlockMode : function(s) { |
|
7234 this.blockMode = s; |
|
7235 }, |
|
7236 |
|
7237 updateBlocker : function() { |
|
7238 var e, b, x, y, w, h; |
|
7239 |
|
7240 b = this.getBlocker(); |
|
7241 if (b) { |
|
7242 if (this.blockMode) { |
|
7243 e = this.getElement(); |
|
7244 x = this.parseInt(e.style.left); |
|
7245 y = this.parseInt(e.style.top); |
|
7246 w = this.parseInt(e.offsetWidth); |
|
7247 h = this.parseInt(e.offsetHeight); |
|
7248 |
|
7249 b.style.left = x + 'px'; |
|
7250 b.style.top = y + 'px'; |
|
7251 b.style.width = w + 'px'; |
|
7252 b.style.height = h + 'px'; |
|
7253 b.style.display = e.style.display; |
|
7254 } else |
|
7255 b.style.display = 'none'; |
|
7256 } |
|
7257 }, |
|
7258 |
|
7259 getBlocker : function() { |
|
7260 var d, b; |
|
7261 |
|
7262 if (!this.blockerElement && this.blockMode) { |
|
7263 d = this.doc; |
|
7264 b = d.getElementById(this.id + "_blocker"); |
|
7265 |
|
7266 if (!b) { |
|
7267 b = d.createElement("iframe"); |
|
7268 |
|
7269 b.setAttribute('id', this.id + "_blocker"); |
|
7270 b.style.cssText = 'display: none; position: absolute; left: 0; top: 0'; |
|
7271 b.src = 'javascript:false;'; |
|
7272 b.frameBorder = '0'; |
|
7273 b.scrolling = 'no'; |
|
7274 |
|
7275 d.body.appendChild(b); |
|
7276 } |
|
7277 |
|
7278 this.blockerElement = b; |
|
7279 } |
|
7280 |
|
7281 return this.blockerElement; |
|
7282 }, |
|
7283 |
|
7284 getAbsPosition : function(n) { |
|
7285 var p = {absLeft : 0, absTop : 0}; |
|
7286 |
|
7287 while (n) { |
|
7288 p.absLeft += n.offsetLeft; |
|
7289 p.absTop += n.offsetTop; |
|
7290 n = n.offsetParent; |
|
7291 } |
|
7292 |
|
7293 return p; |
|
7294 }, |
|
7295 |
|
7296 create : function(n, c, p, h) { |
|
7297 var d = this.doc, e = d.createElement(n); |
|
7298 |
|
7299 e.setAttribute('id', this.id); |
|
7300 |
|
7301 if (c) |
|
7302 e.className = c; |
|
7303 |
|
7304 if (!p) |
|
7305 p = d.body; |
|
7306 |
|
7307 if (h) |
|
7308 e.innerHTML = h; |
|
7309 |
|
7310 p.appendChild(e); |
|
7311 |
|
7312 return this.element = e; |
|
7313 }, |
|
7314 |
|
7315 exists : function() { |
|
7316 return this.doc.getElementById(this.id) != null; |
|
7317 }, |
|
7318 |
|
7319 parseInt : function(s) { |
|
7320 if (s == null || s == '') |
|
7321 return 0; |
|
7322 |
|
7323 return parseInt(s); |
|
7324 }, |
|
7325 |
|
7326 remove : function() { |
|
7327 var e = this.getElement(), b = this.getBlocker(); |
|
7328 |
|
7329 if (e) |
|
7330 e.parentNode.removeChild(e); |
|
7331 |
|
7332 if (b) |
|
7333 b.parentNode.removeChild(b); |
|
7334 } |
|
7335 |
|
7336 }; |
|
7337 |
|
7338 /* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */ |
|
7339 |
|
7340 function TinyMCE_Menu() { |
|
7341 var id; |
|
7342 |
|
7343 if (typeof(tinyMCE.menuCounter) == "undefined") |
|
7344 tinyMCE.menuCounter = 0; |
|
7345 |
|
7346 id = "mc_menu_" + tinyMCE.menuCounter++; |
|
7347 |
|
7348 TinyMCE_Layer.call(this, id, true); |
|
7349 |
|
7350 this.id = id; |
|
7351 this.items = new Array(); |
|
7352 this.needsUpdate = true; |
|
7353 }; |
|
7354 |
|
7355 TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, { |
|
7356 init : function(s) { |
|
7357 var n; |
|
7358 |
|
7359 // Default params |
|
7360 this.settings = { |
|
7361 separator_class : 'mceMenuSeparator', |
|
7362 title_class : 'mceMenuTitle', |
|
7363 disabled_class : 'mceMenuDisabled', |
|
7364 menu_class : 'mceMenu', |
|
7365 drop_menu : true |
|
7366 }; |
|
7367 |
|
7368 for (n in s) |
|
7369 this.settings[n] = s[n]; |
|
7370 |
|
7371 this.create('div', this.settings.menu_class); |
|
7372 }, |
|
7373 |
|
7374 clear : function() { |
|
7375 this.items = new Array(); |
|
7376 }, |
|
7377 |
|
7378 addTitle : function(t) { |
|
7379 this.add({type : 'title', text : t}); |
|
7380 }, |
|
7381 |
|
7382 addDisabled : function(t) { |
|
7383 this.add({type : 'disabled', text : t}); |
|
7384 }, |
|
7385 |
|
7386 addSeparator : function() { |
|
7387 this.add({type : 'separator'}); |
|
7388 }, |
|
7389 |
|
7390 addItem : function(t, js) { |
|
7391 this.add({text : t, js : js}); |
|
7392 }, |
|
7393 |
|
7394 add : function(mi) { |
|
7395 this.items[this.items.length] = mi; |
|
7396 this.needsUpdate = true; |
|
7397 }, |
|
7398 |
|
7399 update : function() { |
|
7400 var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings; |
|
7401 |
|
7402 if (this.settings.drop_menu) |
|
7403 h += '<span class="mceMenuLine"></span>'; |
|
7404 |
|
7405 h += '<table border="0" cellpadding="0" cellspacing="0">'; |
|
7406 |
|
7407 for (i=0; i<m.length; i++) { |
|
7408 t = tinyMCE.xmlEncode(m[i].text); |
|
7409 c = m[i].class_name ? ' class="' + m[i].class_name + '"' : ''; |
|
7410 |
|
7411 switch (m[i].type) { |
|
7412 case 'separator': |
|
7413 h += '<tr class="' + s.separator_class + '"><td>'; |
|
7414 break; |
|
7415 |
|
7416 case 'title': |
|
7417 h += '<tr class="' + s.title_class + '"><td><span' + c +'>' + t + '</span>'; |
|
7418 break; |
|
7419 |
|
7420 case 'disabled': |
|
7421 h += '<tr class="' + s.disabled_class + '"><td><span' + c +'>' + t + '</span>'; |
|
7422 break; |
|
7423 |
|
7424 default: |
|
7425 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>'; |
|
7426 } |
|
7427 |
|
7428 h += '</td></tr>'; |
|
7429 } |
|
7430 |
|
7431 h += '</table>'; |
|
7432 |
|
7433 e.innerHTML = h; |
|
7434 |
|
7435 this.needsUpdate = false; |
|
7436 this.updateBlocker(); |
|
7437 }, |
|
7438 |
|
7439 show : function() { |
|
7440 var nl, i; |
|
7441 |
|
7442 if (tinyMCE.lastMenu == this) |
|
7443 return; |
|
7444 |
|
7445 if (this.needsUpdate) |
|
7446 this.update(); |
|
7447 |
|
7448 if (tinyMCE.lastMenu && tinyMCE.lastMenu != this) |
|
7449 tinyMCE.lastMenu.hide(); |
|
7450 |
|
7451 TinyMCE_Layer.prototype.show.call(this); |
|
7452 |
|
7453 if (!tinyMCE.isOpera) { |
|
7454 // Accessibility stuff |
|
7455 /* nl = this.getElement().getElementsByTagName("a"); |
|
7456 if (nl.length > 0) |
|
7457 nl[0].focus();*/ |
|
7458 } |
|
7459 |
|
7460 tinyMCE.lastMenu = this; |
|
7461 } |
|
7462 |
|
7463 }); |
|
7464 |
|
7465 /* file:jscripts/tiny_mce/classes/TinyMCE_Compatibility.class.js */ |
|
7466 |
|
7467 if (!Function.prototype.call) { |
|
7468 Function.prototype.call = function() { |
|
7469 var a = arguments, s = a[0], i, as = '', r, o; |
|
7470 |
|
7471 for (i=1; i<a.length; i++) |
|
7472 as += (i > 1 ? ',' : '') + 'a[' + i + ']'; |
|
7473 |
|
7474 o = s._fu; |
|
7475 s._fu = this; |
|
7476 r = eval('s._fu(' + as + ')'); |
|
7477 s._fu = o; |
|
7478 |
|
7479 return r; |
|
7480 }; |
|
7481 }; |
|
7482 |
|
7483 /* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */ |
|
7484 |
|
7485 TinyMCE_Engine.prototype.debug = function() { |
|
7486 var m = "", a, i, l = tinyMCE.log.length; |
|
7487 |
|
7488 for (i=0, a = this.debug.arguments; i<a.length; i++) { |
|
7489 m += a[i]; |
|
7490 |
|
7491 if (i<a.length-1) |
|
7492 m += ', '; |
|
7493 } |
|
7494 |
|
7495 if (l < 1000) |
|
7496 tinyMCE.log[l] = "[debug] " + m; |
|
7497 }; |
|
7498 |