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,692 @@
1
+/**
2
+ * $Id$
3
+ *
4
+ * @author Moxiecode
5
+ * @copyright Copyright � 2004-2007, Moxiecode Systems AB, All rights reserved.
6
+ *
7
+ * The contents of this file will be wrapped in a class later on.
8
+ */
9
+
10
+/**#@+
11
+ * @member TinyMCE_Engine
12
+ * @method
13
+ */
14
+tinyMCE.add(TinyMCE_Engine, {
15
+	/**
16
+	 * Creates a HTML tag by name and attributes array. This will XML encode all attribute values.
17
+	 *
18
+	 * @param {string} tn Tag name to create.
19
+	 * @param {Array} a Optional name/Value array of attributes.
20
+	 * @param {string} h Optional inner HTML of new tag, raw HTML code.
21
+	 */
22
+	createTagHTML : function(tn, a, h) {
23
+		var o = '', f = tinyMCE.xmlEncode, n;
24
+
25
+		o = '<' + tn;
26
+
27
+		if (a) {
28
+			for (n in a) {
29
+				if (typeof(a[n]) != 'function' && a[n] != null)
30
+					o += ' ' + f(n) + '="' + f('' + a[n]) + '"';
31
+			}
32
+		}
33
+
34
+		o += !h ? ' />' : '>' + h + '</' + tn + '>';
35
+
36
+		return o;
37
+	},
38
+
39
+	/**
40
+	 * Creates a tag by name and attributes array. This will create a DOM node out of the specified
41
+	 * data.
42
+	 *
43
+	 * @param {string} d Document to create DOM node in.
44
+	 * @param {string} tn Tag name to create.
45
+	 * @param {Array} a Optional name/Value array of attributes.
46
+	 * @param {string} h Optional inner HTML of new tag, raw HTML code.
47
+	 */
48
+	createTag : function(d, tn, a, h) {
49
+		var o = d.createElement(tn), n;
50
+
51
+		if (a) {
52
+			for (n in a) {
53
+				if (typeof(a[n]) != 'function' && a[n] != null)
54
+					tinyMCE.setAttrib(o, n, a[n]);
55
+			}
56
+		}
57
+
58
+		if (h)
59
+			o.innerHTML = h;
60
+
61
+		return o;
62
+	},
63
+
64
+	/**
65
+	 * Returns a element by a specific attribute and it's value.
66
+	 *
67
+	 * @param {HTMLElement} n Element to search in.
68
+	 * @param {string} e Element name to search for.
69
+	 * @param {string} a Attribute name to search for.
70
+	 * @param {string} v Attribute value to search for.
71
+	 * @return HTML element that matched the criterias or null on failure.
72
+	 * @type HTMLElement
73
+	 */
74
+	getElementByAttributeValue : function(n, e, a, v) {
75
+		return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
76
+	},
77
+
78
+	/**
79
+	 * Returns a element array by a specific attribute and it's value.
80
+	 *
81
+	 * @param {HTMLElement} n Element to search in.
82
+	 * @param {string} e Element name to search for.
83
+	 * @param {string} a Attribute name to search for.
84
+	 * @param {string} v Attribute value to search for.
85
+	 * @return HTML element array that matched the criterias or null on failure.
86
+	 * @type Array
87
+	 */
88
+	getElementsByAttributeValue : function(n, e, a, v) {
89
+		var i, nl = n.getElementsByTagName(e), o = [];
90
+
91
+		for (i=0; i<nl.length; i++) {
92
+			if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
93
+				o[o.length] = nl[i];
94
+		}
95
+
96
+		return o;
97
+	},
98
+
99
+	/**
100
+	 * Returns true/false if the specified node is a block element or not.
101
+	 *
102
+	 * @param {HTMLNode} n Node to verify.
103
+	 * @return true/false if the specified node is a block element or not.
104
+	 * @type boolean
105
+	 */
106
+	isBlockElement : function(n) {
107
+		return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
108
+	},
109
+
110
+	/**
111
+	 * Returns the first block element parent of the specified node.
112
+	 *
113
+	 * @param {HTMLNode} n Node get parent block element for.
114
+	 * @param {HTMLNode} r Optional root element, never go below this point.
115
+	 * @return First block element parent of the specified node or null if it wasn't found.
116
+	 * @type HTMLElement
117
+	 */
118
+	getParentBlockElement : function(n, r) {
119
+		return this.getParentNode(n, function(n) {
120
+			return tinyMCE.isBlockElement(n);
121
+		}, r);
122
+
123
+		return null;
124
+	},
125
+
126
+	/**
127
+	 * Inserts a node after the specific node.
128
+	 *
129
+	 * @param {HTMLNode} n New node to insert.
130
+	 * @param {HTMLNode} r Reference node to insert after.
131
+	 */
132
+	insertAfter : function(n, r){
133
+		if (r.nextSibling)
134
+			r.parentNode.insertBefore(n, r.nextSibling);
135
+		else
136
+			r.parentNode.appendChild(n);
137
+	},
138
+
139
+	/**
140
+	 * Sets the innerHTML property of a element, this function also
141
+	 * fixes a MSIE bug where the first comment is removed.
142
+	 *
143
+	 * @param {HTMLElement} e Element to insert HTML in.
144
+	 * @param {string} h HTML code to insert into innerHTML.
145
+	 */
146
+	setInnerHTML : function(e, h) {
147
+		var i, nl, n;
148
+
149
+		// Convert all strong/em to b/i in Gecko
150
+		if (tinyMCE.isGecko) {
151
+			h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>');
152
+			h = h.replace(/<em([^>]*)>/gi, '<i$1>');
153
+			h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>');
154
+			h = h.replace(/<strong([^>]*)>/gi, '<b$1>');
155
+			h = h.replace(/<\/strong>/gi, '</b>');
156
+			h = h.replace(/<\/em>/gi, '</i>');
157
+		}
158
+
159
+		if (tinyMCE.isRealIE) {
160
+			// Since MSIE handles invalid HTML better that valid XHTML we
161
+			// need to make some things invalid. <hr /> gets converted to <hr>.
162
+			h = h.replace(/\s\/>/g, '>');
163
+
164
+			// Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
165
+			h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
166
+			h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
167
+			h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
168
+
169
+			// Remove first comment
170
+			e.innerHTML = tinyMCE.uniqueTag + h;
171
+			e.firstChild.removeNode(true);
172
+
173
+			// Remove weird auto generated empty paragraphs unless it's supposed to be there
174
+			nl = e.getElementsByTagName("p");
175
+			for (i=nl.length-1; i>=0; i--) {
176
+				n = nl[i];
177
+
178
+				if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
179
+					n.parentNode.removeChild(n);
180
+			}
181
+		} else {
182
+			h = this.fixGeckoBaseHREFBug(1, e, h);
183
+			e.innerHTML = h;
184
+			this.fixGeckoBaseHREFBug(2, e, h);
185
+		}
186
+	},
187
+
188
+	/**
189
+	 * Returns the outer HTML of a element, this uses the outerHTML
190
+	 * property in MSIE and Opera and a workaround for Gecko.
191
+	 *
192
+	 * @param {HTMLElement} e HTML element to get outerHTML from.
193
+	 * @return HTML content string.
194
+	 * @type string
195
+	 */
196
+	getOuterHTML : function(e) {
197
+		var d;
198
+
199
+		if (tinyMCE.isIE)
200
+			return e.outerHTML;
201
+
202
+		d = e.ownerDocument.createElement("body");
203
+		d.appendChild(e.cloneNode(true));
204
+
205
+		return d.innerHTML;
206
+	},
207
+
208
+	/**
209
+	 * Sets the outer HTML of a element, this uses the outerHTML
210
+	 * property in MSIE and Opera and a workaround for Gecko.
211
+	 *
212
+	 * @param {HTMLElement} e HTML element to set outerHTML on.
213
+	 * @param {string} h HTML string to set in property.
214
+	 * @param {DOMDocument} d Optional document instance (Required in old IE versions).
215
+	 */
216
+	setOuterHTML : function(e, h, d) {
217
+		var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
218
+
219
+		if (tinyMCE.isIE && e.nodeType == 1)
220
+			e.outerHTML = h;
221
+		else {
222
+			t = d.createElement("body");
223
+			t.innerHTML = h;
224
+
225
+			for (i=0, nl=t.childNodes; i<nl.length; i++)
226
+				e.parentNode.insertBefore(nl[i].cloneNode(true), e);
227
+
228
+			e.parentNode.removeChild(e);
229
+		}
230
+	},
231
+
232
+	/**
233
+	 * Returns a element by id, this will also search the form names to match the id.
234
+	 *
235
+	 * @param {string} id Id of element.
236
+	 * @param {DOMDocument} d Optional document.
237
+	 * @return HTML element that matches the id.
238
+	 * @type HTMLElement
239
+	 */
240
+	_getElementById : function(id, d) {
241
+		var e, i, j, f;
242
+
243
+		if (typeof(d) == "undefined")
244
+			d = document;
245
+
246
+		e = d.getElementById(id);
247
+		if (!e) {
248
+			f = d.forms;
249
+
250
+			for (i=0; i<f.length; i++) {
251
+				for (j=0; j<f[i].elements.length; j++) {
252
+					if (f[i].elements[j].name == id) {
253
+						e = f[i].elements[j];
254
+						break;
255
+					}
256
+				}
257
+			}
258
+		}
259
+
260
+		return e;
261
+	},
262
+
263
+	/**
264
+	 * Returns a array of nodes selected retrived from the child nodes of the specified node.
265
+	 *
266
+	 * @param {HTMLNode} n Node to get children from.
267
+	 * @param {Array} na Array to fill with children.
268
+	 * @param {int} t Node type to get.
269
+	 * @param {string} nn Node name of items to retrive.
270
+	 * @return Node array.
271
+	 * @type Array
272
+	 * @deprecated
273
+	 */
274
+	getNodeTree : function(n, na, t, nn) {
275
+		return this.selectNodes(n, function(n) {
276
+			return (!t || n.nodeType == t) && (!nn || n.nodeName == nn);
277
+		}, na ? na : []);
278
+	},
279
+
280
+	/**
281
+	 * Returns the parent element of the specified node based on the search criteria.
282
+	 *
283
+	 * @param {HTMLNode} node Node to get parent element of.
284
+	 * @param {string} na Comma separated list of element names to get.
285
+	 * @param {function} f Optional function to call for each node, if it returns true the node is valid.
286
+	 * @param {HTMLNode} r Optional root element, never go below this point.
287
+	 * @return HTMLElement or null based on search criteras.
288
+	 * @type HTMLElement
289
+	 */
290
+	getParentElement : function(n, na, f, r) {
291
+		var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v;
292
+
293
+		// Compatiblity with old scripts where f param was a attribute string
294
+		if (f && typeof(f) == 'string')
295
+			return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) !== '';});
296
+
297
+		return this.getParentNode(n, function(n) {
298
+			return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n));
299
+		}, r);
300
+	},
301
+
302
+	/**
303
+	 * Returns a node by the specified selector function. This function will
304
+	 * loop through all parent nodes and call the specified function for each node.
305
+	 * If the function then returns true it will stop the execution and return that node.
306
+	 *
307
+	 * @param {DOMNode} n HTML node to search parents on.
308
+	 * @param {function} f Selection function to execute on each node.
309
+	 * @param {HTMLNode} r Optional root element, never go below this point.
310
+	 * @return DOMNode or null if it wasn't found.
311
+	 * @type DOMNode
312
+	 */
313
+	getParentNode : function(n, f, r) {
314
+		while (n) {
315
+			if (n == r)
316
+				return null;
317
+
318
+			if (f(n))
319
+				return n;
320
+
321
+			n = n.parentNode;
322
+		}
323
+
324
+		return null;
325
+	},
326
+
327
+	/**
328
+	 * Returns the attribute value of a element or the default value if it wasn't found.
329
+	 *
330
+	 * @param {HTMLElement} elm HTML element to get attribute from.
331
+	 * @param {string} name Attribute name to retrive.
332
+	 * @param {string} dv Optional default value to return, this value defaults to a empty string.
333
+	 * @return Attribute value or default value if it wasn't found in element.
334
+	 * @type string
335
+	 */
336
+	getAttrib : function(elm, name, dv) {
337
+		var v;
338
+
339
+		if (typeof(dv) == "undefined")
340
+			dv = "";
341
+
342
+		// Not a element
343
+		if (!elm || elm.nodeType != 1)
344
+			return dv;
345
+
346
+		try {
347
+			v = elm.getAttribute(name, 0);
348
+		} catch (ex) {
349
+			// IE 7 may cast exception on invalid attributes
350
+			v = elm.getAttribute(name, 2);
351
+		}
352
+
353
+		// Try className for class attrib
354
+		if (name == "class" && !v)
355
+			v = elm.className;
356
+
357
+		// Workaround for a issue with Firefox 1.5rc2+
358
+		if (tinyMCE.isGecko) {
359
+			if (name == "src" && elm.src != null && elm.src !== '')
360
+				v = elm.src;
361
+
362
+			// Workaround for a issue with Firefox 1.5rc2+
363
+			if (name == "href" && elm.href != null && elm.href !== '')
364
+				v = elm.href;
365
+		} else if (tinyMCE.isIE) {
366
+			switch (name) {
367
+				case "http-equiv":
368
+					v = elm.httpEquiv;
369
+					break;
370
+
371
+				case "width":
372
+				case "height":
373
+					v = elm.getAttribute(name, 2);
374
+					break;
375
+			}
376
+		}
377
+
378
+		if (name == "style" && !tinyMCE.isOpera)
379
+			v = elm.style.cssText;
380
+
381
+		return (v && v !== '') ? v : dv;
382
+	},
383
+
384
+	/**
385
+	 * Sets the attribute value for a specific attribute.
386
+	 *
387
+	 * @param {HTMLElement} el HTML element to set attribute on.
388
+	 * @param {string} name Attribute name to set.
389
+	 * @param {string} va Attribute value to set.
390
+	 * @param {boolean} fix Optional fix value state, if true only number data will be accepted.
391
+	 */
392
+	setAttrib : function(el, name, va, fix) {
393
+		if (typeof(va) == "number" && va != null)
394
+			va = "" + va;
395
+
396
+		if (fix) {
397
+			if (va == null)
398
+				va = "";
399
+
400
+			va = va.replace(/[^0-9%]/g, '');
401
+		}
402
+
403
+		if (name == "style")
404
+			el.style.cssText = va;
405
+
406
+		if (name == "class")
407
+			el.className = va;
408
+
409
+		if (va != null && va !== '' && va != -1)
410
+			el.setAttribute(name, va);
411
+		else
412
+			el.removeAttribute(name);
413
+	},
414
+
415
+	/**
416
+	 * Sets a style attribute item value.
417
+	 *
418
+	 * @param {HTMLElement} e HTML element to set style attribute item on.
419
+	 * @param {string} n Style item name to set.
420
+	 * @param {string} v Style item value to set.
421
+	 */
422
+	setStyleAttrib : function(e, n, v) {
423
+		e.style[n] = v;
424
+
425
+		// Style attrib deleted in IE
426
+		if (tinyMCE.isIE && v == null || v == '') {
427
+			v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText));
428
+			e.style.cssText = v;
429
+			e.setAttribute("style", v);
430
+		}
431
+	},
432
+
433
+	/**
434
+	 * Switches the CSS class of the specified element. This method also caches the
435
+	 * elements in a lookup table for performance. This should only be used for TinyMCE main UI controls
436
+	 * like buttons or select elements.
437
+	 *
438
+	 * @param {HTMLElement} ei Element to set CSS class on.
439
+	 * @param {string} c CSS class to set.
440
+	 */
441
+	switchClass : function(ei, c) {
442
+		var e;
443
+
444
+		if (tinyMCE.switchClassCache[ei])
445
+			e = tinyMCE.switchClassCache[ei];
446
+		else
447
+			e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);
448
+
449
+		if (e) {
450
+			// Keep tile mode
451
+			if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
452
+				c = 'mceTiledButton ' + c;
453
+
454
+			e.className = c;
455
+		}
456
+	},
457
+
458
+	/**
459
+	 * Returns the absolute x, y position of a node. The position will be returned in a object with
460
+	 * two properties absLeft and absTop.
461
+	 *
462
+	 * @param {HTMLNode} n HTML element to get x, y position from.
463
+	 * @param {HTMLNode} cn Optional HTML element to to stop position calcualtion by.
464
+	 * @return Absolute position of the specified element.
465
+	 * @type TinyMCE_ElementPosition
466
+	 */
467
+	getAbsPosition : function(n, cn) {
468
+		var l = 0, t = 0;
469
+
470
+		while (n && n != cn) {
471
+			l += n.offsetLeft;
472
+			t += n.offsetTop;
473
+			n = n.offsetParent;
474
+		}
475
+
476
+		return {absLeft : l, absTop : t};
477
+	},
478
+
479
+	/**
480
+	 * Finds any previous element by name. This will loop through the siblings
481
+	 * inorder to find the specified element by name. If the element wasn't found
482
+	 * it will return a null value. 
483
+	 *
484
+	 * @param {HTMLNode} e HTML node to search from.
485
+	 * @param {string} n Comma separated list of element names to search for.
486
+	 * @return HTML Element or null if it wasn't found.
487
+	 * @type HTMLElement 
488
+	 */
489
+	prevNode : function(e, n) {
490
+		var a = n.split(','), i;
491
+
492
+		while ((e = e.previousSibling) != null) {
493
+			for (i=0; i<a.length; i++) {
494
+				if (e.nodeName == a[i])
495
+					return e;
496
+			}
497
+		}
498
+
499
+		return null;
500
+	},
501
+
502
+	/**
503
+	 * Finds any element after the current one by name. This will loop through the siblings
504
+	 * inorder to find the specified element by name. If the element wasn't found
505
+	 * it will return a null value. 
506
+	 *
507
+	 * @param {HTMLNode} e HTML node to search from.
508
+	 * @param {string} n Comma separated list of element names to search for.
509
+	 * @return HTML Element or null if it wasn't found.
510
+	 * @type HTMLElement 
511
+	 */
512
+	nextNode : function(e, n) {
513
+		var a = n.split(','), i;
514
+
515
+		while ((e = e.nextSibling) != null) {
516
+			for (i=0; i<a.length; i++) {
517
+				if (e.nodeName == a[i])
518
+					return e;
519
+			}
520
+		}
521
+
522
+		return null;
523
+	},
524
+
525
+	/**
526
+	 * Returns a array of elements when the specified function matches a node.
527
+	 *
528
+	 * @param {DOMNode} n Node to select children from.
529
+	 * @param {string} na Element name(s) to search for separated by commas.
530
+	 * @param {function} f Function that returns true/false if the node is to be added or not.
531
+	 * @return Array with selected elements.
532
+	 * @type Array
533
+	 */
534
+	selectElements : function(n, na, f) {
535
+		var i, a = [], nl, x;
536
+
537
+		for (x=0, na = na.split(','); x<na.length; x++)
538
+			for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++)
539
+				(!f || f(nl[i])) && a.push(nl[i]);
540
+
541
+		return a;
542
+	},
543
+
544
+	/**
545
+	 * Returns a array of nodes when the specified function matches a node.
546
+	 *
547
+	 * @param {DOMNode} n Node to select children from.
548
+	 * @param {function} f Function that returns true/false if the node is to be added or not.
549
+	 * @param {Array} a Optional array to fill with nodes.
550
+	 * @return Array with selected nodes.
551
+	 * @type Array
552
+	 */
553
+	selectNodes : function(n, f, a) {
554
+		var i;
555
+
556
+		if (!a)
557
+			a = [];
558
+
559
+		if (f(n))
560
+			a[a.length] = n;
561
+
562
+		if (n.hasChildNodes()) {
563
+			for (i=0; i<n.childNodes.length; i++)
564
+				tinyMCE.selectNodes(n.childNodes[i], f, a);
565
+		}
566
+
567
+		return a;
568
+	},
569
+
570
+	/**
571
+	 * Adds a CSS class to the specified element. It will remove any previous item with the same name
572
+	 * so adding a class that already exists will move it to the end.
573
+	 *
574
+	 * @param {HTMLElement} e HTML element to add CSS class to.
575
+	 * @param {string] c CSS class to add to HTML element.
576
+	 * @param {boolean] b Optional parameter, if set to true, class will be added to the beginning.
577
+	 * @return Returns the new class attribute value.
578
+	 * @type string
579
+	 */
580
+	addCSSClass : function(e, c, b) {
581
+		var o = this.removeCSSClass(e, c);
582
+		return e.className = b ? c + (o !== '' ? (' ' + o) : '') : (o !== '' ? (o + ' ') : '') + c;
583
+	},
584
+
585
+	/**
586
+	 * Removes the specified CSS class from the element.
587
+	 *
588
+	 * @param {HTMLElement} e HTML element to remove CSS class to.
589
+	 * @param {string] c CSS class to remove to HTML element.
590
+	 * @return Returns the new class attribute value.
591
+	 * @type string
592
+	 */
593
+	removeCSSClass : function(e, c) {
594
+		c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
595
+		return e.className = c != ' ' ? c : '';
596
+	},
597
+
598
+	/**
599
+	 * Returns true if the specified element has the specified class.
600
+	 *
601
+	 * @param {HTMLElement} n HTML element to check CSS class on.
602
+	 * @param {string] c CSS class to check for.
603
+	 * @return true/false if the specified element has the specified class.
604
+	 * @type bool
605
+	 */
606
+	hasCSSClass : function(n, c) {
607
+		return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
608
+	},
609
+
610
+	/**
611
+	 * Renames the specified element to the specified name.
612
+	 *
613
+	 * @param {HTMLElement} e Element to rename.
614
+	 * @param {string} n New name of the element.
615
+	 * @param {DOMDocument} d Optional document reference.
616
+	 */
617
+	renameElement : function(e, n, d) {
618
+		var ne, i, ar;
619
+
620
+		d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d;
621
+
622
+		if (e) {
623
+			ne = d.createElement(n);
624
+
625
+			ar = e.attributes;
626
+			for (i=ar.length-1; i>-1; i--) {
627
+				if (ar[i].specified && ar[i].nodeValue)
628
+					ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
629
+			}
630
+
631
+			ar = e.childNodes;
632
+			for (i=0; i<ar.length; i++)
633
+				ne.appendChild(ar[i].cloneNode(true));
634
+
635
+			e.parentNode.replaceChild(ne, e);
636
+		}
637
+	},
638
+
639
+	/**
640
+	 * Returns the viewport of the specificed window instance.
641
+	 *
642
+	 * @param {Window} w Window to get viewport of.
643
+	 * @return Viewport object with fields top, left, width and height.
644
+	 * @type Object
645
+	 */
646
+	getViewPort : function(w) {
647
+		var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement;
648
+
649
+		return {
650
+			left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft),
651
+			top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop),
652
+			width : w.innerWidth || (m ? de.clientWidth : b.clientWidth),
653
+			height : w.innerHeight || (m ? de.clientHeight : b.clientHeight)
654
+		};
655
+	},
656
+
657
+	/**
658
+	 * Returns the current runtime/computed style value of a element.
659
+	 *
660
+	 * @param {Element} n HTML element to get style from.
661
+	 * @param {string} na Style name to return.
662
+	 * @param {string} d Optional default value.
663
+	 * @return {string} Current runtime/computed style value of a element.
664
+	 */
665
+	getStyle : function(n, na, d) {
666
+		if (!n)
667
+			return false;
668
+
669
+		// Gecko
670
+		if (tinyMCE.isGecko && n.ownerDocument.defaultView) {
671
+			try {
672
+				return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na);
673
+			} catch (n) {
674
+				// Old safari might fail
675
+				return null;
676
+			}
677
+		}
678
+
679
+		// Camelcase it, if needed
680
+		na = na.replace(/-(\D)/g, function(a, b){
681
+			return b.toUpperCase();
682
+		});
683
+
684
+		// IE & Opera
685
+		if (n.currentStyle)
686
+			return n.currentStyle[na];
687
+
688
+		return false;
689
+	}
690
+
691
+	/**#@-*/
692
+});