Browse code

tinyMCE '2' is now 2.1.2 - Seems tinyMCE '2' was actually 3.0.9 (my fault for not checking), so '2' is now 2.1.2, and '3' is now 3.4.8... eFiction 3.4.3 used tinyMCE 2.1.0, and 3.5 upgraded that to 3.0.9.

Clarissa Walker authored on 2026/07/28 07:20:33
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,391 @@
1
+/**
2
+ * $Id$
3
+ *
4
+ * @author Moxiecode
5
+ * @copyright Copyright � 2004-2007, Moxiecode Systems AB, All rights reserved.
6
+ */
7
+
8
+// Some global instances, this will be filled later
9
+var tinyMCE = null, tinyMCELang = null;
10
+
11
+/**
12
+ * Constructor for the popup class. This class contains base logic for popup/dialogs and sets up
13
+ * object references to the TinyMCE core.
14
+ *
15
+ * @constructor
16
+ */
17
+function TinyMCE_Popup() {
18
+};
19
+
20
+/**#@+
21
+ * @member TinyMCE_Popup
22
+ */
23
+TinyMCE_Popup.prototype = {
24
+	/**#@+
25
+	 * @method
26
+	 */
27
+
28
+	/**
29
+	 * Searches for a window with a TinyMCE instance by looping through parent windows and openers.
30
+	 *
31
+	 * @param {DOMWindow} w DOM window to start search by.
32
+	 * @return {DOMWindow} Window with TinyMCE instance in it or null.
33
+	 */
34
+	findWin : function(w) {
35
+		var c;
36
+
37
+		// Check parents
38
+		c = w;
39
+		while (c && (c = c.parent) != null) {
40
+			if (typeof(c.tinyMCE) != "undefined")
41
+				return c;
42
+		}
43
+
44
+		// Check openers
45
+		c = w;
46
+		while (c && (c = c.opener) != null) {
47
+			if (typeof(c.tinyMCE) != "undefined")
48
+				return c;
49
+		}
50
+
51
+		// Try top
52
+		if (typeof(top.tinyMCE) != "undefined")
53
+			return top;
54
+
55
+		return null;
56
+	},
57
+
58
+	/**
59
+	 * Initializes the TinyMCE Popup class. This will setup the TinyMCE core references and other popup/dialog related functions.
60
+	 */
61
+	init : function() {
62
+		var win = window.opener ? window.opener : window.dialogArguments, c;
63
+		var inst, re, title, divElm;
64
+
65
+		if (!win)
66
+			win = this.findWin(window);
67
+
68
+		if (!win) {
69
+			alert("tinyMCE object reference not found from popup.");
70
+			return;
71
+		}
72
+
73
+		window.opener = win;
74
+		this.windowOpener = win;
75
+		this.onLoadEval = "";
76
+
77
+		// Setup parent references
78
+		tinyMCE = win.tinyMCE;
79
+		tinyMCELang = win.tinyMCELang;
80
+
81
+		inst = tinyMCE.selectedInstance;
82
+		this.isWindow = tinyMCE.getWindowArg('mce_inside_iframe', false) == false;
83
+		this.storeSelection = (tinyMCE.isRealIE) && !this.isWindow && tinyMCE.getWindowArg('mce_store_selection', true);
84
+
85
+		if (this.isWindow)
86
+			window.focus();
87
+
88
+		// Store selection
89
+		if (this.storeSelection)
90
+			inst.selectionBookmark = inst.selection.getBookmark(true);
91
+
92
+		// Setup dir
93
+		if (tinyMCELang.lang_dir)
94
+			document.dir = tinyMCELang.lang_dir;
95
+
96
+		// Setup title
97
+		re = new RegExp('{|\\\$|}', 'g');
98
+		title = document.title.replace(re, "");
99
+		if (typeof(tinyMCELang[title]) != "undefined") {
100
+			divElm = document.createElement("div");
101
+			divElm.innerHTML = tinyMCELang[title];
102
+			document.title = divElm.innerHTML;
103
+
104
+			if (typeof(tinyMCE.setWindowTitle) != 'undefined')
105
+				tinyMCE.setWindowTitle(window, divElm.innerHTML);
106
+		}
107
+
108
+		// Output Popup CSS class
109
+		document.write('<link href="' + tinyMCE.getParam("popups_css") + '" rel="stylesheet" type="text/css">');
110
+
111
+		if (tinyMCE.getParam("popups_css_add")) {
112
+			c = tinyMCE.getParam("popups_css_add");
113
+
114
+			// Is relative
115
+			if (c.indexOf('://') == -1 && c.charAt(0) != '/')
116
+				c = tinyMCE.documentBasePath + "/" + c;
117
+
118
+			document.write('<link href="' + c + '" rel="stylesheet" type="text/css">');
119
+		}
120
+
121
+		tinyMCE.addEvent(window, "load", this.onLoad);
122
+	},
123
+
124
+	/**
125
+	 * Gets executed when the window has finished loading it's contents. This function will then
126
+	 * replace language variables with their real values.
127
+	 */
128
+	onLoad : function() {
129
+		var dir, i, elms, body = document.body;
130
+
131
+		if (tinyMCE.getWindowArg('mce_replacevariables', true))
132
+			body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs);
133
+
134
+		dir = tinyMCE.selectedInstance.settings.directionality;
135
+		if (dir == "rtl" && document.forms && document.forms.length > 0) {
136
+			elms = document.forms[0].elements;
137
+			for (i=0; i<elms.length; i++) {
138
+				if ((elms[i].type == "text" || elms[i].type == "textarea") && elms[i].getAttribute("dir") != "ltr")
139
+					elms[i].dir = dir;
140
+			}
141
+		}
142
+
143
+		if (body.style.display == 'none')
144
+			body.style.display = 'block';
145
+
146
+		// Execute real onload (Opera fix)
147
+		if (tinyMCEPopup.onLoadEval !== '')
148
+			eval(tinyMCEPopup.onLoadEval);
149
+	},
150
+
151
+	/**
152
+	 * Executes the specified string onload. This is a workaround for Opera since it
153
+	 * doesn't execute the events in the same order than MSIE and Firefox.
154
+	 *
155
+	 * @param {string} str String to evaluate on load.
156
+	 */
157
+	executeOnLoad : function(str) {
158
+		if (tinyMCE.isOpera)
159
+			this.onLoadEval = str;
160
+		else
161
+			eval(str);
162
+	},
163
+
164
+	/**
165
+	 * Resizes the current window to it's inner body size. This function
166
+	 * was needed since MSIE makes the visible dialog area diffrent depending
167
+	 * on what Theme/Skin you use.
168
+	 */
169
+	resizeToInnerSize : function() {
170
+		var i, doc, body, oldMargin, wrapper, iframe, nodes, dx, dy;
171
+
172
+		// Netscape 7.1 workaround
173
+		if (this.isWindow && tinyMCE.isNS71) {
174
+			window.resizeBy(0, 10);
175
+			return;
176
+		}
177
+
178
+		if (this.isWindow) {
179
+			doc = document;
180
+			body = doc.body;
181
+
182
+			if (body.style.display == 'none')
183
+				body.style.display = 'block';
184
+
185
+			// Remove margin
186
+			oldMargin = body.style.margin;
187
+			body.style.margin = '0';
188
+
189
+			// Create wrapper
190
+			wrapper = doc.createElement("div");
191
+			wrapper.id = 'mcBodyWrapper';
192
+			wrapper.style.display = 'none';
193
+			wrapper.style.margin = '0';
194
+
195
+			// Wrap body elements
196
+			nodes = doc.body.childNodes;
197
+			for (i=nodes.length-1; i>=0; i--) {
198
+				if (wrapper.hasChildNodes())
199
+					wrapper.insertBefore(nodes[i].cloneNode(true), wrapper.firstChild);
200
+				else
201
+					wrapper.appendChild(nodes[i].cloneNode(true));
202
+
203
+				nodes[i].parentNode.removeChild(nodes[i]);
204
+			}
205
+
206
+			// Add wrapper
207
+			doc.body.appendChild(wrapper);
208
+
209
+			// Create iframe
210
+			iframe = document.createElement("iframe");
211
+			iframe.id = "mcWinIframe";
212
+			iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings.default_document;
213
+			iframe.width = "100%";
214
+			iframe.height = "100%";
215
+			iframe.style.margin = '0';
216
+
217
+			// Add iframe
218
+			doc.body.appendChild(iframe);
219
+
220
+			// Measure iframe
221
+			iframe = document.getElementById('mcWinIframe');
222
+			dx = tinyMCE.getWindowArg('mce_width') - iframe.clientWidth;
223
+			dy = tinyMCE.getWindowArg('mce_height') - iframe.clientHeight;
224
+
225
+			// Resize window
226
+			// tinyMCE.debug(tinyMCE.getWindowArg('mce_width') + "," + tinyMCE.getWindowArg('mce_height') + " - " + dx + "," + dy);
227
+			window.resizeBy(dx, dy);
228
+
229
+			// Hide iframe and show wrapper
230
+			body.style.margin = oldMargin;
231
+			iframe.style.display = 'none';
232
+			wrapper.style.display = 'block';
233
+		}
234
+	},
235
+
236
+	/**
237
+	 * Resizes the current window to the dimensions of the body.
238
+	 */
239
+	resizeToContent : function() {
240
+		var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
241
+		var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
242
+		var elm, width, height, x, y, dx, dy;
243
+
244
+		if (isOpera)
245
+			return;
246
+
247
+		if (isMSIE) {
248
+			try { window.resizeTo(10, 10); } catch (e) {}
249
+
250
+			elm = document.body;
251
+			width = elm.offsetWidth;
252
+			height = elm.offsetHeight;
253
+			dx = (elm.scrollWidth - width) + 4;
254
+			dy = elm.scrollHeight - height;
255
+
256
+			try { window.resizeBy(dx, dy); } catch (e) {}
257
+		} else {
258
+			window.scrollBy(1000, 1000);
259
+			if (window.scrollX > 0 || window.scrollY > 0) {
260
+				window.resizeBy(window.innerWidth * 2, window.innerHeight * 2);
261
+				window.sizeToContent();
262
+				window.scrollTo(0, 0);
263
+				x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
264
+				y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
265
+				window.moveTo(x, y);
266
+			}
267
+		}
268
+	},
269
+
270
+	/**
271
+	 * Returns a window argument, window arguments can be passed from a plugin to a window
272
+	 * by using the tinyMCE.openWindow function.
273
+	 *
274
+	 * @param {string} name Argument name to retrive.
275
+	 * @param {string} default_value Optional default value to assign if the argument wasn't set.
276
+	 * @return Argument value object.
277
+	 * @type Object
278
+	 */
279
+	getWindowArg : function(name, default_value) {
280
+		return tinyMCE.getWindowArg(name, default_value);
281
+	},
282
+
283
+	/**
284
+	 * Restores the selection back to the one stored after executing a command.
285
+	 * This function was needed in MSIE when using inlinepopups, the selection
286
+	 * would otherwice get lost if the user focused another field.
287
+	 */
288
+	restoreSelection : function() {
289
+		var inst;
290
+
291
+		if (this.storeSelection) {
292
+			inst = tinyMCE.selectedInstance;
293
+
294
+			inst.getWin().focus();
295
+
296
+			if (inst.selectionBookmark)
297
+				inst.selection.moveToBookmark(inst.selectionBookmark);
298
+		}
299
+	},
300
+
301
+	/**
302
+	 * Executes the specific command on the parent instance that opened the window. This method
303
+	 * will also take care of the storage and restorage of the current selection in MSIE when
304
+	 * using inlinepopups. So we suggest using this method instead of tinyMCE.execCommand when using
305
+	 * popup windows.
306
+	 *
307
+	 * @param {string} command Command name to execute, for example mceLink or Bold.
308
+	 * @param {boolean} user_interface True/false state if a UI (dialog) should be presented or not.
309
+	 * @param {mixed} value Optional command value, this can be anything.
310
+	 */
311
+	execCommand : function(command, user_interface, value) {
312
+		var inst = tinyMCE.selectedInstance;
313
+
314
+		this.restoreSelection();
315
+		inst.execCommand(command, user_interface, value);
316
+
317
+		// Store selection
318
+		if (this.storeSelection)
319
+			inst.selectionBookmark = inst.selection.getBookmark(true);
320
+	},
321
+
322
+	/**
323
+	 * Closes the current window. This should be used instead of window.close. Since this will
324
+	 * also handle inlinepopups closing.
325
+	 */
326
+	close : function() {
327
+		tinyMCE.closeWindow(window);
328
+	},
329
+
330
+	/**
331
+	 * Executes a color picker on the specified element id. When the user
332
+	 * then selects a color it will be set as the value of the specified element.
333
+	 *
334
+	 * @param {DOMEvent} e DOM event object.
335
+	 * @param {string} element_id Element id to be filled with the color value from the picker.
336
+	 */
337
+	pickColor : function(e, element_id) {
338
+		tinyMCE.selectedInstance.execCommand('mceColorPicker', true, {
339
+			element_id : element_id,
340
+			document : document,
341
+			window : window,
342
+			store_selection : false
343
+		});
344
+	},
345
+
346
+	/**
347
+	 * Opens a filebrowser/imagebrowser this will set the output value from
348
+	 * the browser as a value on the specified element.
349
+	 *
350
+	 * @param {string} element_id Id of the element to set value in.
351
+	 * @param {string} type Type of browser to open image/file/flash.
352
+	 * @param {string} option Option name to get the file_broswer_callback function name from.
353
+	 */
354
+	openBrowser : function(element_id, type, option) {
355
+		var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));
356
+		var url = document.getElementById(element_id).value;
357
+
358
+		tinyMCE.setWindowArg("window", window);
359
+		tinyMCE.setWindowArg("document", document);
360
+
361
+		// Call to external callback
362
+		if (eval('typeof(tinyMCEPopup.windowOpener.' + cb + ')') == "undefined")
363
+			alert("Callback function: " + cb + " could not be found.");
364
+		else
365
+			eval("tinyMCEPopup.windowOpener." + cb + "(element_id, url, type, window);");
366
+	},
367
+
368
+	/**
369
+	 * Imports the specified class into the current popup. This will setup a local class definition
370
+	 * by importing from the parent window.
371
+	 *
372
+	 * @param {string} c Class name to import to current page.
373
+	 */
374
+	importClass : function(c) {
375
+		var n;
376
+
377
+		window[c] = function() {};
378
+
379
+		for (n in window.opener[c].prototype)
380
+			window[c].prototype[n] = window.opener[c].prototype[n];
381
+
382
+		window[c].constructor = window.opener[c].constructor;
383
+	}
384
+
385
+	/**#@-*/
386
+};
387
+
388
+// Setup global instance
389
+var tinyMCEPopup = new TinyMCE_Popup();
390
+
391
+tinyMCEPopup.init();