1 var tinyMCEPopup={init:function(){var b=this,a,c;a=b.getWin();tinymce=a.tinymce;tinyMCE=a.tinyMCE;b.editor=tinymce.EditorManager.activeEditor;b.params=b.editor.windowManager.params;b.features=b.editor.windowManager.features;b.dom=tinymce.dom;b.listeners=[];b.onInit={add:function(e,d){b.listeners.push({func:e,scope:d})}};b.isWindow=false;b.id=b.features.id;b.editor.windowManager.onOpen.dispatch(b.editor.windowManager,window)},getWin:function(){return window},getWindowArg:function(c,b){var a=this.params[c];return tinymce.is(a)?a:b},getParam:function(b,a){return this.editor.getParam(b,a)},getLang:function(b,a){return this.editor.getLang(b,a)},execCommand:function(d,c,e,b){b=b||{};b.skip_focus=1;this.restoreSelection();return this.editor.execCommand(d,c,e,b)},resizeToInnerSize:function(){var a=this;setTimeout(function(){var b=a.dom.getViewPort(window);a.editor.windowManager.resizeBy(a.getWindowArg("mce_width")-b.w,a.getWindowArg("mce_height")-b.h,a.id||window)},0)},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark(1)},restoreSelection:function(){var a=tinyMCEPopup;if(!a.isWindow&&tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},requireLangPack:function(){var b=this,a=b.getWindowArg("plugin_url")||b.getWindowArg("theme_url");if(a&&b.editor.settings.language&&b.features.translate_i18n!==false){a+="/langs/"+b.editor.settings.language+"_dlg.js";if(!tinymce.ScriptLoader.isDone(a)){document.write('<script type="text/javascript" src="'+tinymce._addVer(a)+'"><\/script>');tinymce.ScriptLoader.markDone(a)}}},pickColor:function(b,a){this.execCommand("mceColorPicker",true,{color:document.getElementById(a).value,func:function(e){document.getElementById(a).value=e;try{document.getElementById(a).onchange()}catch(d){}}})},openBrowser:function(a,c,b){tinyMCEPopup.restoreSelection();this.editor.execCallback("file_browser_callback",a,document.getElementById(a).value,c,window)},confirm:function(b,a,c){this.editor.windowManager.confirm(b,a,c,window)},alert:function(b,a,c){this.editor.windowManager.alert(b,a,c,window)},close:function(){var a=this;function b(){a.editor.windowManager.close(window);a.editor=null}if(tinymce.isOpera){a.getWin().setTimeout(b,0)}else{b()}},_restoreSelection:function(){var a=window.event.srcElement;if(a.nodeName=="INPUT"&&(a.type=="submit"||a.type=="button")){tinyMCEPopup.restoreSelection()}},_onDOMLoaded:function(){var b=tinyMCEPopup,d=document.title,e,c,a;if(b.domLoaded){return}b.domLoaded=1;tinyMCEPopup.init();if(b.features.translate_i18n!==false){c=document.body.innerHTML;if(tinymce.isIE){c=c.replace(/ (value|title|alt)=([^"][^\s>]+)/gi,' $1="$2"')}document.dir=b.editor.getParam("directionality","");if((a=b.editor.translate(c))&&a!=c){document.body.innerHTML=a}if((a=b.editor.translate(d))&&a!=d){document.title=d=a}}document.body.style.display="";if(tinymce.isIE){document.attachEvent("onmouseup",tinyMCEPopup._restoreSelection);b.dom.add(b.dom.select("head")[0],"base",{target:"_self"})}b.restoreSelection();if(!b.isWindow){b.editor.windowManager.setTitle(window,d)}else{window.focus()}if(!tinymce.isIE&&!b.isWindow){tinymce.dom.Event._add(document,"focus",function(){b.editor.windowManager.focus(b.id)})}tinymce.each(b.dom.select("select"),function(f){f.onkeydown=tinyMCEPopup._accessHandler});tinymce.each(b.listeners,function(f){f.func.call(f.scope,b.editor)});if(b.getWindowArg("mce_auto_focus",true)){window.focus();tinymce.each(document.forms,function(g){tinymce.each(g.elements,function(f){if(b.dom.hasClass(f,"mceFocus")&&!f.disabled){f.focus();return false}})})}document.onkeyup=tinyMCEPopup._closeWinKeyHandler},_accessHandler:function(a){a=a||window.event;if(a.keyCode==13||a.keyCode==32){a=a.target||a.srcElement;if(a.onchange){a.onchange()}return tinymce.dom.Event.cancel(a)}},_closeWinKeyHandler:function(a){a=a||window.event;if(a.keyCode==27){tinyMCEPopup.close()}},_wait:function(){if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);tinyMCEPopup._onDOMLoaded()}});if(document.documentElement.doScroll&&window==window.top){(function(){if(tinyMCEPopup.domLoaded){return}try{document.documentElement.doScroll("left")}catch(a){setTimeout(arguments.callee,0);return}tinyMCEPopup._onDOMLoaded()})()}document.attachEvent("onload",tinyMCEPopup._onDOMLoaded)}else{if(document.addEventListener){window.addEventListener("DOMContentLoaded",tinyMCEPopup._onDOMLoaded,false);window.addEventListener("load",tinyMCEPopup._onDOMLoaded,false)}}}}; |
1 /** |
|
2 * popup.js |
|
3 * |
|
4 * An altered version of tinyMCEPopup to work in the same window as tinymce. |
|
5 * |
|
6 * ------------------------------------------------------------------ |
|
7 * |
|
8 * Copyright 2009, Moxiecode Systems AB |
|
9 * Released under LGPL License. |
|
10 * |
|
11 * License: http://tinymce.moxiecode.com/license |
|
12 * Contributing: http://tinymce.moxiecode.com/contributing |
|
13 */ |
|
14 |
|
15 // Some global instances |
|
16 |
|
17 /** |
|
18 * TinyMCE popup/dialog helper class. This gives you easy access to the |
|
19 * parent editor instance and a bunch of other things. It's higly recommended |
|
20 * that you load this script into your dialogs. |
|
21 * |
|
22 * @static |
|
23 * @class tinyMCEPopup |
|
24 */ |
|
25 var tinyMCEPopup = { |
|
26 /** |
|
27 * Initializes the popup this will be called automatically. |
|
28 * |
|
29 * @method init |
|
30 */ |
|
31 init : function() { |
|
32 var t = this, w, ti; |
|
33 |
|
34 // Find window & API |
|
35 w = t.getWin(); |
|
36 tinymce = w.tinymce; |
|
37 tinyMCE = w.tinyMCE; |
|
38 t.editor = tinymce.EditorManager.activeEditor; |
|
39 t.params = t.editor.windowManager.params; |
|
40 t.features = t.editor.windowManager.features; |
|
41 t.dom = tinymce.dom; |
|
42 |
|
43 // Setup on init listeners |
|
44 t.listeners = []; |
|
45 t.onInit = { |
|
46 add : function(f, s) { |
|
47 t.listeners.push({func : f, scope : s}); |
|
48 } |
|
49 }; |
|
50 |
|
51 t.isWindow = false; |
|
52 t.id = t.features.id; |
|
53 t.editor.windowManager.onOpen.dispatch(t.editor.windowManager, window); |
|
54 }, |
|
55 |
|
56 /** |
|
57 * Returns the reference to the parent window that opened the dialog. |
|
58 * |
|
59 * @method getWin |
|
60 * @return {Window} Reference to the parent window that opened the dialog. |
|
61 */ |
|
62 getWin : function() { |
|
63 return window; |
|
64 }, |
|
65 |
|
66 /** |
|
67 * Returns a window argument/parameter by name. |
|
68 * |
|
69 * @method getWindowArg |
|
70 * @param {String} n Name of the window argument to retrieve. |
|
71 * @param {String} dv Optional default value to return. |
|
72 * @return {String} Argument value or default value if it wasn't found. |
|
73 */ |
|
74 getWindowArg : function(n, dv) { |
|
75 var v = this.params[n]; |
|
76 |
|
77 return tinymce.is(v) ? v : dv; |
|
78 }, |
|
79 |
|
80 /** |
|
81 * Returns a editor parameter/config option value. |
|
82 * |
|
83 * @method getParam |
|
84 * @param {String} n Name of the editor config option to retrieve. |
|
85 * @param {String} dv Optional default value to return. |
|
86 * @return {String} Parameter value or default value if it wasn't found. |
|
87 */ |
|
88 getParam : function(n, dv) { |
|
89 return this.editor.getParam(n, dv); |
|
90 }, |
|
91 |
|
92 /** |
|
93 * Returns a language item by key. |
|
94 * |
|
95 * @method getLang |
|
96 * @param {String} n Language item like mydialog.something. |
|
97 * @param {String} dv Optional default value to return. |
|
98 * @return {String} Language value for the item like "my string" or the default value if it wasn't found. |
|
99 */ |
|
100 getLang : function(n, dv) { |
|
101 return this.editor.getLang(n, dv); |
|
102 }, |
|
103 |
|
104 /** |
|
105 * Executed a command on editor that opened the dialog/popup. |
|
106 * |
|
107 * @method execCommand |
|
108 * @param {String} cmd Command to execute. |
|
109 * @param {Boolean} ui Optional boolean value if the UI for the command should be presented or not. |
|
110 * @param {Object} val Optional value to pass with the comman like an URL. |
|
111 * @param {Object} a Optional arguments object. |
|
112 */ |
|
113 execCommand : function(cmd, ui, val, a) { |
|
114 a = a || {}; |
|
115 a.skip_focus = 1; |
|
116 |
|
117 this.restoreSelection(); |
|
118 return this.editor.execCommand(cmd, ui, val, a); |
|
119 }, |
|
120 |
|
121 /** |
|
122 * Resizes the dialog to the inner size of the window. This is needed since various browsers |
|
123 * have different border sizes on windows. |
|
124 * |
|
125 * @method resizeToInnerSize |
|
126 */ |
|
127 resizeToInnerSize : function() { |
|
128 var t = this; |
|
129 |
|
130 // Detach it to workaround a Chrome specific bug |
|
131 // https://sourceforge.net/tracker/?func=detail&atid=635682&aid=2926339&group_id=103281 |
|
132 setTimeout(function() { |
|
133 var vp = t.dom.getViewPort(window); |
|
134 |
|
135 t.editor.windowManager.resizeBy( |
|
136 t.getWindowArg('mce_width') - vp.w, |
|
137 t.getWindowArg('mce_height') - vp.h, |
|
138 t.id || window |
|
139 ); |
|
140 }, 0); |
|
141 }, |
|
142 |
|
143 /** |
|
144 * Will executed the specified string when the page has been loaded. This function |
|
145 * was added for compatibility with the 2.x branch. |
|
146 * |
|
147 * @method executeOnLoad |
|
148 * @param {String} s String to evalutate on init. |
|
149 */ |
|
150 executeOnLoad : function(s) { |
|
151 this.onInit.add(function() { |
|
152 eval(s); |
|
153 }); |
|
154 }, |
|
155 |
|
156 /** |
|
157 * Stores the current editor selection for later restoration. This can be useful since some browsers |
|
158 * looses it's selection if a control element is selected/focused inside the dialogs. |
|
159 * |
|
160 * @method storeSelection |
|
161 */ |
|
162 storeSelection : function() { |
|
163 this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark(1); |
|
164 }, |
|
165 |
|
166 /** |
|
167 * Restores any stored selection. This can be useful since some browsers |
|
168 * looses it's selection if a control element is selected/focused inside the dialogs. |
|
169 * |
|
170 * @method restoreSelection |
|
171 */ |
|
172 restoreSelection : function() { |
|
173 var t = tinyMCEPopup; |
|
174 |
|
175 if (!t.isWindow && tinymce.isIE) |
|
176 t.editor.selection.moveToBookmark(t.editor.windowManager.bookmark); |
|
177 }, |
|
178 |
|
179 /** |
|
180 * Loads a specific dialog language pack. If you pass in plugin_url as a arugment |
|
181 * when you open the window it will load the <plugin url>/langs/<code>_dlg.js lang pack file. |
|
182 * |
|
183 * @method requireLangPack |
|
184 */ |
|
185 requireLangPack : function() { |
|
186 var t = this, u = t.getWindowArg('plugin_url') || t.getWindowArg('theme_url'); |
|
187 |
|
188 if (u && t.editor.settings.language && t.features.translate_i18n !== false) { |
|
189 u += '/langs/' + t.editor.settings.language + '_dlg.js'; |
|
190 |
|
191 if (!tinymce.ScriptLoader.isDone(u)) { |
|
192 document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"></script>'); |
|
193 tinymce.ScriptLoader.markDone(u); |
|
194 } |
|
195 } |
|
196 }, |
|
197 |
|
198 /** |
|
199 * Executes a color picker on the specified element id. When the user |
|
200 * then selects a color it will be set as the value of the specified element. |
|
201 * |
|
202 * @method pickColor |
|
203 * @param {DOMEvent} e DOM event object. |
|
204 * @param {string} element_id Element id to be filled with the color value from the picker. |
|
205 */ |
|
206 pickColor : function(e, element_id) { |
|
207 this.execCommand('mceColorPicker', true, { |
|
208 color : document.getElementById(element_id).value, |
|
209 func : function(c) { |
|
210 document.getElementById(element_id).value = c; |
|
211 |
|
212 try { |
|
213 document.getElementById(element_id).onchange(); |
|
214 } catch (ex) { |
|
215 // Try fire event, ignore errors |
|
216 } |
|
217 } |
|
218 }); |
|
219 }, |
|
220 |
|
221 /** |
|
222 * Opens a filebrowser/imagebrowser this will set the output value from |
|
223 * the browser as a value on the specified element. |
|
224 * |
|
225 * @method openBrowser |
|
226 * @param {string} element_id Id of the element to set value in. |
|
227 * @param {string} type Type of browser to open image/file/flash. |
|
228 * @param {string} option Option name to get the file_broswer_callback function name from. |
|
229 */ |
|
230 openBrowser : function(element_id, type, option) { |
|
231 tinyMCEPopup.restoreSelection(); |
|
232 this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window); |
|
233 }, |
|
234 |
|
235 /** |
|
236 * Creates a confirm dialog. Please don't use the blocking behavior of this |
|
237 * native version use the callback method instead then it can be extended. |
|
238 * |
|
239 * @method confirm |
|
240 * @param {String} t Title for the new confirm dialog. |
|
241 * @param {function} cb Callback function to be executed after the user has selected ok or cancel. |
|
242 * @param {Object} s Optional scope to execute the callback in. |
|
243 */ |
|
244 confirm : function(t, cb, s) { |
|
245 this.editor.windowManager.confirm(t, cb, s, window); |
|
246 }, |
|
247 |
|
248 /** |
|
249 * Creates a alert dialog. Please don't use the blocking behavior of this |
|
250 * native version use the callback method instead then it can be extended. |
|
251 * |
|
252 * @method alert |
|
253 * @param {String} t Title for the new alert dialog. |
|
254 * @param {function} cb Callback function to be executed after the user has selected ok. |
|
255 * @param {Object} s Optional scope to execute the callback in. |
|
256 */ |
|
257 alert : function(tx, cb, s) { |
|
258 this.editor.windowManager.alert(tx, cb, s, window); |
|
259 }, |
|
260 |
|
261 /** |
|
262 * Closes the current window. |
|
263 * |
|
264 * @method close |
|
265 */ |
|
266 close : function() { |
|
267 var t = this; |
|
268 |
|
269 // To avoid domain relaxing issue in Opera |
|
270 function close() { |
|
271 t.editor.windowManager.close(window); |
|
272 t.editor = null; |
|
273 }; |
|
274 |
|
275 if (tinymce.isOpera) |
|
276 t.getWin().setTimeout(close, 0); |
|
277 else |
|
278 close(); |
|
279 }, |
|
280 |
|
281 // Internal functions |
|
282 |
|
283 _restoreSelection : function() { |
|
284 var e = window.event.srcElement; |
|
285 |
|
286 if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button')) |
|
287 tinyMCEPopup.restoreSelection(); |
|
288 }, |
|
289 |
|
290 /* _restoreSelection : function() { |
|
291 var e = window.event.srcElement; |
|
292 |
|
293 // If user focus a non text input or textarea |
|
294 if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text') |
|
295 tinyMCEPopup.restoreSelection(); |
|
296 },*/ |
|
297 |
|
298 _onDOMLoaded : function() { |
|
299 var t = tinyMCEPopup, ti = document.title, bm, h, nv; |
|
300 |
|
301 if (t.domLoaded) |
|
302 return; |
|
303 |
|
304 t.domLoaded = 1; |
|
305 |
|
306 tinyMCEPopup.init(); |
|
307 |
|
308 // Translate page |
|
309 if (t.features.translate_i18n !== false) { |
|
310 h = document.body.innerHTML; |
|
311 |
|
312 // Replace a=x with a="x" in IE |
|
313 if (tinymce.isIE) |
|
314 h = h.replace(/ (value|title|alt)=([^"][^\s>]+)/gi, ' $1="$2"') |
|
315 |
|
316 document.dir = t.editor.getParam('directionality',''); |
|
317 |
|
318 if ((nv = t.editor.translate(h)) && nv != h) |
|
319 document.body.innerHTML = nv; |
|
320 |
|
321 if ((nv = t.editor.translate(ti)) && nv != ti) |
|
322 document.title = ti = nv; |
|
323 } |
|
324 |
|
325 document.body.style.display = ''; |
|
326 |
|
327 // Restore selection in IE when focus is placed on a non textarea or input element of the type text |
|
328 if (tinymce.isIE) { |
|
329 document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection); |
|
330 |
|
331 // Add base target element for it since it would fail with modal dialogs |
|
332 t.dom.add(t.dom.select('head')[0], 'base', {target : '_self'}); |
|
333 } |
|
334 |
|
335 t.restoreSelection(); |
|
336 |
|
337 // Set inline title |
|
338 if (!t.isWindow) |
|
339 t.editor.windowManager.setTitle(window, ti); |
|
340 else |
|
341 window.focus(); |
|
342 |
|
343 if (!tinymce.isIE && !t.isWindow) { |
|
344 tinymce.dom.Event._add(document, 'focus', function() { |
|
345 t.editor.windowManager.focus(t.id); |
|
346 }); |
|
347 } |
|
348 |
|
349 // Patch for accessibility |
|
350 tinymce.each(t.dom.select('select'), function(e) { |
|
351 e.onkeydown = tinyMCEPopup._accessHandler; |
|
352 }); |
|
353 |
|
354 // Call onInit |
|
355 // Init must be called before focus so the selection won't get lost by the focus call |
|
356 tinymce.each(t.listeners, function(o) { |
|
357 o.func.call(o.scope, t.editor); |
|
358 }); |
|
359 |
|
360 // Move focus to window |
|
361 if (t.getWindowArg('mce_auto_focus', true)) { |
|
362 window.focus(); |
|
363 |
|
364 // Focus element with mceFocus class |
|
365 tinymce.each(document.forms, function(f) { |
|
366 tinymce.each(f.elements, function(e) { |
|
367 if (t.dom.hasClass(e, 'mceFocus') && !e.disabled) { |
|
368 e.focus(); |
|
369 return false; // Break loop |
|
370 } |
|
371 }); |
|
372 }); |
|
373 } |
|
374 |
|
375 document.onkeyup = tinyMCEPopup._closeWinKeyHandler; |
|
376 }, |
|
377 |
|
378 _accessHandler : function(e) { |
|
379 e = e || window.event; |
|
380 |
|
381 if (e.keyCode == 13 || e.keyCode == 32) { |
|
382 e = e.target || e.srcElement; |
|
383 |
|
384 if (e.onchange) |
|
385 e.onchange(); |
|
386 |
|
387 return tinymce.dom.Event.cancel(e); |
|
388 } |
|
389 }, |
|
390 |
|
391 _closeWinKeyHandler : function(e) { |
|
392 e = e || window.event; |
|
393 |
|
394 if (e.keyCode == 27) |
|
395 tinyMCEPopup.close(); |
|
396 }, |
|
397 |
|
398 _wait : function() { |
|
399 // Use IE method |
|
400 if (document.attachEvent) { |
|
401 document.attachEvent("onreadystatechange", function() { |
|
402 if (document.readyState === "complete") { |
|
403 document.detachEvent("onreadystatechange", arguments.callee); |
|
404 tinyMCEPopup._onDOMLoaded(); |
|
405 } |
|
406 }); |
|
407 |
|
408 if (document.documentElement.doScroll && window == window.top) { |
|
409 (function() { |
|
410 if (tinyMCEPopup.domLoaded) |
|
411 return; |
|
412 |
|
413 try { |
|
414 // If IE is used, use the trick by Diego Perini |
|
415 // http://javascript.nwbox.com/IEContentLoaded/ |
|
416 document.documentElement.doScroll("left"); |
|
417 } catch (ex) { |
|
418 setTimeout(arguments.callee, 0); |
|
419 return; |
|
420 } |
|
421 |
|
422 tinyMCEPopup._onDOMLoaded(); |
|
423 })(); |
|
424 } |
|
425 |
|
426 document.attachEvent('onload', tinyMCEPopup._onDOMLoaded); |
|
427 } else if (document.addEventListener) { |
|
428 window.addEventListener('DOMContentLoaded', tinyMCEPopup._onDOMLoaded, false); |
|
429 window.addEventListener('load', tinyMCEPopup._onDOMLoaded, false); |
|
430 } |
|
431 } |
|
432 }; |