[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /** 2 * tinymce_mce_popup.js 3 * 4 * Released under LGPL License. 5 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved 6 * 7 * License: http://www.tinymce.com/license 8 * Contributing: http://www.tinymce.com/contributing 9 */ 10 11 var tinymce, tinyMCE; 12 13 /** 14 * TinyMCE popup/dialog helper class. This gives you easy access to the 15 * parent editor instance and a bunch of other things. It's higly recommended 16 * that you load this script into your dialogs. 17 * 18 * @static 19 * @class tinyMCEPopup 20 */ 21 var tinyMCEPopup = { 22 /** 23 * Initializes the popup this will be called automatically. 24 * 25 * @method init 26 */ 27 init: function () { 28 var self = this, parentWin, settings, uiWindow; 29 30 // Find window & API 31 parentWin = self.getWin(); 32 tinymce = tinyMCE = parentWin.tinymce; 33 self.editor = tinymce.EditorManager.activeEditor; 34 self.params = self.editor.windowManager.getParams(); 35 36 uiWindow = self.editor.windowManager.windows[self.editor.windowManager.windows.length - 1]; 37 self.features = uiWindow.features; 38 self.uiWindow = uiWindow; 39 40 settings = self.editor.settings; 41 42 // Setup popup CSS path(s) 43 if (settings.popup_css !== false) { 44 if (settings.popup_css) { 45 settings.popup_css = self.editor.documentBaseURI.toAbsolute(settings.popup_css); 46 } else { 47 settings.popup_css = self.editor.baseURI.toAbsolute("plugins/compat3x/css/dialog.css"); 48 } 49 } 50 51 if (settings.popup_css_add) { 52 settings.popup_css += ',' + self.editor.documentBaseURI.toAbsolute(settings.popup_css_add); 53 } 54 55 // Setup local DOM 56 self.dom = self.editor.windowManager.createInstance('tinymce.dom.DOMUtils', document, { 57 ownEvents: true, 58 proxy: tinyMCEPopup._eventProxy 59 }); 60 61 self.dom.bind(window, 'ready', self._onDOMLoaded, self); 62 63 // Enables you to skip loading the default css 64 if (self.features.popup_css !== false) { 65 self.dom.loadCSS(self.features.popup_css || self.editor.settings.popup_css); 66 } 67 68 // Setup on init listeners 69 self.listeners = []; 70 71 /** 72 * Fires when the popup is initialized. 73 * 74 * @event onInit 75 * @param {tinymce.Editor} editor Editor instance. 76 * @example 77 * // Alerts the selected contents when the dialog is loaded 78 * tinyMCEPopup.onInit.add(function(ed) { 79 * alert(ed.selection.getContent()); 80 * }); 81 * 82 * // Executes the init method on page load in some object using the SomeObject scope 83 * tinyMCEPopup.onInit.add(SomeObject.init, SomeObject); 84 */ 85 self.onInit = { 86 add: function (func, scope) { 87 self.listeners.push({ func: func, scope: scope }); 88 } 89 }; 90 91 self.isWindow = !self.getWindowArg('mce_inline'); 92 self.id = self.getWindowArg('mce_window_id'); 93 }, 94 95 /** 96 * Returns the reference to the parent window that opened the dialog. 97 * 98 * @method getWin 99 * @return {Window} Reference to the parent window that opened the dialog. 100 */ 101 getWin: function () { 102 // Added frameElement check to fix bug: #2817583 103 return (!window.frameElement && window.dialogArguments) || opener || parent || top; 104 }, 105 106 /** 107 * Returns a window argument/parameter by name. 108 * 109 * @method getWindowArg 110 * @param {String} name Name of the window argument to retrieve. 111 * @param {String} defaultValue Optional default value to return. 112 * @return {String} Argument value or default value if it wasn't found. 113 */ 114 getWindowArg: function (name, defaultValue) { 115 var value = this.params[name]; 116 117 return tinymce.is(value) ? value : defaultValue; 118 }, 119 120 /** 121 * Returns a editor parameter/config option value. 122 * 123 * @method getParam 124 * @param {String} name Name of the editor config option to retrieve. 125 * @param {String} defaultValue Optional default value to return. 126 * @return {String} Parameter value or default value if it wasn't found. 127 */ 128 getParam: function (name, defaultValue) { 129 return this.editor.getParam(name, defaultValue); 130 }, 131 132 /** 133 * Returns a language item by key. 134 * 135 * @method getLang 136 * @param {String} name Language item like mydialog.something. 137 * @param {String} defaultValue Optional default value to return. 138 * @return {String} Language value for the item like "my string" or the default value if it wasn't found. 139 */ 140 getLang: function (name, defaultValue) { 141 return this.editor.getLang(name, defaultValue); 142 }, 143 144 /** 145 * Executed a command on editor that opened the dialog/popup. 146 * 147 * @method execCommand 148 * @param {String} cmd Command to execute. 149 * @param {Boolean} ui Optional boolean value if the UI for the command should be presented or not. 150 * @param {Object} val Optional value to pass with the comman like an URL. 151 * @param {Object} a Optional arguments object. 152 */ 153 execCommand: function (cmd, ui, val, args) { 154 args = args || {}; 155 args.skip_focus = 1; 156 157 this.restoreSelection(); 158 return this.editor.execCommand(cmd, ui, val, args); 159 }, 160 161 /** 162 * Resizes the dialog to the inner size of the window. This is needed since various browsers 163 * have different border sizes on windows. 164 * 165 * @method resizeToInnerSize 166 */ 167 resizeToInnerSize: function () { 168 /*var self = this; 169 170 // Detach it to workaround a Chrome specific bug 171 // https://sourceforge.net/tracker/?func=detail&atid=635682&aid=2926339&group_id=103281 172 setTimeout(function() { 173 var vp = self.dom.getViewPort(window); 174 175 self.editor.windowManager.resizeBy( 176 self.getWindowArg('mce_width') - vp.w, 177 self.getWindowArg('mce_height') - vp.h, 178 self.id || window 179 ); 180 }, 10);*/ 181 }, 182 183 /** 184 * Will executed the specified string when the page has been loaded. This function 185 * was added for compatibility with the 2.x branch. 186 * 187 * @method executeOnLoad 188 * @param {String} evil String to evalutate on init. 189 */ 190 executeOnLoad: function (evil) { 191 this.onInit.add(function () { 192 eval(evil); 193 }); 194 }, 195 196 /** 197 * Stores the current editor selection for later restoration. This can be useful since some browsers 198 * looses it's selection if a control element is selected/focused inside the dialogs. 199 * 200 * @method storeSelection 201 */ 202 storeSelection: function () { 203 this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark(1); 204 }, 205 206 /** 207 * Restores any stored selection. This can be useful since some browsers 208 * looses it's selection if a control element is selected/focused inside the dialogs. 209 * 210 * @method restoreSelection 211 */ 212 restoreSelection: function () { 213 var self = tinyMCEPopup; 214 215 if (!self.isWindow && tinymce.isIE) { 216 self.editor.selection.moveToBookmark(self.editor.windowManager.bookmark); 217 } 218 }, 219 220 /** 221 * Loads a specific dialog language pack. If you pass in plugin_url as a argument 222 * when you open the window it will load the <plugin url>/langs/<code>_dlg.js lang pack file. 223 * 224 * @method requireLangPack 225 */ 226 requireLangPack: function () { 227 var self = this, url = self.getWindowArg('plugin_url') || self.getWindowArg('theme_url'), settings = self.editor.settings, lang; 228 229 if (settings.language !== false) { 230 lang = settings.language || "en"; 231 } 232 233 if (url && lang && self.features.translate_i18n !== false && settings.language_load !== false) { 234 url += '/langs/' + lang + '_dlg.js'; 235 236 if (!tinymce.ScriptLoader.isDone(url)) { 237 document.write('<script type="text/javascript" src="' + url + '"></script>'); 238 tinymce.ScriptLoader.markDone(url); 239 } 240 } 241 }, 242 243 /** 244 * Executes a color picker on the specified element id. When the user 245 * then selects a color it will be set as the value of the specified element. 246 * 247 * @method pickColor 248 * @param {DOMEvent} e DOM event object. 249 * @param {string} element_id Element id to be filled with the color value from the picker. 250 */ 251 pickColor: function (e, element_id) { 252 var el = document.getElementById(element_id), colorPickerCallback = this.editor.settings.color_picker_callback; 253 if (colorPickerCallback) { 254 colorPickerCallback.call( 255 this.editor, 256 function (value) { 257 el.value = value; 258 try { 259 el.onchange(); 260 } catch (ex) { 261 // Try fire event, ignore errors 262 } 263 }, 264 el.value 265 ); 266 } 267 }, 268 269 /** 270 * Opens a filebrowser/imagebrowser this will set the output value from 271 * the browser as a value on the specified element. 272 * 273 * @method openBrowser 274 * @param {string} element_id Id of the element to set value in. 275 * @param {string} type Type of browser to open image/file/flash. 276 * @param {string} option Option name to get the file_broswer_callback function name from. 277 */ 278 openBrowser: function (element_id, type) { 279 tinyMCEPopup.restoreSelection(); 280 this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window); 281 }, 282 283 /** 284 * Creates a confirm dialog. Please don't use the blocking behavior of this 285 * native version use the callback method instead then it can be extended. 286 * 287 * @method confirm 288 * @param {String} t Title for the new confirm dialog. 289 * @param {function} cb Callback function to be executed after the user has selected ok or cancel. 290 * @param {Object} s Optional scope to execute the callback in. 291 */ 292 confirm: function (t, cb, s) { 293 this.editor.windowManager.confirm(t, cb, s, window); 294 }, 295 296 /** 297 * Creates a alert dialog. Please don't use the blocking behavior of this 298 * native version use the callback method instead then it can be extended. 299 * 300 * @method alert 301 * @param {String} tx Title for the new alert dialog. 302 * @param {function} cb Callback function to be executed after the user has selected ok. 303 * @param {Object} s Optional scope to execute the callback in. 304 */ 305 alert: function (tx, cb, s) { 306 this.editor.windowManager.alert(tx, cb, s, window); 307 }, 308 309 /** 310 * Closes the current window. 311 * 312 * @method close 313 */ 314 close: function () { 315 var t = this; 316 317 // To avoid domain relaxing issue in Opera 318 function close() { 319 t.editor.windowManager.close(window); 320 tinymce = tinyMCE = t.editor = t.params = t.dom = t.dom.doc = null; // Cleanup 321 } 322 323 if (tinymce.isOpera) { 324 t.getWin().setTimeout(close, 0); 325 } else { 326 close(); 327 } 328 }, 329 330 // Internal functions 331 332 _restoreSelection: function () { 333 var e = window.event.srcElement; 334 335 if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button')) { 336 tinyMCEPopup.restoreSelection(); 337 } 338 }, 339 340 /* _restoreSelection : function() { 341 var e = window.event.srcElement; 342 343 // If user focus a non text input or textarea 344 if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text') 345 tinyMCEPopup.restoreSelection(); 346 },*/ 347 348 _onDOMLoaded: function () { 349 var t = tinyMCEPopup, ti = document.title, h, nv; 350 351 // Translate page 352 if (t.features.translate_i18n !== false) { 353 var map = { 354 "update": "Ok", 355 "insert": "Ok", 356 "cancel": "Cancel", 357 "not_set": "--", 358 "class_name": "Class name", 359 "browse": "Browse" 360 }; 361 362 var langCode = (tinymce.settings ? tinymce.settings : t.editor.settings).language || 'en'; 363 for (var key in map) { 364 tinymce.i18n.data[langCode + "." + key] = tinymce.i18n.translate(map[key]); 365 } 366 367 h = document.body.innerHTML; 368 369 // Replace a=x with a="x" in IE 370 if (tinymce.isIE) { 371 h = h.replace(/ (value|title|alt)=([^"][^\s>]+)/gi, ' $1="$2"'); 372 } 373 374 document.dir = t.editor.getParam('directionality', ''); 375 376 if ((nv = t.editor.translate(h)) && nv != h) { 377 document.body.innerHTML = nv; 378 } 379 380 if ((nv = t.editor.translate(ti)) && nv != ti) { 381 document.title = ti = nv; 382 } 383 } 384 385 if (!t.editor.getParam('browser_preferred_colors', false) || !t.isWindow) { 386 t.dom.addClass(document.body, 'forceColors'); 387 } 388 389 document.body.style.display = ''; 390 391 // Restore selection in IE when focus is placed on a non textarea or input element of the type text 392 if (tinymce.Env.ie) { 393 if (tinymce.Env.ie < 11) { 394 document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection); 395 396 // Add base target element for it since it would fail with modal dialogs 397 t.dom.add(t.dom.select('head')[0], 'base', { target: '_self' }); 398 } else { 399 document.addEventListener('mouseup', tinyMCEPopup._restoreSelection, false); 400 } 401 } 402 403 t.restoreSelection(); 404 t.resizeToInnerSize(); 405 406 // Set inline title 407 if (!t.isWindow) { 408 t.editor.windowManager.setTitle(window, ti); 409 } else { 410 window.focus(); 411 } 412 413 if (!tinymce.isIE && !t.isWindow) { 414 t.dom.bind(document, 'focus', function () { 415 t.editor.windowManager.focus(t.id); 416 }); 417 } 418 419 // Patch for accessibility 420 tinymce.each(t.dom.select('select'), function (e) { 421 e.onkeydown = tinyMCEPopup._accessHandler; 422 }); 423 424 // Call onInit 425 // Init must be called before focus so the selection won't get lost by the focus call 426 tinymce.each(t.listeners, function (o) { 427 o.func.call(o.scope, t.editor); 428 }); 429 430 // Move focus to window 431 if (t.getWindowArg('mce_auto_focus', true)) { 432 window.focus(); 433 434 // Focus element with mceFocus class 435 tinymce.each(document.forms, function (f) { 436 tinymce.each(f.elements, function (e) { 437 if (t.dom.hasClass(e, 'mceFocus') && !e.disabled) { 438 e.focus(); 439 return false; // Break loop 440 } 441 }); 442 }); 443 } 444 445 document.onkeyup = tinyMCEPopup._closeWinKeyHandler; 446 447 if ('textContent' in document) { 448 t.uiWindow.getEl('head').firstChild.textContent = document.title; 449 } else { 450 t.uiWindow.getEl('head').firstChild.innerText = document.title; 451 } 452 }, 453 454 _accessHandler: function (e) { 455 e = e || window.event; 456 457 if (e.keyCode == 13 || e.keyCode == 32) { 458 var elm = e.target || e.srcElement; 459 460 if (elm.onchange) { 461 elm.onchange(); 462 } 463 464 return tinymce.dom.Event.cancel(e); 465 } 466 }, 467 468 _closeWinKeyHandler: function (e) { 469 e = e || window.event; 470 471 if (e.keyCode == 27) { 472 tinyMCEPopup.close(); 473 } 474 }, 475 476 _eventProxy: function (id) { 477 return function (evt) { 478 tinyMCEPopup.dom.events.callNativeHandler(id, evt); 479 }; 480 } 481 }; 482 483 tinyMCEPopup.init(); 484 485 tinymce.util.Dispatcher = function (scope) { 486 this.scope = scope || this; 487 this.listeners = []; 488 489 this.add = function (callback, scope) { 490 this.listeners.push({ cb: callback, scope: scope || this.scope }); 491 492 return callback; 493 }; 494 495 this.addToTop = function (callback, scope) { 496 var self = this, listener = { cb: callback, scope: scope || self.scope }; 497 498 // Create new listeners if addToTop is executed in a dispatch loop 499 if (self.inDispatch) { 500 self.listeners = [listener].concat(self.listeners); 501 } else { 502 self.listeners.unshift(listener); 503 } 504 505 return callback; 506 }; 507 508 this.remove = function (callback) { 509 var listeners = this.listeners, output = null; 510 511 tinymce.each(listeners, function (listener, i) { 512 if (callback == listener.cb) { 513 output = listener; 514 listeners.splice(i, 1); 515 return false; 516 } 517 }); 518 519 return output; 520 }; 521 522 this.dispatch = function () { 523 var self = this, returnValue, args = arguments, i, listeners = self.listeners, listener; 524 525 self.inDispatch = true; 526 527 // Needs to be a real loop since the listener count might change while looping 528 // And this is also more efficient 529 for (i = 0; i < listeners.length; i++) { 530 listener = listeners[i]; 531 returnValue = listener.cb.apply(listener.scope, args.length > 0 ? args : [listener.scope]); 532 533 if (returnValue === false) { 534 break; 535 } 536 } 537 538 self.inDispatch = false; 539 540 return returnValue; 541 }; 542 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Fri Nov 15 08:20:01 2024 | Cross-referenced by PHPXref |