includes/clientside/tinymce/tiny_mce_src.js
changeset 476 f26a69c40431
parent 459 31c23016ab62
child 543 dffcbfbc4e59
equal deleted inserted replaced
475:51386f1852b8 476:f26a69c40431
     1 
     1 
     2 /* file:jscripts/tiny_mce/classes/tinymce.js */
     2 /* file:jscripts/tiny_mce/classes/tinymce.js */
     3 
     3 
     4 var tinymce = {
     4 var tinymce = {
     5 	majorVersion : '3',
     5 	majorVersion : '3',
     6 	minorVersion : '0.1',
     6 	minorVersion : '0.3',
     7 	releaseDate : '2008-02-21',
     7 	releaseDate : '2008-03-03',
     8 
     8 
     9 	_init : function() {
     9 	_init : function() {
    10 		var t = this, ua = navigator.userAgent, i, nl, n, base;
    10 		var t = this, ua = navigator.userAgent, i, nl, n, base;
    11 
    11 
    12 		// Browser checks
    12 		// Browser checks
  1029 
  1029 
  1030 			return null;
  1030 			return null;
  1031 		},
  1031 		},
  1032 
  1032 
  1033 		get : function(e) {
  1033 		get : function(e) {
  1034 			if (typeof(e) == 'string')
  1034 			var n;
  1035 				return this.doc.getElementById(e);
  1035 
       
  1036 			if (typeof(e) == 'string') {
       
  1037 				n = e;
       
  1038 				e = this.doc.getElementById(e);
       
  1039 
       
  1040 				// IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick
       
  1041 				if (e && e.id !== n)
       
  1042 					return this.doc.getElementsByName(n)[1];
       
  1043 			}
  1036 
  1044 
  1037 			return e;
  1045 			return e;
  1038 		},
  1046 		},
  1039 
  1047 
  1040 		// #if !jquery
  1048 		// #if !jquery
  1556 				r = r.offsetParent;
  1564 				r = r.offsetParent;
  1557 			}
  1565 			}
  1558 
  1566 
  1559 			r = n;
  1567 			r = n;
  1560 			while (r) {
  1568 			while (r) {
  1561 				// Opera 9.25 bug fix, fixed in 9.50
  1569 				// Opera 9.25 bug fix, fixed in 9.50 seems to be fixed in Opera 9.26 too
  1562 				if (!tinymce.isOpera || r.nodeName != 'TR') {
  1570 			/*	if (!tinymce.isOpera || r.nodeName != 'TR') {
  1563 					x -= r.scrollLeft || 0;
  1571 					x -= r.scrollLeft || 0;
  1564 					y -= r.scrollTop || 0;
  1572 					y -= r.scrollTop || 0;
  1565 				}
  1573 				}*/
  1566 
  1574 
  1567 				r = r.parentNode;
  1575 				r = r.parentNode;
  1568 
  1576 
  1569 				if (r == d.body)
  1577 				if (r == d.body)
  1570 					break;
  1578 					break;
  1787 							// IE will remove comments from the beginning
  1795 							// IE will remove comments from the beginning
  1788 							// unless you padd the contents with something
  1796 							// unless you padd the contents with something
  1789 							e.innerHTML = '<br />' + h;
  1797 							e.innerHTML = '<br />' + h;
  1790 							e.removeChild(e.firstChild);
  1798 							e.removeChild(e.firstChild);
  1791 						} catch (ex) {
  1799 						} catch (ex) {
  1792 							// IE sometimes produces an unknown runtime error on innerHTML
  1800 							// IE sometimes produces an unknown runtime error on innerHTML if it's an block element within a block element for example a div inside a p
  1793 							// This seems to fix this issue, don't know why.
  1801 							// This seems to fix this problem
       
  1802 
       
  1803 							// Remove all child nodes
       
  1804 							while (e.firstChild)
       
  1805 								e.firstChild.removeNode();
       
  1806 
       
  1807 							// Create new div with HTML contents and a BR infront to keep comments
  1794 							x = t.create('div');
  1808 							x = t.create('div');
  1795 							x.innerHTML = '<br />' + h;
  1809 							x.innerHTML = '<br />' + h;
  1796 
  1810 
       
  1811 							// Add all children from div to target
  1797 							each (x.childNodes, function(n, i) {
  1812 							each (x.childNodes, function(n, i) {
  1798 								// Skip the BR
  1813 								// Skip br element
  1799 								if (i > 1)
  1814 								if (i)
  1800 									e.appendChild(n);
  1815 									e.appendChild(n);
  1801 							});
  1816 							});
  1802 						}
  1817 						}
  1803 					};
  1818 					};
  1804 
  1819 
  1983 				}
  1998 				}
  1984 			});
  1999 			});
  1985 		},
  2000 		},
  1986 
  2001 
  1987 		decode : function(s) {
  2002 		decode : function(s) {
  1988 			var e = document.createElement("div");
  2003 			var e;
  1989 
  2004 
  1990 			e.innerHTML = s;
  2005 			// Look for entities to decode
  1991 
  2006 			if (/&[^;]+;/.test(s)) {
  1992 			return !e.firstChild ? s : e.firstChild.nodeValue;
  2007 				// Decode the entities using a div element not super efficient but less code
       
  2008 				e = this.doc.createElement("div");
       
  2009 				e.innerHTML = s;
       
  2010 
       
  2011 				return !e.firstChild ? s : e.firstChild.nodeValue;
       
  2012 			}
       
  2013 
       
  2014 			return s;
  1993 		},
  2015 		},
  1994 
  2016 
  1995 		encode : function(s) {
  2017 		encode : function(s) {
  1996 			return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) {
  2018 			return s ? ('' + s).replace(/[<>&\"]/g, function (c, b) {
  1997 				switch (c) {
  2019 				switch (c) {
  2779 					if (n == en) {
  2801 					if (n == en) {
  2780 						d.end = p;
  2802 						d.end = p;
  2781 						return d;
  2803 						return d;
  2782 					}
  2804 					}
  2783 
  2805 
  2784 					p += n.nodeValue ? n.nodeValue.length : 0;
  2806 					p += n.nodeValue ? tinymce.trim(n.nodeValue).length : 0;
  2785 				}
  2807 				}
  2786 
  2808 
  2787 				return null;
  2809 				return null;
  2788 			};
  2810 			};
  2789 
  2811 
  2796 
  2818 
  2797 				return {
  2819 				return {
  2798 					start : e.start + s.anchorOffset,
  2820 					start : e.start + s.anchorOffset,
  2799 					end : e.end + s.focusOffset,
  2821 					end : e.end + s.focusOffset,
  2800 					scrollX : sx,
  2822 					scrollX : sx,
  2801 					scrollY : sy
  2823 					scrollY : sy,
       
  2824 					beg : s.anchorOffset == 0
  2802 				};
  2825 				};
  2803 			} else {
  2826 			} else {
  2804 				e = getPos(ro, r.startContainer, r.endContainer);
  2827 				e = getPos(ro, r.startContainer, r.endContainer);
  2805 
  2828 
  2806 				if (!e)
  2829 				if (!e)
  2808 
  2831 
  2809 				return {
  2832 				return {
  2810 					start : e.start + r.startOffset,
  2833 					start : e.start + r.startOffset,
  2811 					end : e.end + r.endOffset,
  2834 					end : e.end + r.endOffset,
  2812 					scrollX : sx,
  2835 					scrollX : sx,
  2813 					scrollY : sy
  2836 					scrollY : sy,
       
  2837 					beg : r.startOffset == 0
  2814 				};
  2838 				};
  2815 			}
  2839 			}
  2816 		},
  2840 		},
  2817 
  2841 
  2818 		moveToBookmark : function(b) {
  2842 		moveToBookmark : function(b) {
  2819 			var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd;
  2843 			var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd;
  2820 
  2844 
  2821 			function getPos(r, sp, ep) {
  2845 			function getPos(r, sp, ep) {
  2822 				var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
  2846 				var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}, o, v;
  2823 
  2847 
  2824 				while ((n = w.nextNode()) != null) {
  2848 				while ((n = w.nextNode()) != null) {
  2825 					p += n.nodeValue ? n.nodeValue.length : 0;
  2849 					p += n.nodeValue ? tinymce.trim(n.nodeValue).length : 0;
  2826 
  2850 
  2827 					if (p >= sp && !d.startNode) {
  2851 					if (p >= sp && !d.startNode) {
       
  2852 						o = sp - (p - n.nodeValue.length);
       
  2853 
       
  2854 						// Fix for odd quirk in FF
       
  2855 						if (b.beg && o >= n.nodeValue.length)
       
  2856 							continue;
       
  2857 
  2828 						d.startNode = n;
  2858 						d.startNode = n;
  2829 						d.startOffset = sp - (p - n.nodeValue.length);
  2859 						d.startOffset = o;
  2830 					}
  2860 					}
  2831 
  2861 
  2832 					if (p >= ep) {
  2862 					if (p >= ep) {
  2833 						d.endNode = n;
  2863 						d.endNode = n;
  2834 						d.endOffset = ep - (p - n.nodeValue.length);
  2864 						d.endOffset = ep - (p - n.nodeValue.length);
  2835 
       
  2836 						return d;
  2865 						return d;
  2837 					}
  2866 					}
  2838 				}
  2867 				}
  2839 
  2868 
  2840 				return null;
  2869 				return null;
  2904 				s.addRange(b.rng);
  2933 				s.addRange(b.rng);
  2905 			} else {
  2934 			} else {
  2906 				if (is(b.start) && is(b.end)) {
  2935 				if (is(b.start) && is(b.end)) {
  2907 					try {
  2936 					try {
  2908 						sd = getPos(ro, b.start, b.end);
  2937 						sd = getPos(ro, b.start, b.end);
       
  2938 
  2909 						if (sd) {
  2939 						if (sd) {
  2910 							r = t.dom.doc.createRange();
  2940 							r = t.dom.doc.createRange();
  2911 							r.setStart(sd.startNode, sd.startOffset);
  2941 							r.setStart(sd.startNode, sd.startOffset);
  2912 							r.setEnd(sd.endNode, sd.endOffset);
  2942 							r.setEnd(sd.endNode, sd.endOffset);
  2913 							s.removeAllRanges();
  2943 							s.removeAllRanges();
  3337 			var t = this;
  3367 			var t = this;
  3338 
  3368 
  3339 			t.key = 0;
  3369 			t.key = 0;
  3340 			t.onPreProcess = new Dispatcher(t);
  3370 			t.onPreProcess = new Dispatcher(t);
  3341 			t.onPostProcess = new Dispatcher(t);
  3371 			t.onPostProcess = new Dispatcher(t);
  3342 			t.writer = tinymce.relaxedDomain && tinymce.isGecko ? new tinymce.dom.StringWriter() : new tinymce.dom.XMLWriter();
  3372 
       
  3373 			if (tinymce.relaxedDomain && tinymce.isGecko) {
       
  3374 				// Gecko has a bug where we can't create a new XML document if domain relaxing is used
       
  3375 				t.writer = new tinymce.dom.StringWriter();
       
  3376 			} else {
       
  3377 				try {
       
  3378 					t.writer = new tinymce.dom.XMLWriter();
       
  3379 				} catch (ex) {
       
  3380 					// IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter
       
  3381 					t.writer = new tinymce.dom.StringWriter();
       
  3382 				}
       
  3383 			}
  3343 
  3384 
  3344 			// Default settings
  3385 			// Default settings
  3345 			t.settings = s = extend({
  3386 			t.settings = s = extend({
  3346 				dom : tinymce.DOM,
  3387 				dom : tinymce.DOM,
  3347 				valid_nodes : 0,
  3388 				valid_nodes : 0,
  3846 				// This process is only done when getting contents out from the editor.
  3887 				// This process is only done when getting contents out from the editor.
  3847 				if (!o.set) {
  3888 				if (!o.set) {
  3848 					if (s.remove_linebreaks) {
  3889 					if (s.remove_linebreaks) {
  3849 						h = h.replace(/(<[^>]+>)\s+/g, '$1 ');
  3890 						h = h.replace(/(<[^>]+>)\s+/g, '$1 ');
  3850 						h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');
  3891 						h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');
  3851 						h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start
  3892 						h = h.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start
  3852 						h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start
  3893 						h = h.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start
  3853 						h = h.replace(/\s+<\/(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end
  3894 						h = h.replace(/\s+<\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end
  3854 					}
  3895 					}
  3855 
  3896 
  3856 					// Simple indentation
  3897 					// Simple indentation
  3857 					if (s.apply_source_formatting && s.indent_mode == 'simple') {
  3898 					if (s.apply_source_formatting && s.indent_mode == 'simple') {
  3858 						// Add line breaks before and after block elements
  3899 						// Add line breaks before and after block elements
  3859 						h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');
  3900 						h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');
  3860 						h = h.replace(/\s*<(p|h[1-6]|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');
  3901 						h = h.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');
  3861 						h = h.replace(/<\/(p|h[1-6]|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');
  3902 						h = h.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');
  3862 						h = h.replace(/\n\n/g, '\n');
  3903 						h = h.replace(/\n\n/g, '\n');
  3863 					}
  3904 					}
  3864 				}
  3905 				}
  3865 
  3906 
  3866 				h = t._unprotect(h, p);
  3907 				h = t._unprotect(h, p);
  4028 
  4069 
  4029 		_protect : function(o) {
  4070 		_protect : function(o) {
  4030 			o.items = o.items || [];
  4071 			o.items = o.items || [];
  4031 
  4072 
  4032 			function enc(s) {
  4073 			function enc(s) {
  4033 				return s.replace(/[\r\n]/g, function(c) {
  4074 				return s.replace(/[\r\n\\]/g, function(c) {
  4034 					if (c === '\n')
  4075 					if (c === '\n')
  4035 						return '\\n';
  4076 						return '\\n';
       
  4077 					else if (c === '\\')
       
  4078 						return '\\\\';
  4036 
  4079 
  4037 					return '\\r';
  4080 					return '\\r';
  4038 				});
  4081 				});
  4039 			};
  4082 			};
  4040 
  4083 
  4041 			function dec(s) {
  4084 			function dec(s) {
  4042 				return s.replace(/\\[rn]/g, function(c) {
  4085 				return s.replace(/\\[\\rn]/g, function(c) {
  4043 					if (c === '\\n')
  4086 					if (c === '\\n')
  4044 						return '\n';
  4087 						return '\n';
       
  4088 					else if (c === '\\\\')
       
  4089 						return '\\';
  4045 
  4090 
  4046 					return '\r';
  4091 					return '\r';
  4047 				});
  4092 				});
  4048 			};
  4093 			};
  4049 
  4094 
  4131 
  4176 
  4132 				return v;
  4177 				return v;
  4133 			} else {
  4178 			} else {
  4134 				// Remove internal mceItemXX classes when content is extracted from editor
  4179 				// Remove internal mceItemXX classes when content is extracted from editor
  4135 				if (na == 'class' && this.processObj.get)
  4180 				if (na == 'class' && this.processObj.get)
  4136 					v = v.replace(/\bmceItem\w+\b/g, '');
  4181 					v = v.replace(/\s?mceItem\w+\s?/g, '');
  4137 			}
  4182 			}
  4138 
  4183 
  4139 			if (v === '')
  4184 			if (v === '')
  4140 				return null;
  4185 				return null;
  4141 
  4186 
  4154 	tinymce.create('tinymce.dom.ScriptLoader', {
  4199 	tinymce.create('tinymce.dom.ScriptLoader', {
  4155 		ScriptLoader : function(s) {
  4200 		ScriptLoader : function(s) {
  4156 			this.settings = s || {};
  4201 			this.settings = s || {};
  4157 			this.queue = [];
  4202 			this.queue = [];
  4158 			this.lookup = {};
  4203 			this.lookup = {};
       
  4204 		},
       
  4205 
       
  4206 		isDone : function(u) {
       
  4207 			return this.lookup[u] ? this.lookup[u].state == 2 : 0;
  4159 		},
  4208 		},
  4160 
  4209 
  4161 		markDone : function(u) {
  4210 		markDone : function(u) {
  4162 			this.lookup[u] = {state : 2, url : u};
  4211 			this.lookup[u] = {state : 2, url : u};
  4163 		},
  4212 		},
  4646 			s.offset_y = s.offset_y || 0;
  4695 			s.offset_y = s.offset_y || 0;
  4647 			s.vp_offset_x = s.vp_offset_x || 0;
  4696 			s.vp_offset_x = s.vp_offset_x || 0;
  4648 			s.vp_offset_y = s.vp_offset_y || 0;
  4697 			s.vp_offset_y = s.vp_offset_y || 0;
  4649 
  4698 
  4650 			if (is(s.icons) && !s.icons)
  4699 			if (is(s.icons) && !s.icons)
  4651 				s['class'] += ' noIcons';
  4700 				s['class'] += ' mceNoIcons';
  4652 
  4701 
  4653 			this.parent(id, s);
  4702 			this.parent(id, s);
  4654 			this.onShowMenu = new tinymce.util.Dispatcher(this);
  4703 			this.onShowMenu = new tinymce.util.Dispatcher(this);
  4655 			this.onHideMenu = new tinymce.util.Dispatcher(this);
  4704 			this.onHideMenu = new tinymce.util.Dispatcher(this);
  4656 			this.classPrefix = 'mceMenu';
  4705 			this.classPrefix = 'mceMenu';
       
  4706 
       
  4707 			// Fix for odd IE bug: #1903622
       
  4708 			this.fixIE = tinymce.isIE && window.top != window;
  4657 		},
  4709 		},
  4658 
  4710 
  4659 		createMenu : function(s) {
  4711 		createMenu : function(s) {
  4660 			var t = this, cs = t.settings, m;
  4712 			var t = this, cs = t.settings, m;
  4661 
  4713 
  4741 
  4793 
  4742 			DOM.setStyles(co, {left : x , top : y});
  4794 			DOM.setStyles(co, {left : x , top : y});
  4743 			t.element.update();
  4795 			t.element.update();
  4744 
  4796 
  4745 			t.isMenuVisible = 1;
  4797 			t.isMenuVisible = 1;
  4746 			t.mouseClickFunc = Event.add(co, 'click', function(e) {
  4798 			t.mouseClickFunc = Event.add(co, t.fixIE ? 'mousedown' : 'click', function(e) {
  4747 				var m;
  4799 				var m;
  4748 
  4800 
  4749 				e = e.target;
  4801 				e = e.target;
  4750 
  4802 
  4751 				if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, 'mceMenuItemSub')) {
  4803 				if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, 'mceMenuItemSub')) {
  4803 
  4855 
  4804 			if (!t.isMenuVisible)
  4856 			if (!t.isMenuVisible)
  4805 				return;
  4857 				return;
  4806 
  4858 
  4807 			Event.remove(co, 'mouseover', t.mouseOverFunc);
  4859 			Event.remove(co, 'mouseover', t.mouseOverFunc);
  4808 			Event.remove(co, 'click', t.mouseClickFunc);
  4860 			Event.remove(co, t.fixIE ? 'mousedown' : 'click', t.mouseClickFunc);
  4809 			DOM.hide(co);
  4861 			DOM.hide(co);
  4810 			t.isMenuVisible = 0;
  4862 			t.isMenuVisible = 0;
  4811 
  4863 
  4812 			if (!c)
  4864 			if (!c)
  4813 				t.collapse(1);
  4865 				t.collapse(1);
  4886 			if (s.separator) {
  4938 			if (s.separator) {
  4887 				ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItemSeparator'});
  4939 				ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItemSeparator'});
  4888 				DOM.add(ro, 'td', {'class' : 'mceMenuItemSeparator'});
  4940 				DOM.add(ro, 'td', {'class' : 'mceMenuItemSeparator'});
  4889 
  4941 
  4890 				if (n = ro.previousSibling)
  4942 				if (n = ro.previousSibling)
  4891 					DOM.addClass(n, 'last');
  4943 					DOM.addClass(n, 'mceLast');
  4892 
  4944 
  4893 				return;
  4945 				return;
  4894 			}
  4946 			}
  4895 
  4947 
  4896 			n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItem mceMenuItemEnabled'});
  4948 			n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : 'mceMenuItem mceMenuItemEnabled'});
  4897 			n = it = DOM.add(n, 'td');
  4949 			n = it = DOM.add(n, 'td');
  4898 			n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});
  4950 			n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});
  4899 
  4951 
  4900 			DOM.addClass(it, s['class']);
  4952 			DOM.addClass(it, s['class']);
  4901 //			n = DOM.add(n, 'span', {'class' : 'item'});
  4953 //			n = DOM.add(n, 'span', {'class' : 'item'});
  4902 			DOM.add(n, 'span', {'class' : 'icon' + (s.icon ? ' ' + s.icon : '')});
  4954 			DOM.add(n, 'span', {'class' : 'mceIcon' + (s.icon ? ' mce_' + s.icon : '')});
  4903 			n = DOM.add(n, s.element || 'span', {'class' : 'text', title : o.settings.title}, o.settings.title);
  4955 			n = DOM.add(n, s.element || 'span', {'class' : 'mceText', title : o.settings.title}, o.settings.title);
  4904 
  4956 
  4905 			if (o.settings.style)
  4957 			if (o.settings.style)
  4906 				DOM.setAttrib(n, 'style', o.settings.style);
  4958 				DOM.setAttrib(n, 'style', o.settings.style);
  4907 
  4959 
  4908 			if (tb.childNodes.length == 1)
  4960 			if (tb.childNodes.length == 1)
  4909 				DOM.addClass(ro, 'first');
  4961 				DOM.addClass(ro, 'mceFirst');
  4910 
  4962 
  4911 			if ((n = ro.previousSibling) && DOM.hasClass(n, 'mceMenuItemSeparator'))
  4963 			if ((n = ro.previousSibling) && DOM.hasClass(n, 'mceMenuItemSeparator'))
  4912 				DOM.addClass(ro, 'first');
  4964 				DOM.addClass(ro, 'mceFirst');
  4913 
  4965 
  4914 			if (o.collapse)
  4966 			if (o.collapse)
  4915 				DOM.addClass(ro, 'mceMenuItemSub');
  4967 				DOM.addClass(ro, 'mceMenuItemSub');
  4916 
  4968 
  4917 			if (n = ro.previousSibling)
  4969 			if (n = ro.previousSibling)
  4918 				DOM.removeClass(n, 'last');
  4970 				DOM.removeClass(n, 'mceLast');
  4919 
  4971 
  4920 			DOM.addClass(ro, 'last');
  4972 			DOM.addClass(ro, 'mceLast');
  4921 		}
  4973 		}
  4922 
  4974 
  4923 		});
  4975 		});
  4924 })();
  4976 })();
  4925 /* file:jscripts/tiny_mce/classes/ui/Button.js */
  4977 /* file:jscripts/tiny_mce/classes/ui/Button.js */
  4935 
  4987 
  4936 		renderHTML : function() {
  4988 		renderHTML : function() {
  4937 			var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class'] + '" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">';
  4989 			var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class'] + '" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">';
  4938 
  4990 
  4939 			if (s.image)
  4991 			if (s.image)
  4940 				h += '<img class="icon" src="' + s.image + '" /></a>';
  4992 				h += '<img class="mceIcon" src="' + s.image + '" /></a>';
  4941 			else
  4993 			else
  4942 				h += '<span class="icon ' + s['class'] + '"></span></a>';
  4994 				h += '<span class="mceIcon ' + s['class'] + '"></span></a>';
  4943 
  4995 
  4944 			return h;
  4996 			return h;
  4945 		},
  4997 		},
  4946 
  4998 
  4947 		postRender : function() {
  4999 		postRender : function() {
  4992 				});
  5044 				});
  4993 
  5045 
  4994 				// If no item was found then present title
  5046 				// If no item was found then present title
  4995 				if (!fv) {
  5047 				if (!fv) {
  4996 					DOM.setHTML(e, DOM.encode(t.settings.title));
  5048 					DOM.setHTML(e, DOM.encode(t.settings.title));
  4997 					DOM.addClass(e, 'title');
  5049 					DOM.addClass(e, 'mceTitle');
  4998 					e = 0;
  5050 					e = 0;
  4999 					return;
  5051 					return;
  5000 				} else
  5052 				} else
  5001 					DOM.removeClass(e, 'title');
  5053 					DOM.removeClass(e, 'mceTitle');
  5002 			}
  5054 			}
  5003 
  5055 
  5004 			e = 0;
  5056 			e = 0;
  5005 		},
  5057 		},
  5006 
  5058 
  5023 
  5075 
  5024 		renderHTML : function() {
  5076 		renderHTML : function() {
  5025 			var h = '', t = this, s = t.settings;
  5077 			var h = '', t = this, s = t.settings;
  5026 
  5078 
  5027 			h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';
  5079 			h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';
  5028 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'text', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>';
  5080 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'mceText', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>';
  5029 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>';
  5081 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'mceOpen', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>';
  5030 			h += '</tr></tbody></table>';
  5082 			h += '</tr></tbody></table>';
  5031 
  5083 
  5032 			return h;
  5084 			return h;
  5033 		},
  5085 		},
  5034 
  5086 
  5082 		renderMenu : function() {
  5134 		renderMenu : function() {
  5083 			var t = this, m;
  5135 			var t = this, m;
  5084 
  5136 
  5085 			m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
  5137 			m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
  5086 				menu_line : 1,
  5138 				menu_line : 1,
  5087 				'class' : 'mceListBoxMenu noIcons',
  5139 				'class' : 'mceListBoxMenu mceNoIcons',
  5088 				max_width : 150,
  5140 				max_width : 150,
  5089 				max_height : 150
  5141 				max_height : 150
  5090 			});
  5142 			});
  5091 
  5143 
  5092 			m.onHideMenu.add(t.hideMenu, t);
  5144 			m.onHideMenu.add(t.hideMenu, t);
  5335 			var h, t = this, s = t.settings, h1;
  5387 			var h, t = this, s = t.settings, h1;
  5336 
  5388 
  5337 			h = '<tbody><tr>';
  5389 			h = '<tbody><tr>';
  5338 
  5390 
  5339 			if (s.image)
  5391 			if (s.image)
  5340 				h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'action ' + s['class']});
  5392 				h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'mceAction ' + s['class']});
  5341 			else
  5393 			else
  5342 				h1 = DOM.createHTML('span', {'class' : 'action ' + s['class']});
  5394 				h1 = DOM.createHTML('span', {'class' : 'mceAction ' + s['class']});
  5343 
  5395 
  5344 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_action', href : 'javascript:;', 'class' : 'action ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';
  5396 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_action', href : 'javascript:;', 'class' : 'mceAction ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';
  5345 	
  5397 	
  5346 			h1 = DOM.createHTML('span', {'class' : 'open ' + s['class']});
  5398 			h1 = DOM.createHTML('span', {'class' : 'mceOpen ' + s['class']});
  5347 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'open ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';
  5399 			h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'mceOpen ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';
  5348 
  5400 
  5349 			h += '</tr></tbody>';
  5401 			h += '</tr></tbody>';
  5350 
  5402 
  5351 			return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);
  5403 			return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);
  5352 		},
  5404 		},
  5469 				});
  5521 				});
  5470 			});
  5522 			});
  5471 
  5523 
  5472 			if (s.more_colors_func) {
  5524 			if (s.more_colors_func) {
  5473 				n = DOM.add(tb, 'tr');
  5525 				n = DOM.add(tb, 'tr');
  5474 				n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'morecolors'});
  5526 				n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'mceMoreColors'});
  5475 				n = DOM.add(n, 'a', {href : 'javascript:;', onclick : 'return false;', 'class' : 'morecolors'}, s.more_colors_title);
  5527 				n = DOM.add(n, 'a', {href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);
  5476 
  5528 
  5477 				Event.add(n, 'click', function(e) {
  5529 				Event.add(n, 'click', function(e) {
  5478 					s.more_colors_func.call(s.more_colors_scope || this);
  5530 					s.more_colors_func.call(s.more_colors_scope || this);
  5479 					return Event.cancel(e); // Cancel to fix onbeforeunload problem
  5531 					return Event.cancel(e); // Cancel to fix onbeforeunload problem
  5480 				});
  5532 				});
  5697 				}
  5749 				}
  5698 
  5750 
  5699 				switch (s.mode) {
  5751 				switch (s.mode) {
  5700 					case "exact":
  5752 					case "exact":
  5701 						l = s.elements || '';
  5753 						l = s.elements || '';
  5702 						each(l.split(','), function(v) {
  5754 
  5703 							if (DOM.get(v))
  5755 						if(l.length > 0) {
  5704 								new tinymce.Editor(v, s).render(1);
  5756 							each(l.split(','), function(v) {
  5705 							else {
  5757 								if (DOM.get(v))
  5706 								c = 0;
  5758 									new tinymce.Editor(v, s).render(1);
  5707 
  5759 								else {
  5708 								each(document.forms, function(f) {
  5760 									c = 0;
  5709 									each(f.elements, function(e) {
  5761 
  5710 										if (e.name === v) {
  5762 									each(document.forms, function(f) {
  5711 											v = 'mce_editor_' + c;
  5763 										each(f.elements, function(e) {
  5712 											DOM.setAttrib(e, 'id', v);
  5764 											if (e.name === v) {
  5713 											new tinymce.Editor(v, s).render(1);
  5765 												v = 'mce_editor_' + c;
  5714 										}
  5766 												DOM.setAttrib(e, 'id', v);
       
  5767 												new tinymce.Editor(v, s).render(1);
       
  5768 											}
       
  5769 										});
  5715 									});
  5770 									});
  5716 								});
  5771 								}
  5717 							}
  5772 							});
  5718 						});
  5773 						}
  5719 						break;
  5774 						break;
  5720 
  5775 
  5721 					case "textareas":
  5776 					case "textareas":
  5722 					case "specific_textareas":
  5777 					case "specific_textareas":
  5723 						function hasClass(n, c) {
  5778 						function hasClass(n, c) {
  5892 		tinymce.documentBaseURL += '/';
  5947 		tinymce.documentBaseURL += '/';
  5893 
  5948 
  5894 	tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
  5949 	tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
  5895 	tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
  5950 	tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
  5896 
  5951 
  5897 	if (tinymce.EditorManager.baseURI.host != document.domain)
  5952 	if (tinymce.EditorManager.baseURI.host != window.location.hostname)
  5898 		document.domain = tinymce.relaxedDomain = document.domain.replace(/.*\.(.+\..+)$/, '$1');
  5953 		document.domain = tinymce.relaxedDomain = window.location.hostname.replace(/.*\.(.+\..+)$/, '$1');
  5899 })();
  5954 })();
  5900 
  5955 
  5901 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call
  5956 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call
  5902 var tinyMCE = window.tinyMCE = tinymce.EditorManager;
  5957 var tinyMCE = window.tinyMCE = tinymce.EditorManager;
  5903 
  5958 
  5998 				valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target]',
  6053 				valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target]',
  5999 				hidden_input : 1,
  6054 				hidden_input : 1,
  6000 				padd_empty_editor : 1,
  6055 				padd_empty_editor : 1,
  6001 				render_ui : 1,
  6056 				render_ui : 1,
  6002 				init_theme : 1,
  6057 				init_theme : 1,
       
  6058 				force_p_newlines : 1,
  6003 				indentation : '30px'
  6059 				indentation : '30px'
  6004 			}, s);
  6060 			}, s);
  6005 
  6061 
  6006 			// Setup URIs
  6062 			// Setup URIs
  6007 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
  6063 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
  6013 			t.execCallback('setup', t);
  6069 			t.execCallback('setup', t);
  6014 		},
  6070 		},
  6015 
  6071 
  6016 		render : function(nst) {
  6072 		render : function(nst) {
  6017 			var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
  6073 			var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
       
  6074 
       
  6075 			// Page is not loaded yet, wait for it
       
  6076 			if (!Event.domLoaded) {
       
  6077 				Event.add(document, 'init', function() {
       
  6078 					t.render();
       
  6079 				});
       
  6080 				return;
       
  6081 			}
  6018 
  6082 
  6019 			// Force strict loading mode if render us called by user and not internally
  6083 			// Force strict loading mode if render us called by user and not internally
  6020 			if (!nst) {
  6084 			if (!nst) {
  6021 				s.strict_loading_mode = 1;
  6085 				s.strict_loading_mode = 1;
  6022 				tinyMCE.settings = s;
  6086 				tinyMCE.settings = s;
  6136 			} else
  6200 			} else
  6137 				loadScripts();
  6201 				loadScripts();
  6138 		},
  6202 		},
  6139 
  6203 
  6140 		init : function() {
  6204 		init : function() {
  6141 			var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u;
  6205 			var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;
  6142 
  6206 
  6143 			EditorManager.add(t);
  6207 			EditorManager.add(t);
  6144 
  6208 
  6145 			// Create theme
  6209 			// Create theme
  6146 			s.theme = s.theme.replace(/-/, '');
  6210 			s.theme = s.theme.replace(/-/, '');
  6200 					t.nodeChanged();
  6264 					t.nodeChanged();
  6201 			});
  6265 			});
  6202 
  6266 
  6203 			// Remove ghost selections on images and tables in Gecko
  6267 			// Remove ghost selections on images and tables in Gecko
  6204 			if (isGecko) {
  6268 			if (isGecko) {
  6205 				function repaint() {
  6269 				function repaint(a, o) {
  6206 					t.execCommand('mceRepaint');
  6270 					if (!o || !o.initial)
       
  6271 						t.execCommand('mceRepaint');
  6207 				};
  6272 				};
  6208 
  6273 
  6209 				t.onUndo.add(repaint);
  6274 				t.onUndo.add(repaint);
  6210 				t.onRedo.add(repaint);
  6275 				t.onRedo.add(repaint);
  6211 				t.onSetContent.add(repaint);
  6276 				t.onSetContent.add(repaint);
  6217 			// Measure box
  6282 			// Measure box
  6218 			if (s.render_ui) {
  6283 			if (s.render_ui) {
  6219 				w = s.width || e.style.width || e.clientWidth;
  6284 				w = s.width || e.style.width || e.clientWidth;
  6220 				h = s.height || e.style.height || e.clientHeight;
  6285 				h = s.height || e.style.height || e.clientHeight;
  6221 				t.orgDisplay = e.style.display;
  6286 				t.orgDisplay = e.style.display;
  6222 
  6287 				re = new RegExp('%|px|auto', 'gi');
  6223 				if (('' + w).indexOf('%') == -1)
  6288 
       
  6289 				if (!re.test('' + w))
  6224 					w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);
  6290 					w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);
  6225 
  6291 
  6226 				if (('' + h).indexOf('%') == -1)
  6292 				if (!re.test('' + h))
  6227 					h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
  6293 					h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
  6228 
  6294 
  6229 				// Render UI
  6295 				// Render UI
  6230 				o = t.theme.renderUI({
  6296 				o = t.theme.renderUI({
  6231 					targetNode : e,
  6297 					targetNode : e,
  6253 			t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
  6319 			t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
  6254 
  6320 
  6255 			if (tinymce.relaxedDomain)
  6321 			if (tinymce.relaxedDomain)
  6256 				t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';
  6322 				t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';
  6257 
  6323 
  6258 			t.iframeHTML += '</head><body id="tinymce" class="mceContentBody"></body></html>';
  6324 			bi = s.body_id || 'tinymce';
       
  6325 			if (bi.indexOf('=') != -1) {
       
  6326 				bi = t.getParam('body_id', '', 'hash');
       
  6327 				bi = bi[t.id] || bi;
       
  6328 			}
       
  6329 
       
  6330 			bc = s.body_class || '';
       
  6331 			if (bc.indexOf('=') != -1) {
       
  6332 				bc = t.getParam('body_class', '', 'hash');
       
  6333 				bc = bc[t.id] || '';
       
  6334 			}
       
  6335 
       
  6336 			t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';
  6259 
  6337 
  6260 			// Domain relaxing enabled, then set document domain
  6338 			// Domain relaxing enabled, then set document domain
  6261 			if (tinymce.relaxedDomain) {
  6339 			if (tinymce.relaxedDomain) {
  6262 				// We need to write the contents here in IE since multiple writes messes up refresh button and back button
  6340 				// We need to write the contents here in IE since multiple writes messes up refresh button and back button
  6263 				if (isIE)
  6341 				if (isIE)
  6264 					u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + s.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';
  6342 					u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';
  6265 				else if (tinymce.isOpera)
  6343 				else if (tinymce.isOpera)
  6266 					u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';					
  6344 					u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';					
  6267 			}
  6345 			}
  6268 
  6346 
  6269 			// Create iframe
  6347 			// Create iframe
  6270 			n = DOM.add(o.iframeContainer, 'iframe', {
  6348 			n = DOM.add(o.iframeContainer, 'iframe', {
  6271 				id : s.id + "_ifr",
  6349 				id : t.id + "_ifr",
  6272 				src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7
  6350 				src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7
  6273 				frameBorder : '0',
  6351 				frameBorder : '0',
  6274 				style : {
  6352 				style : {
  6275 					width : '100%',
  6353 					width : '100%',
  6276 					height : h
  6354 					height : h
  6277 				}
  6355 				}
  6278 			});
  6356 			});
  6279 
  6357 
  6280 			t.contentAreaContainer = o.iframeContainer;
  6358 			t.contentAreaContainer = o.iframeContainer;
  6281 			DOM.get(o.editorContainer).style.display = t.orgDisplay;
  6359 			DOM.get(o.editorContainer).style.display = t.orgDisplay;
  6282 			DOM.get(s.id).style.display = 'none';
  6360 			DOM.get(t.id).style.display = 'none';
  6283 
  6361 
  6284 			// Safari 2.x requires us to wait for the load event and load a real HTML doc
  6362 			// Safari 2.x requires us to wait for the load event and load a real HTML doc
  6285 			if (tinymce.isOldWebKit) {
  6363 			if (tinymce.isOldWebKit) {
  6286 				Event.add(n, 'load', t.setupIframe, t);
  6364 				Event.add(n, 'load', t.setupIframe, t);
  6287 				n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
  6365 				n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
  6292 				e = n = o = null; // Cleanup
  6370 				e = n = o = null; // Cleanup
  6293 			}
  6371 			}
  6294 		},
  6372 		},
  6295 
  6373 
  6296 		setupIframe : function() {
  6374 		setupIframe : function() {
  6297 			var t = this, s = t.settings, e = DOM.get(s.id), d = t.getDoc(), h;
  6375 			var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h;
  6298 
  6376 
  6299 			// Setup iframe body
  6377 			// Setup iframe body
  6300 			if (!isIE || !tinymce.relaxedDomain) {
  6378 			if (!isIE || !tinymce.relaxedDomain) {
  6301 				d.open();
  6379 				d.open();
  6302 				d.write(t.iframeHTML);
  6380 				d.write(t.iframeHTML);
  6636 
  6714 
  6637 		getLang : function(n, dv) {
  6715 		getLang : function(n, dv) {
  6638 			return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');
  6716 			return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');
  6639 		},
  6717 		},
  6640 
  6718 
  6641 		getParam : function(n, dv) {
  6719 		getParam : function(n, dv, ty) {
  6642 			return is(this.settings[n]) ? this.settings[n] : dv;
  6720 			var tr = tinymce.trim, v = is(this.settings[n]) ? this.settings[n] : dv, o;
       
  6721 
       
  6722 			if (ty === 'hash') {
       
  6723 				o = {};
       
  6724 
       
  6725 				if (is(v, 'string')) {
       
  6726 					each(v.split(/[;,]/), function(v) {
       
  6727 						v = v.split('=');
       
  6728 
       
  6729 						if (v.length > 1)
       
  6730 							o[tr(v[0])] = tr(v[1]);
       
  6731 						else
       
  6732 							o[tr(v[0])] = tr(v);
       
  6733 					});
       
  6734 				} else
       
  6735 					o = v;
       
  6736 
       
  6737 				return o;
       
  6738 			}
       
  6739 
       
  6740 			return v;
  6643 		},
  6741 		},
  6644 
  6742 
  6645 		nodeChanged : function(o) {
  6743 		nodeChanged : function(o) {
  6646 			var t = this, s = t.selection, n = s.getNode() || t.getBody();
  6744 			var t = this, s = t.selection, n = s.getNode() || t.getBody();
  6647 
  6745 
  6798 			o = t.editorCommands.queryCommandState(c);
  6896 			o = t.editorCommands.queryCommandState(c);
  6799 			if (o !== -1)
  6897 			if (o !== -1)
  6800 				return o;
  6898 				return o;
  6801 
  6899 
  6802 			// Browser commands
  6900 			// Browser commands
  6803 			return this.getDoc().queryCommandState(c);
  6901 			try {
       
  6902 				return this.getDoc().queryCommandState(c);
       
  6903 			} catch (ex) {
       
  6904 				// Fails sometimes see bug: 1896577
       
  6905 			}
  6804 		},
  6906 		},
  6805 
  6907 
  6806 		queryCommandValue : function(c) {
  6908 		queryCommandValue : function(c) {
  6807 			var t = this, o;
  6909 			var t = this, o;
  6808 
  6910 
  6818 			o = t.editorCommands.queryCommandValue(c);
  6920 			o = t.editorCommands.queryCommandValue(c);
  6819 			if (is(o))
  6921 			if (is(o))
  6820 				return o;
  6922 				return o;
  6821 
  6923 
  6822 			// Browser commands
  6924 			// Browser commands
  6823 			return this.getDoc().queryCommandValue(c);
  6925 			try {
       
  6926 				return this.getDoc().queryCommandValue(c);
       
  6927 			} catch (ex) {
       
  6928 				// Fails sometimes see bug: 1896577
       
  6929 			}
  6824 		},
  6930 		},
  6825 
  6931 
  6826 		show : function() {
  6932 		show : function() {
  6827 			var t = this;
  6933 			var t = this;
  6828 
  6934 
  6830 			DOM.hide(t.id);
  6936 			DOM.hide(t.id);
  6831 			t.load();
  6937 			t.load();
  6832 		},
  6938 		},
  6833 
  6939 
  6834 		hide : function() {
  6940 		hide : function() {
  6835 			var t = this, s = t.settings, d = t.getDoc();
  6941 			var t = this, d = t.getDoc();
  6836 
  6942 
  6837 			// Fixed bug where IE has a blinking cursor left from the editor
  6943 			// Fixed bug where IE has a blinking cursor left from the editor
  6838 			if (isIE && d)
  6944 			if (isIE && d)
  6839 				d.execCommand('SelectAll');
  6945 				d.execCommand('SelectAll');
  6840 
  6946 
       
  6947 			// We must save before we hide so Safari doesn't crash
       
  6948 			t.save();
  6841 			DOM.hide(t.getContainer());
  6949 			DOM.hide(t.getContainer());
  6842 			DOM.setStyle(s.id, 'display', t.orgDisplay);
  6950 			DOM.setStyle(t.id, 'display', t.orgDisplay);
  6843 			t.save();
       
  6844 		},
  6951 		},
  6845 
  6952 
  6846 		isHidden : function() {
  6953 		isHidden : function() {
  6847 			return !DOM.isHidden(this.id);
  6954 			return !DOM.isHidden(this.id);
  6848 		},
  6955 		},
  6860 			t.hide();
  6967 			t.hide();
  6861 			DOM.remove(t.getContainer());
  6968 			DOM.remove(t.getContainer());
  6862 
  6969 
  6863 			t.execCallback('remove_instance_callback', t);
  6970 			t.execCallback('remove_instance_callback', t);
  6864 			t.onRemove.dispatch(t);
  6971 			t.onRemove.dispatch(t);
       
  6972 
       
  6973 			// Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command
       
  6974 			t.onExecCommand.listeners = [];
  6865 
  6975 
  6866 			EditorManager.remove(t);
  6976 			EditorManager.remove(t);
  6867 		},
  6977 		},
  6868 
  6978 
  6869 		resizeToContent : function() {
  6979 		resizeToContent : function() {
  7038 
  7148 
  7039 			// Use callback instead
  7149 			// Use callback instead
  7040 			if (s.urlconverter_callback)
  7150 			if (s.urlconverter_callback)
  7041 				return t.execCallback('urlconverter_callback', u, e, true, n);
  7151 				return t.execCallback('urlconverter_callback', u, e, true, n);
  7042 
  7152 
  7043 			// Don't convert link href since thats the CSS files that gets loaded into the editor
  7153 			// Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs
  7044 			if (!s.convert_urls || (e && e.nodeName == 'LINK'))
  7154 			if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0)
  7045 				return u;
  7155 				return u;
  7046 
  7156 
  7047 			// Convert to relative
  7157 			// Convert to relative
  7048 			if (s.relative_urls)
  7158 			if (s.relative_urls)
  7049 				return t.documentBaseURI.toRelative(u);
  7159 				return t.documentBaseURI.toRelative(u);
  7530 
  7640 
  7531 			t.destroyed = 1;
  7641 			t.destroyed = 1;
  7532 		},
  7642 		},
  7533 
  7643 
  7534 		_convertInlineElements : function() {
  7644 		_convertInlineElements : function() {
  7535 			var t = this, s = t.settings, dom = t.dom, v;
  7645 			var t = this, s = t.settings, dom = t.dom, v, e, na, st, sp;
  7536 
  7646 
  7537 			function convert(ed, o) {
  7647 			function convert(ed, o) {
  7538 				if (!s.inline_styles)
  7648 				if (!s.inline_styles)
  7539 					return;
  7649 					return;
  7540 
  7650 
  7547 									dom.setAttrib(n, 'height', '');
  7657 									dom.setAttrib(n, 'height', '');
  7548 								}
  7658 								}
  7549 								break;
  7659 								break;
  7550 
  7660 
  7551 							case 'U':
  7661 							case 'U':
  7552 								dom.replace(dom.create('span', {style : 'text-decoration: underline;'}), n, 1);
       
  7553 								break;
       
  7554 
       
  7555 							case 'STRIKE':
  7662 							case 'STRIKE':
  7556 								dom.replace(dom.create('span', {style : 'text-decoration: line-through;'}), n, 1);
  7663 								sp = dom.create('span', {style : dom.getAttrib(n, 'style')});
       
  7664 								sp.style.textDecoration = n.nodeName == 'U' ? 'underline' : 'line-through';
       
  7665 								dom.setAttrib(sp, 'mce_style', '');
       
  7666 								dom.replace(sp, n, 1);
  7557 								break;
  7667 								break;
  7558 						}
  7668 						}
  7559 					});
  7669 					});
  7560 				} else if (o.set) {
  7670 				} else if (o.set) {
  7561 					each(t.dom.select('table,span', o.node), function(n) {
  7671 					each(t.dom.select('table,span', o.node), function(n) {
  7563 							if (v = dom.getStyle(n, 'height'))
  7673 							if (v = dom.getStyle(n, 'height'))
  7564 								dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));
  7674 								dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));
  7565 						} else {
  7675 						} else {
  7566 							// Convert spans to elements
  7676 							// Convert spans to elements
  7567 							if (n.style.textDecoration == 'underline')
  7677 							if (n.style.textDecoration == 'underline')
  7568 								dom.replace(dom.create('u'), n, 1);
  7678 								na = 'u';
  7569 							else if (n.style.textDecoration == 'line-through')
  7679 							else if (n.style.textDecoration == 'line-through')
  7570 								dom.replace(dom.create('strike'), n, 1);
  7680 								na = 'strike';
       
  7681 							else
       
  7682 								na = '';
       
  7683 
       
  7684 							if (na) {
       
  7685 								n.style.textDecoration = '';
       
  7686 								dom.setAttrib(n, 'mce_style', '');
       
  7687 
       
  7688 								e = dom.create(na, {
       
  7689 									style : dom.getAttrib(n, 'style')
       
  7690 								});
       
  7691 
       
  7692 								dom.replace(e, n, 1);
       
  7693 							}
  7571 						}
  7694 						}
  7572 					});
  7695 					});
  7573 				}
  7696 				}
  7574 			};
  7697 			};
  7575 
  7698 
  7581 				});
  7704 				});
  7582 			}
  7705 			}
  7583 		},
  7706 		},
  7584 
  7707 
  7585 		_convertFonts : function() {
  7708 		_convertFonts : function() {
  7586 			var t = this, s = t.settings, dom = t.dom, sl, cl, fz, fzn, v, i, st;
  7709 			var t = this, s = t.settings, dom = t.dom, sl, cl, fz, fzn, v, i, st, x, nl, sp, f, n;
  7587 
  7710 
  7588 			// No need
  7711 			// No need
  7589 			if (!s.inline_styles)
  7712 			if (!s.inline_styles)
  7590 				return;
  7713 				return;
  7591 
  7714 
  7602 			function convertToFonts(no) {
  7725 			function convertToFonts(no) {
  7603 				// Convert spans to fonts on non WebKit browsers
  7726 				// Convert spans to fonts on non WebKit browsers
  7604 				if (tinymce.isWebKit || !s.inline_styles)
  7727 				if (tinymce.isWebKit || !s.inline_styles)
  7605 					return;
  7728 					return;
  7606 
  7729 
  7607 				each(t.dom.select('span', no), function(n) {
  7730 				nl = t.dom.select('span', no);
  7608 					var f = dom.create('font', {
  7731 				for (x = nl.length - 1; x >= 0; x--) {
       
  7732 					n = nl[x];
       
  7733 
       
  7734 					f = dom.create('font', {
  7609 						color : dom.toHex(dom.getStyle(n, 'color')),
  7735 						color : dom.toHex(dom.getStyle(n, 'color')),
  7610 						face : dom.getStyle(n, 'fontFamily'),
  7736 						face : dom.getStyle(n, 'fontFamily'),
  7611 						style : dom.getAttrib(n, 'style')
  7737 						style : dom.getAttrib(n, 'style')
  7612 					});
  7738 					});
  7613 
  7739 
  7637 					if (f.color || f.face || f.size) {
  7763 					if (f.color || f.face || f.size) {
  7638 						f.style.fontFamily = '';
  7764 						f.style.fontFamily = '';
  7639 						dom.setAttrib(f, 'mce_style', '');
  7765 						dom.setAttrib(f, 'mce_style', '');
  7640 						dom.replace(f, n, 1);
  7766 						dom.replace(f, n, 1);
  7641 					}
  7767 					}
  7642 				});
  7768 				}
  7643 			};
  7769 			};
  7644 
  7770 
  7645 			// Run on setup
  7771 			// Run on setup
  7646 			t.onSetContent.add(function(ed, o) {
  7772 			t.onSetContent.add(function(ed, o) {
  7647 				if (o.initial)
  7773 				convertToFonts(ed.getBody());
  7648 					convertToFonts(ed.getBody());
       
  7649 			});
  7774 			});
  7650 
  7775 
  7651 			// Run on cleanup
  7776 			// Run on cleanup
  7652 			t.onPreProcess.add(function(ed, o) {
  7777 			t.onPreProcess.add(function(ed, o) {
  7653 				// Keep unit tests happy
  7778 				// Keep unit tests happy
  7654 				if (!s.inline_styles)
  7779 				if (!s.inline_styles)
  7655 					return;
  7780 					return;
  7656 
  7781 
  7657 				if (o.get) {
  7782 				if (o.get) {
  7658 					each(t.dom.select('font', o.node), function(n) {
  7783 					nl = t.dom.select('font', o.node);
  7659 						var sp = dom.create('span', {
  7784 					for (x = nl.length - 1; x >= 0; x--) {
       
  7785 						n = nl[x];
       
  7786 
       
  7787 						sp = dom.create('span', {
  7660 							style : dom.getAttrib(n, 'style')
  7788 							style : dom.getAttrib(n, 'style')
  7661 						});
  7789 						});
  7662 
  7790 
  7663 						dom.setStyles(sp, {
  7791 						dom.setStyles(sp, {
  7664 							fontFamily : dom.getAttrib(n, 'face'),
  7792 							fontFamily : dom.getAttrib(n, 'face'),
  7673 								dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);
  7801 								dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);
  7674 						}
  7802 						}
  7675 
  7803 
  7676 						dom.setAttrib(sp, 'mce_style', '');
  7804 						dom.setAttrib(sp, 'mce_style', '');
  7677 						dom.replace(sp, n, 1);
  7805 						dom.replace(sp, n, 1);
  7678 					});
  7806 					}
  7679 				} else if (o.set)
  7807 				}
  7680 					convertToFonts(o.node);
       
  7681 			});
  7808 			});
  7682 		},
  7809 		},
  7683 
  7810 
  7684 		_isHidden : function() {
  7811 		_isHidden : function() {
  7685 			var s;
  7812 			var s;
  8465 		queryStatemceBlockQuote : function() {
  8592 		queryStatemceBlockQuote : function() {
  8466 			return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});
  8593 			return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});
  8467 		},
  8594 		},
  8468 
  8595 
  8469 		mceBlockQuote : function() {
  8596 		mceBlockQuote : function() {
       
  8597 			var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;
       
  8598 
       
  8599 			function getBQ(e) {
       
  8600 				return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
       
  8601 			};
       
  8602 
       
  8603 			// Get start/end block
       
  8604 			sb = dom.getParent(s.getStart(), dom.isBlock);
       
  8605 			eb = dom.getParent(s.getEnd(), dom.isBlock);
       
  8606 
       
  8607 			// Remove blockquote(s)
       
  8608 			if (bq = getBQ(sb)) {
       
  8609 				if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
       
  8610 					bm = s.getBookmark();
       
  8611 
       
  8612 				// Move all elements after the end block into new bq
       
  8613 				if (getBQ(eb)) {
       
  8614 					bq2 = bq.cloneNode(false);
       
  8615 
       
  8616 					while (n = eb.nextSibling)
       
  8617 						bq2.appendChild(n.parentNode.removeChild(n));
       
  8618 				}
       
  8619 
       
  8620 				// Add new bq after
       
  8621 				if (bq2)
       
  8622 					dom.insertAfter(bq2, bq);
       
  8623 
       
  8624 				// Move all selected blocks after the current bq
       
  8625 				nl = t._getSelectedBlocks(sb, eb);
       
  8626 				for (i = nl.length - 1; i >= 0; i--) {
       
  8627 					dom.insertAfter(nl[i], bq);
       
  8628 				}
       
  8629 
       
  8630 				// Empty bq, then remove it
       
  8631 				if (/^\s*$/.test(bq.innerHTML))
       
  8632 					dom.remove(bq, 1); // Keep children so boomark restoration works correctly
       
  8633 
       
  8634 				// Empty bq, then remote it
       
  8635 				if (bq2 && /^\s*$/.test(bq2.innerHTML))
       
  8636 					dom.remove(bq2, 1); // Keep children so boomark restoration works correctly
       
  8637 
       
  8638 				if (!bm) {
       
  8639 					// Move caret inside empty block element
       
  8640 					if (!isIE) {
       
  8641 						r = ed.getDoc().createRange();
       
  8642 						r.setStart(sb, 0);
       
  8643 						r.setEnd(sb, 0);
       
  8644 						s.setRng(r);
       
  8645 					} else {
       
  8646 						s.select(sb);
       
  8647 						s.collapse(0);
       
  8648 
       
  8649 						// IE misses the empty block some times element so we must move back the caret
       
  8650 						if (dom.getParent(s.getStart(), dom.isBlock) != sb) {
       
  8651 							r = s.getRng();
       
  8652 							r.move('character', -1);
       
  8653 							r.select();
       
  8654 						}
       
  8655 					}
       
  8656 				} else
       
  8657 					t.editor.selection.moveToBookmark(bm);
       
  8658 
       
  8659 				return;
       
  8660 			}
       
  8661 
       
  8662 			// Since IE can start with a totally empty document we need to add the first bq and paragraph
       
  8663 			if (isIE && !sb && !eb) {
       
  8664 				t.editor.getDoc().execCommand('Indent');
       
  8665 				n = getBQ(s.getNode());
       
  8666 				n.style.margin = n.dir = ''; // IE adds margin and dir to bq
       
  8667 				return;
       
  8668 			}
       
  8669 
       
  8670 			if (!sb || !eb)
       
  8671 				return;
       
  8672 
       
  8673 			// If empty paragraph node then do not use bookmark
       
  8674 			if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))
       
  8675 				bm = s.getBookmark();
       
  8676 
       
  8677 			// Move selected block elements into a bq
       
  8678 			each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {
       
  8679 				// Found existing BQ add to this one
       
  8680 				if (e.nodeName == 'BLOCKQUOTE' && !bq) {
       
  8681 					bq = e;
       
  8682 					return;
       
  8683 				}
       
  8684 
       
  8685 				// No BQ found, create one
       
  8686 				if (!bq) {
       
  8687 					bq = dom.create('blockquote');
       
  8688 					e.parentNode.insertBefore(bq, e);
       
  8689 				}
       
  8690 
       
  8691 				// Add children from existing BQ
       
  8692 				if (e.nodeName == 'BLOCKQUOTE' && bq) {
       
  8693 					n = e.firstChild;
       
  8694 
       
  8695 					while (n) {
       
  8696 						bq.appendChild(n.cloneNode(true));
       
  8697 						n = n.nextSibling;
       
  8698 					}
       
  8699 
       
  8700 					dom.remove(e);
       
  8701 					return;
       
  8702 				}
       
  8703 
       
  8704 				// Add non BQ element to BQ
       
  8705 				bq.appendChild(dom.remove(e));
       
  8706 			});
       
  8707 
       
  8708 			if (!bm) {
       
  8709 				// Move caret inside empty block element
       
  8710 				if (!isIE) {
       
  8711 					r = ed.getDoc().createRange();
       
  8712 					r.setStart(sb, 0);
       
  8713 					r.setEnd(sb, 0);
       
  8714 					s.setRng(r);
       
  8715 				} else {
       
  8716 					s.select(sb);
       
  8717 					s.collapse(1);
       
  8718 				}
       
  8719 			} else
       
  8720 				s.moveToBookmark(bm);
       
  8721 		},
       
  8722 /*
       
  8723 		_mceBlockQuote : function() {
  8470 			var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;
  8724 			var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;
  8471 
  8725 
  8472 			function findBQ(e) {
  8726 			function findBQ(e) {
  8473 				return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
  8727 				return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});
  8474 			};
  8728 			};
  8518 				bq.appendChild(dom.remove(e));
  8772 				bq.appendChild(dom.remove(e));
  8519 			});
  8773 			});
  8520 
  8774 
  8521 			t.editor.selection.moveToBookmark(b);
  8775 			t.editor.selection.moveToBookmark(b);
  8522 		},
  8776 		},
  8523 
  8777 */
  8524 		_getSelectedBlocks : function(st, en) {
  8778 		_getSelectedBlocks : function(st, en) {
  8525 			var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];
  8779 			var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];
  8526 
  8780 
  8527 			sb = dom.getParent(st || s.getStart(), dom.isBlock);
  8781 			sb = dom.getParent(st || s.getStart(), dom.isBlock);
  8528 			eb = dom.getParent(en || s.getEnd(), dom.isBlock);
  8782 			eb = dom.getParent(en || s.getEnd(), dom.isBlock);
  8586 				t.data.length--;
  8840 				t.data.length--;
  8587 				t.index = t.data.length;
  8841 				t.index = t.data.length;
  8588 			}
  8842 			}
  8589 		}
  8843 		}
  8590 
  8844 
  8591 		if (s.custom_undo_redo_restore_selection)
  8845 		if (s.custom_undo_redo_restore_selection && !l.initial)
  8592 			l.bookmark = b = l.bookmark || ed.selection.getBookmark();
  8846 			l.bookmark = b = l.bookmark || ed.selection.getBookmark();
  8593 
  8847 
  8594 		if (t.index < t.data.length && t.data[t.index].initial)
  8848 		if (t.index < t.data.length && t.data[t.index].initial)
  8595 			t.index++;
  8849 			t.index++;
  8596 
  8850 
  8688 	each = tinymce.each;
  8942 	each = tinymce.each;
  8689 	extend = tinymce.extend;
  8943 	extend = tinymce.extend;
  8690 
  8944 
  8691 	tinymce.create('tinymce.ForceBlocks', {
  8945 	tinymce.create('tinymce.ForceBlocks', {
  8692 		ForceBlocks : function(ed) {
  8946 		ForceBlocks : function(ed) {
  8693 			var t = this, s, elm;
  8947 			var t = this, s = ed.settings, elm;
  8694 
  8948 
  8695 			t.editor = ed;
  8949 			t.editor = ed;
  8696 			t.dom = ed.dom;
  8950 			t.dom = ed.dom;
  8697 
       
  8698 			// Default settings
       
  8699 			t.settings = s = extend({
       
  8700 				forced_root_block : 'p',
       
  8701 				force_p_newlines : true
       
  8702 			}, ed.settings);
       
  8703 
       
  8704 			elm = (s.forced_root_block || 'p').toLowerCase();
  8951 			elm = (s.forced_root_block || 'p').toLowerCase();
  8705 			s.element = elm.toUpperCase();
  8952 			s.element = elm.toUpperCase();
  8706 
  8953 
  8707 			ed.onPreInit.add(t.setup, t);
  8954 			ed.onPreInit.add(t.setup, t);
  8708 
  8955 
  8736 				ed.onBeforeGetContent.add(t.forceRoots, t);
  8983 				ed.onBeforeGetContent.add(t.forceRoots, t);
  8737 			}
  8984 			}
  8738 		},
  8985 		},
  8739 
  8986 
  8740 		setup : function() {
  8987 		setup : function() {
  8741 			var t = this, ed = t.editor, s = t.settings;
  8988 			var t = this, ed = t.editor, s = ed.settings;
  8742 
  8989 
  8743 			// Force root blocks when typing and when getting output
  8990 			// Force root blocks when typing and when getting output
  8744 			if (s.forced_root_block) {
  8991 			if (s.forced_root_block) {
  8745 				ed.onKeyUp.add(t.forceRoots, t);
  8992 				ed.onKeyUp.add(t.forceRoots, t);
  8746 				ed.onPreProcess.add(t.forceRoots, t);
  8993 				ed.onPreProcess.add(t.forceRoots, t);
  8895 									si = sp - bp;
  9142 									si = sp - bp;
  8896 									ei = le;
  9143 									ei = le;
  8897 								}
  9144 								}
  8898 							}
  9145 							}
  8899 
  9146 
  8900 							bl = ed.dom.create(t.settings.forced_root_block);
  9147 							bl = ed.dom.create(ed.settings.forced_root_block);
  8901 							bl.appendChild(nx.cloneNode(1));
  9148 							bl.appendChild(nx.cloneNode(1));
  8902 							nx.parentNode.replaceChild(bl, nx);
  9149 							nx.parentNode.replaceChild(bl, nx);
  8903 						}
  9150 						}
  8904 					} else {
  9151 					} else {
  8905 						if (bl.hasChildNodes())
  9152 						if (bl.hasChildNodes())
  8912 			}
  9159 			}
  8913 
  9160 
  8914 			// Restore selection
  9161 			// Restore selection
  8915 			if (si != -2) {
  9162 			if (si != -2) {
  8916 				if (!isIE) {
  9163 				if (!isIE) {
  8917 					bl = d.getElementsByTagName(t.settings.element)[0];
  9164 					bl = d.getElementsByTagName(ed.settings.element)[0];
  8918 					r = d.createRange();
  9165 					r = d.createRange();
  8919 
  9166 
  8920 					// Select last location or generated block
  9167 					// Select last location or generated block
  8921 					if (si != -1)
  9168 					if (si != -1)
  8922 						r.setStart(t.find(b, 1, si), so);
  9169 						r.setStart(t.find(b, 1, si), so);
  8953 
  9200 
  8954 			return d.getParent(n, d.isBlock);
  9201 			return d.getParent(n, d.isBlock);
  8955 		},
  9202 		},
  8956 
  9203 
  8957 		insertPara : function(e) {
  9204 		insertPara : function(e) {
  8958 			var t = this, ed = t.editor, d = ed.getDoc(), se = t.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
  9205 			var t = this, ed = t.editor, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
  8959 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n;
  9206 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n;
  8960 
  9207 
  8961 			function isEmpty(n) {
  9208 			function isEmpty(n) {
  8962 				n = n.innerHTML;
  9209 				n = n.innerHTML;
  8963 				n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
  9210 				n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
  9151 			// The caret sometimes gets stuck in Gecko if you delete empty paragraphs
  9398 			// The caret sometimes gets stuck in Gecko if you delete empty paragraphs
  9152 			// This workaround removes the element by hand and moves the caret to the previous element
  9399 			// This workaround removes the element by hand and moves the caret to the previous element
  9153 			if (sc && ed.dom.isBlock(sc) && bs) {
  9400 			if (sc && ed.dom.isBlock(sc) && bs) {
  9154 				if (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR') {
  9401 				if (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR') {
  9155 					n = sc.previousSibling;
  9402 					n = sc.previousSibling;
  9156 					if (n) { 
  9403 					if (n) {
  9157 						ed.dom.remove(sc);
  9404 						ed.dom.remove(sc);
  9158 						se.select(n, 1);
  9405 						se.select(n.firstChild);
  9159 						se.collapse(0);
  9406 						se.collapse(0);
  9160 						return Event.cancel(e);
  9407 						return Event.cancel(e);
  9161 					}
  9408 					}
  9162 				}
  9409 				}
  9163 			}
  9410 			}
  9264 
  9511 
  9265 			return t.add(c);
  9512 			return t.add(c);
  9266 		},
  9513 		},
  9267 
  9514 
  9268 		createDropMenu : function(id, s) {
  9515 		createDropMenu : function(id, s) {
  9269 			var t = this, ed = t.editor, c, bm;
  9516 			var t = this, ed = t.editor, c, bm, v;
  9270 
  9517 
  9271 			s = extend({
  9518 			s = extend({
  9272 				'class' : 'mceDropDown'
  9519 				'class' : 'mceDropDown'
  9273 			}, s);
  9520 			}, s);
  9274 
  9521 
  9275 			s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';
  9522 			s['class'] = s['class'] + ' ' + ed.getParam('skin') + 'Skin';
       
  9523 			if (v = ed.getParam('skin_variant'))
       
  9524 				s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);
  9276 
  9525 
  9277 			id = t.prefix + id;
  9526 			id = t.prefix + id;
  9278 			c = t.controls[id] = new tinymce.ui.DropMenu(id, s);
  9527 			c = t.controls[id] = new tinymce.ui.DropMenu(id, s);
  9279 			c.onAddItem.add(function(c, o) {
  9528 			c.onAddItem.add(function(c, o) {
  9280 				var s = o.settings;
  9529 				var s = o.settings;
  9327 				};
  9576 				};
  9328 			}
  9577 			}
  9329 
  9578 
  9330 			s = extend({
  9579 			s = extend({
  9331 				title : s.title,
  9580 				title : s.title,
  9332 				'class' : id,
  9581 				'class' : 'mce_' + id,
  9333 				scope : s.scope,
  9582 				scope : s.scope,
  9334 				control_manager : t
  9583 				control_manager : t
  9335 			}, s);
  9584 			}, s);
  9336 
  9585 
  9337 			id = t.prefix + id;
  9586 			id = t.prefix + id;
  9380 				};
  9629 				};
  9381 			}
  9630 			}
  9382 
  9631 
  9383 			s = extend({
  9632 			s = extend({
  9384 				title : s.title,
  9633 				title : s.title,
  9385 				'class' : id,
  9634 				'class' : 'mce_' + id,
  9386 				unavailable_prefix : ed.getLang('unavailable', ''),
  9635 				unavailable_prefix : ed.getLang('unavailable', ''),
  9387 				scope : s.scope,
  9636 				scope : s.scope,
  9388 				control_manager : t
  9637 				control_manager : t
  9389 			}, s);
  9638 			}, s);
  9390 
  9639 
  9427 				};
  9676 				};
  9428 			}
  9677 			}
  9429 
  9678 
  9430 			s = extend({
  9679 			s = extend({
  9431 				title : s.title,
  9680 				title : s.title,
  9432 				'class' : id,
  9681 				'class' : 'mce_' + id,
  9433 				scope : s.scope,
  9682 				scope : s.scope,
  9434 				control_manager : t
  9683 				control_manager : t
  9435 			}, s);
  9684 			}, s);
  9436 
  9685 
  9437 			id = t.prefix + id;
  9686 			id = t.prefix + id;
  9462 				};
  9711 				};
  9463 			}
  9712 			}
  9464 
  9713 
  9465 			s = extend({
  9714 			s = extend({
  9466 				title : s.title,
  9715 				title : s.title,
  9467 				'class' : id,
  9716 				'class' : 'mce_' + id,
  9468 				'menu_class' : ed.getParam('skin') + 'Skin',
  9717 				'menu_class' : ed.getParam('skin') + 'Skin',
  9469 				scope : s.scope,
  9718 				scope : s.scope,
  9470 				more_colors_title : ed.getLang('more_colors')
  9719 				more_colors_title : ed.getLang('more_colors')
  9471 			}, s);
  9720 			}, s);
  9472 
  9721