web/wp-includes/js/tinymce/themes/advanced/editor_template_src.js
changeset 204 09a1c134465b
parent 194 32102edaa81b
equal deleted inserted replaced
203:f507feede89a 204:09a1c134465b
     8  * Contributing: http://tinymce.moxiecode.com/contributing
     8  * Contributing: http://tinymce.moxiecode.com/contributing
     9  */
     9  */
    10 
    10 
    11 (function(tinymce) {
    11 (function(tinymce) {
    12 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode;
    12 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode;
       
    13 
       
    14 	// Generates a preview for a format
       
    15 	function getPreviewCss(ed, fmt) {
       
    16 		var name, previewElm, dom = ed.dom, previewCss = '', parentFontSize, previewStylesName;
       
    17 
       
    18 		previewStyles = ed.settings.preview_styles;
       
    19 
       
    20 		// No preview forced
       
    21 		if (previewStyles === false)
       
    22 			return '';
       
    23 
       
    24 		// Default preview
       
    25 		if (!previewStyles)
       
    26 			previewStyles = 'font-family font-size font-weight text-decoration text-transform color background-color';
       
    27 
       
    28 		// Removes any variables since these can't be previewed
       
    29 		function removeVars(val) {
       
    30 			return val.replace(/%(\w+)/g, '');
       
    31 		};
       
    32 
       
    33 		// Create block/inline element to use for preview
       
    34 		name = fmt.block || fmt.inline || 'span';
       
    35 		previewElm = dom.create(name);
       
    36 
       
    37 		// Add format styles to preview element
       
    38 		each(fmt.styles, function(value, name) {
       
    39 			value = removeVars(value);
       
    40 
       
    41 			if (value)
       
    42 				dom.setStyle(previewElm, name, value);
       
    43 		});
       
    44 
       
    45 		// Add attributes to preview element
       
    46 		each(fmt.attributes, function(value, name) {
       
    47 			value = removeVars(value);
       
    48 
       
    49 			if (value)
       
    50 				dom.setAttrib(previewElm, name, value);
       
    51 		});
       
    52 
       
    53 		// Add classes to preview element
       
    54 		each(fmt.classes, function(value) {
       
    55 			value = removeVars(value);
       
    56 
       
    57 			if (!dom.hasClass(previewElm, value))
       
    58 				dom.addClass(previewElm, value);
       
    59 		});
       
    60 
       
    61 		// Add the previewElm outside the visual area
       
    62 		dom.setStyles(previewElm, {position: 'absolute', left: -0xFFFF});
       
    63 		ed.getBody().appendChild(previewElm);
       
    64 
       
    65 		// Get parent container font size so we can compute px values out of em/% for older IE:s
       
    66 		parentFontSize = dom.getStyle(ed.getBody(), 'fontSize', true);
       
    67 		parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0;
       
    68 
       
    69 		each(previewStyles.split(' '), function(name) {
       
    70 			var value = dom.getStyle(previewElm, name, true);
       
    71 
       
    72 			// If background is transparent then check if the body has a background color we can use
       
    73 			if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
       
    74 				value = dom.getStyle(ed.getBody(), name, true);
       
    75 
       
    76 				// Ignore white since it's the default color, not the nicest fix
       
    77 				if (dom.toHex(value).toLowerCase() == '#ffffff') {
       
    78 					return;
       
    79 				}
       
    80 			}
       
    81 
       
    82 			// Old IE won't calculate the font size so we need to do that manually
       
    83 			if (name == 'font-size') {
       
    84 				if (/em|%$/.test(value)) {
       
    85 					if (parentFontSize === 0) {
       
    86 						return;
       
    87 					}
       
    88 
       
    89 					// Convert font size from em/% to px
       
    90 					value = parseFloat(value, 10) / (/%$/.test(value) ? 100 : 1);
       
    91 					value = (value * parentFontSize) + 'px';
       
    92 				}
       
    93 			}
       
    94 
       
    95 			previewCss += name + ':' + value + ';';
       
    96 		});
       
    97 
       
    98 		dom.remove(previewElm);
       
    99 
       
   100 		return previewCss;
       
   101 	};
    13 
   102 
    14 	// Tell it to load theme specific language pack(s)
   103 	// Tell it to load theme specific language pack(s)
    15 	tinymce.ThemeManager.requireLangPack('advanced');
   104 	tinymce.ThemeManager.requireLangPack('advanced');
    16 
   105 
    17 	tinymce.create('tinymce.themes.AdvancedTheme', {
   106 	tinymce.create('tinymce.themes.AdvancedTheme', {
    59 
   148 
    60 		stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'],
   149 		stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'],
    61 
   150 
    62 		init : function(ed, url) {
   151 		init : function(ed, url) {
    63 			var t = this, s, v, o;
   152 			var t = this, s, v, o;
    64 	
   153 
    65 			t.editor = ed;
   154 			t.editor = ed;
    66 			t.url = url;
   155 			t.url = url;
    67 			t.onResolveName = new tinymce.util.Dispatcher(this);
   156 			t.onResolveName = new tinymce.util.Dispatcher(this);
       
   157 			s = ed.settings;
    68 
   158 
    69 			ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast();
   159 			ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast();
    70 			ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin;
   160 			ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin;
       
   161 
       
   162 			// Setup default buttons
       
   163 			if (!s.theme_advanced_buttons1) {
       
   164 				s = extend({
       
   165 					theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",
       
   166 					theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",
       
   167 					theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap"
       
   168 				}, s);
       
   169 			}
    71 
   170 
    72 			// Default settings
   171 			// Default settings
    73 			t.settings = s = extend({
   172 			t.settings = s = extend({
    74 				theme_advanced_path : true,
   173 				theme_advanced_path : true,
    75 				theme_advanced_toolbar_location : 'bottom',
   174 				theme_advanced_toolbar_location : 'top',
    76 				theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",
       
    77 				theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",
       
    78 				theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap",
       
    79 				theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6",
   175 				theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6",
    80 				theme_advanced_toolbar_align : "center",
   176 				theme_advanced_toolbar_align : "left",
       
   177 				theme_advanced_statusbar_location : "bottom",
    81 				theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",
   178 				theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",
    82 				theme_advanced_more_colors : 1,
   179 				theme_advanced_more_colors : 1,
    83 				theme_advanced_row_height : 23,
   180 				theme_advanced_row_height : 23,
    84 				theme_advanced_resize_horizontal : 1,
   181 				theme_advanced_resize_horizontal : 1,
    85 				theme_advanced_resizing_use_cookie : 1,
   182 				theme_advanced_resizing_use_cookie : 1,
    86 				theme_advanced_font_sizes : "1,2,3,4,5,6,7",
   183 				theme_advanced_font_sizes : "1,2,3,4,5,6,7",
    87 				theme_advanced_font_selector : "span",
   184 				theme_advanced_font_selector : "span",
    88 				theme_advanced_show_current_color: 0,
   185 				theme_advanced_show_current_color: 0,
    89 				readonly : ed.settings.readonly
   186 				readonly : ed.settings.readonly
    90 			}, ed.settings);
   187 			}, s);
    91 
   188 
    92 			// Setup default font_size_style_values
   189 			// Setup default font_size_style_values
    93 			if (!s.font_size_style_values)
   190 			if (!s.font_size_style_values)
    94 				s.font_size_style_values = "8pt,10pt,12pt,14pt,18pt,24pt,36pt";
   191 				s.font_size_style_values = "8pt,10pt,12pt,14pt,18pt,24pt,36pt";
    95 
   192 
   217 		_importClasses : function(e) {
   314 		_importClasses : function(e) {
   218 			var ed = this.editor, ctrl = ed.controlManager.get('styleselect');
   315 			var ed = this.editor, ctrl = ed.controlManager.get('styleselect');
   219 
   316 
   220 			if (ctrl.getLength() == 0) {
   317 			if (ctrl.getLength() == 0) {
   221 				each(ed.dom.getClasses(), function(o, idx) {
   318 				each(ed.dom.getClasses(), function(o, idx) {
   222 					var name = 'style_' + idx;
   319 					var name = 'style_' + idx, fmt;
   223 
   320 
   224 					ed.formatter.register(name, {
   321 					fmt = {
   225 						inline : 'span',
   322 						inline : 'span',
   226 						attributes : {'class' : o['class']},
   323 						attributes : {'class' : o['class']},
   227 						selector : '*'
   324 						selector : '*'
       
   325 					};
       
   326 
       
   327 					ed.formatter.register(name, fmt);
       
   328 
       
   329 					ctrl.add(o['class'], name, {
       
   330 						style: function() {
       
   331 							return getPreviewCss(ed, fmt);
       
   332 						}
   228 					});
   333 					});
   229 
       
   230 					ctrl.add(o['class'], name);
       
   231 				});
   334 				});
   232 			}
   335 			}
   233 		},
   336 		},
   234 
   337 
   235 		_createStyleSelect : function(n) {
   338 		_createStyleSelect : function(n) {
   237 
   340 
   238 			// Setup style select box
   341 			// Setup style select box
   239 			ctrl = ctrlMan.createListBox('styleselect', {
   342 			ctrl = ctrlMan.createListBox('styleselect', {
   240 				title : 'advanced.style_select',
   343 				title : 'advanced.style_select',
   241 				onselect : function(name) {
   344 				onselect : function(name) {
   242 					var matches, formatNames = [];
   345 					var matches, formatNames = [], removedFormat;
   243 
   346 
   244 					each(ctrl.items, function(item) {
   347 					each(ctrl.items, function(item) {
   245 						formatNames.push(item.value);
   348 						formatNames.push(item.value);
   246 					});
   349 					});
   247 
   350 
   248 					ed.focus();
   351 					ed.focus();
   249 					ed.undoManager.add();
   352 					ed.undoManager.add();
   250 
   353 
   251 					// Toggle off the current format
   354 					// Toggle off the current format(s)
   252 					matches = ed.formatter.matchAll(formatNames);
   355 					matches = ed.formatter.matchAll(formatNames);
   253 					if (!name || matches[0] == name) {
   356 					tinymce.each(matches, function(match) {
   254 						if (matches[0]) 
   357 						if (!name || match == name) {
   255 							ed.formatter.remove(matches[0]);
   358 							if (match)
   256 					} else
   359 								ed.formatter.remove(match);
       
   360 
       
   361 							removedFormat = true;
       
   362 						}
       
   363 					});
       
   364 
       
   365 					if (!removedFormat)
   257 						ed.formatter.apply(name);
   366 						ed.formatter.apply(name);
   258 
   367 
   259 					ed.undoManager.add();
   368 					ed.undoManager.add();
   260 					ed.nodeChanged();
   369 					ed.nodeChanged();
   261 
   370 
   262 					return false; // No auto select
   371 					return false; // No auto select
   263 				}
   372 				}
   264 			});
   373 			});
   265 
   374 
   266 			// Handle specified format
   375 			// Handle specified format
   267 			ed.onInit.add(function() {
   376 			ed.onPreInit.add(function() {
   268 				var counter = 0, formats = ed.getParam('style_formats');
   377 				var counter = 0, formats = ed.getParam('style_formats');
   269 
   378 
   270 				if (formats) {
   379 				if (formats) {
   271 					each(formats, function(fmt) {
   380 					each(formats, function(fmt) {
   272 						var name, keys = 0;
   381 						var name, keys = 0;
   274 						each(fmt, function() {keys++;});
   383 						each(fmt, function() {keys++;});
   275 
   384 
   276 						if (keys > 1) {
   385 						if (keys > 1) {
   277 							name = fmt.name = fmt.name || 'style_' + (counter++);
   386 							name = fmt.name = fmt.name || 'style_' + (counter++);
   278 							ed.formatter.register(name, fmt);
   387 							ed.formatter.register(name, fmt);
   279 							ctrl.add(fmt.title, name);
   388 							ctrl.add(fmt.title, name, {
       
   389 								style: function() {
       
   390 									return getPreviewCss(ed, fmt);
       
   391 								}
       
   392 							});
   280 						} else
   393 						} else
   281 							ctrl.add(fmt.title);
   394 							ctrl.add(fmt.title);
   282 					});
   395 					});
   283 				} else {
   396 				} else {
   284 					each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) {
   397 					each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) {
   285 						var name;
   398 						var name, fmt;
   286 
   399 
   287 						if (val) {
   400 						if (val) {
   288 							name = 'style_' + (counter++);
   401 							name = 'style_' + (counter++);
   289 
   402 							fmt = {
   290 							ed.formatter.register(name, {
       
   291 								inline : 'span',
   403 								inline : 'span',
   292 								classes : val,
   404 								classes : val,
   293 								selector : '*'
   405 								selector : '*'
       
   406 							};
       
   407 
       
   408 							ed.formatter.register(name, fmt);
       
   409 							ctrl.add(t.editor.translate(key), name, {
       
   410 								style: function() {
       
   411 									return getPreviewCss(ed, fmt);
       
   412 								}
   294 							});
   413 							});
   295 
       
   296 							ctrl.add(t.editor.translate(key), name);
       
   297 						}
   414 						}
   298 					});
   415 					});
   299 				}
   416 				}
   300 			});
   417 			});
   301 
   418 
   431 				return false;
   548 				return false;
   432 			}});
   549 			}});
   433 
   550 
   434 			if (c) {
   551 			if (c) {
   435 				each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) {
   552 				each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) {
   436 					c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v});
   553 					c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v, style: function() {
       
   554 						return getPreviewCss(t.editor, {block: v});
       
   555 					}});
   437 				});
   556 				});
   438 			}
   557 			}
   439 
   558 
   440 			return c;
   559 			return c;
   441 		},
   560 		},
   505 				ed.settings.aria_label = s.aria_label + ed.getLang('advanced.help_shortcut');
   624 				ed.settings.aria_label = s.aria_label + ed.getLang('advanced.help_shortcut');
   506 			}
   625 			}
   507 
   626 
   508 			// TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.
   627 			// TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.
   509 			// Maybe actually inherit it from the original textara?
   628 			// Maybe actually inherit it from the original textara?
   510 			n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')});
   629 			n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')});
   511 			DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);
   630 			DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);
   512 
   631 
   513 			if (!DOM.boxModel)
   632 			if (!DOM.boxModel)
   514 				n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'});
   633 				n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'});
   515 
   634 
   550 			Event.add(ed.id + '_path_row', 'click', function(e) {
   669 			Event.add(ed.id + '_path_row', 'click', function(e) {
   551 				e = e.target;
   670 				e = e.target;
   552 
   671 
   553 				if (e.nodeName == 'A') {
   672 				if (e.nodeName == 'A') {
   554 					t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1'));
   673 					t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1'));
   555 
   674 					return false;
   556 					return Event.cancel(e);
       
   557 				}
   675 				}
   558 			});
   676 			});
   559 /*
   677 /*
   560 			if (DOM.get(ed.id + '_path_row')) {
   678 			if (DOM.get(ed.id + '_path_row')) {
   561 				Event.add(ed.id + '_tbl', 'mouseover', function(e) {
   679 				Event.add(ed.id + '_tbl', 'mouseover', function(e) {
   562 					var re;
   680 					var re;
   563 	
   681 
   564 					e = e.target;
   682 					e = e.target;
   565 
   683 
   566 					if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) {
   684 					if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) {
   567 						re = DOM.get(ed.id + '_path_row');
   685 						re = DOM.get(ed.id + '_path_row');
   568 						t.lastPath = re.innerHTML;
   686 						t.lastPath = re.innerHTML;
   711 					DOM.hide(lastExtID);
   829 					DOM.hide(lastExtID);
   712 
   830 
   713 					var f = Event.add(ed.id + '_external_close', 'click', function() {
   831 					var f = Event.add(ed.id + '_external_close', 'click', function() {
   714 						DOM.hide(ed.id + '_external');
   832 						DOM.hide(ed.id + '_external');
   715 						Event.remove(ed.id + '_external_close', 'click', f);
   833 						Event.remove(ed.id + '_external_close', 'click', f);
       
   834 						return false;
   716 					});
   835 					});
   717 
   836 
   718 					DOM.show(e);
   837 					DOM.show(e);
   719 					DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1);
   838 					DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1);
   720 
   839 
   823 					tb.add(c);
   942 					tb.add(c);
   824 			});
   943 			});
   825 		},
   944 		},
   826 
   945 
   827 		_addToolbars : function(c, o) {
   946 		_addToolbars : function(c, o) {
   828 			var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup;
   947 			var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false;
   829 
   948 
   830 			toolbarGroup = cf.createToolbarGroup('toolbargroup', {
   949 			toolbarGroup = cf.createToolbarGroup('toolbargroup', {
   831 				'name': ed.getLang('advanced.toolbar'),
   950 				'name': ed.getLang('advanced.toolbar'),
   832 				'tab_focus_toolbar':ed.getParam('theme_advanced_tab_focus_toolbar')
   951 				'tab_focus_toolbar':ed.getParam('theme_advanced_tab_focus_toolbar')
   833 			});
   952 			});
   835 			t.toolbarGroup = toolbarGroup;
   954 			t.toolbarGroup = toolbarGroup;
   836 
   955 
   837 			a = s.theme_advanced_toolbar_align.toLowerCase();
   956 			a = s.theme_advanced_toolbar_align.toLowerCase();
   838 			a = 'mce' + t._ufirst(a);
   957 			a = 'mce' + t._ufirst(a);
   839 
   958 
   840 			n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"});
   959 			n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"toolbar"});
   841 
   960 
   842 			// Create toolbar and add the controls
   961 			// Create toolbar and add the controls
   843 			for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
   962 			for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
       
   963 				toolbarsExist = true;
   844 				tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
   964 				tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
   845 
   965 
   846 				if (s['theme_advanced_buttons' + i + '_add'])
   966 				if (s['theme_advanced_buttons' + i + '_add'])
   847 					v += ',' + s['theme_advanced_buttons' + i + '_add'];
   967 					v += ',' + s['theme_advanced_buttons' + i + '_add'];
   848 
   968 
   852 				t._addControls(v, tb);
   972 				t._addControls(v, tb);
   853 				toolbarGroup.add(tb);
   973 				toolbarGroup.add(tb);
   854 
   974 
   855 				o.deltaHeight -= s.theme_advanced_row_height;
   975 				o.deltaHeight -= s.theme_advanced_row_height;
   856 			}
   976 			}
       
   977 			// Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly
       
   978 			if (!toolbarsExist)
       
   979 				o.deltaHeight -= s.theme_advanced_row_height;
   857 			h.push(toolbarGroup.renderHTML());
   980 			h.push(toolbarGroup.renderHTML());
   858 			h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
   981 			h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
   859 			DOM.setHTML(n, h.join(''));
   982 			DOM.setHTML(n, h.join(''));
   860 		},
   983 		},
   861 
   984 
   862 		_addStatusBar : function(tb, o) {
   985 		_addStatusBar : function(tb, o) {
   863 			var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td;
   986 			var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td;
   864 
   987 
   865 			n = DOM.add(tb, 'tr');
   988 			n = DOM.add(tb, 'tr');
   866 			n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); 
   989 			n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'});
   867 			n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'});
   990 			n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'});
   868 			if (s.theme_advanced_path) {
   991 			if (s.theme_advanced_path) {
   869 				DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path'));
   992 				DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path'));
   870 				DOM.add(n, 'span', {}, ': ');
   993 				DOM.add(n, 'span', {}, ': ');
   871 			} else {
   994 			} else {
   872 				DOM.add(n, 'span', {}, '&#160;');
   995 				DOM.add(n, 'span', {}, '&#160;');
   873 			}
   996 			}
   874 			
   997 
   875 
   998 
   876 			if (s.theme_advanced_resizing) {
   999 			if (s.theme_advanced_resizing) {
   877 				DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"});
  1000 				DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"});
   878 
  1001 
   879 				if (s.theme_advanced_resizing_use_cookie) {
  1002 				if (s.theme_advanced_resizing_use_cookie) {
   914 							Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2);
  1037 							Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2);
   915 
  1038 
   916 							width = startWidth + (e.screenX - startX);
  1039 							width = startWidth + (e.screenX - startX);
   917 							height = startHeight + (e.screenY - startY);
  1040 							height = startHeight + (e.screenY - startY);
   918 							t.resizeTo(width, height, true);
  1041 							t.resizeTo(width, height, true);
       
  1042 
       
  1043 							ed.nodeChanged();
   919 						};
  1044 						};
   920 
  1045 
   921 						e.preventDefault();
  1046 						e.preventDefault();
   922 
  1047 
   923 						// Get the current rect size
  1048 						// Get the current rect size
   973 			t._updateUndoStatus(ed);
  1098 			t._updateUndoStatus(ed);
   974 			cm.setDisabled('outdent', !ed.queryCommandState('Outdent'));
  1099 			cm.setDisabled('outdent', !ed.queryCommandState('Outdent'));
   975 
  1100 
   976 			p = getParent('A');
  1101 			p = getParent('A');
   977 			if (c = cm.get('link')) {
  1102 			if (c = cm.get('link')) {
   978 				if (!p || !p.name) {
  1103 				c.setDisabled((!p && co) || (p && !p.href));
   979 					c.setDisabled(!p && co);
  1104 				c.setActive(!!p && (!p.name && !p.id));
   980 					c.setActive(!!p);
       
   981 				}
       
   982 			}
  1105 			}
   983 
  1106 
   984 			if (c = cm.get('unlink')) {
  1107 			if (c = cm.get('unlink')) {
   985 				c.setDisabled(!p && co);
  1108 				c.setDisabled(!p && co);
   986 				c.setActive(!!p && !p.name);
  1109 				c.setActive(!!p && !p.name && !p.id);
   987 			}
  1110 			}
   988 
  1111 
   989 			if (c = cm.get('anchor')) {
  1112 			if (c = cm.get('anchor')) {
   990 				c.setActive(!co && !!p && p.name);
  1113 				c.setActive(!co && !!p && (p.name || (p.id && !p.href)));
   991 			}
  1114 			}
   992 
  1115 
   993 			p = getParent('IMG');
  1116 			p = getParent('IMG');
   994 			if (c = cm.get('image'))
  1117 			if (c = cm.get('image'))
   995 				c.setActive(!co && !!p && n.className.indexOf('mceItem') == -1);
  1118 				c.setActive(!co && !!p && n.className.indexOf('mceItem') == -1);
  1002 					formatNames.push(item.value);
  1125 					formatNames.push(item.value);
  1003 				});
  1126 				});
  1004 
  1127 
  1005 				matches = ed.formatter.matchAll(formatNames);
  1128 				matches = ed.formatter.matchAll(formatNames);
  1006 				c.select(matches[0]);
  1129 				c.select(matches[0]);
       
  1130 				tinymce.each(matches, function(match, index) {
       
  1131 					if (index > 0) {
       
  1132 						c.mark(match);
       
  1133 					}
       
  1134 				});
  1007 			}
  1135 			}
  1008 
  1136 
  1009 			if (c = cm.get('formatselect')) {
  1137 			if (c = cm.get('formatselect')) {
  1010 				p = getParent(DOM.isBlock);
  1138 				p = getParent(ed.dom.isBlock);
  1011 
  1139 
  1012 				if (p)
  1140 				if (p)
  1013 					c.select(p.nodeName.toLowerCase());
  1141 					c.select(p.nodeName.toLowerCase());
  1014 			}
  1142 			}
  1015 
  1143 
  1024 					if (!fz && n.style.fontSize)
  1152 					if (!fz && n.style.fontSize)
  1025 						fz = n.style.fontSize;
  1153 						fz = n.style.fontSize;
  1026 
  1154 
  1027 					if (!fn && n.style.fontFamily)
  1155 					if (!fn && n.style.fontFamily)
  1028 						fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase();
  1156 						fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase();
  1029 					
  1157 
  1030 					if (!fc && n.style.color)
  1158 					if (!fc && n.style.color)
  1031 						fc = n.style.color;
  1159 						fc = n.style.color;
  1032 
  1160 
  1033 					if (!bc && n.style.backgroundColor)
  1161 					if (!bc && n.style.backgroundColor)
  1034 						bc = n.style.backgroundColor;
  1162 						bc = n.style.backgroundColor;
  1055 
  1183 
  1056 					if (v['class'] && v['class'] === cl)
  1184 					if (v['class'] && v['class'] === cl)
  1057 						return true;
  1185 						return true;
  1058 				});
  1186 				});
  1059 			}
  1187 			}
  1060 			
  1188 
  1061 			if (s.theme_advanced_show_current_color) {
  1189 			if (s.theme_advanced_show_current_color) {
  1062 				function updateColor(controlId, color) {
  1190 				function updateColor(controlId, color) {
  1063 					if (c = cm.get(controlId)) {
  1191 					if (c = cm.get(controlId)) {
  1064 						if (!color)
  1192 						if (!color)
  1065 							color = c.settings.default_color;
  1193 							color = c.settings.default_color;
  1103 					// Ignore non element and bogus/hidden elements
  1231 					// Ignore non element and bogus/hidden elements
  1104 					if (n.nodeType != 1 || na === 'br' || n.getAttribute('data-mce-bogus') || DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved'))
  1232 					if (n.nodeType != 1 || na === 'br' || n.getAttribute('data-mce-bogus') || DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved'))
  1105 						return;
  1233 						return;
  1106 
  1234 
  1107 					// Handle prefix
  1235 					// Handle prefix
  1108 					if (tinymce.isIE && n.scopeName !== 'HTML')
  1236 					if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName)
  1109 						na = n.scopeName + ':' + na;
  1237 						na = n.scopeName + ':' + na;
  1110 
  1238 
  1111 					// Remove internal prefix
  1239 					// Remove internal prefix
  1112 					na = na.replace(/mce\:/g, '');
  1240 					na = na.replace(/mce\:/g, '');
  1113 
  1241 
  1159 
  1287 
  1160 					if (v = DOM.getAttrib(n, 'id'))
  1288 					if (v = DOM.getAttrib(n, 'id'))
  1161 						ti += 'id: ' + v + ' ';
  1289 						ti += 'id: ' + v + ' ';
  1162 
  1290 
  1163 					if (v = n.className) {
  1291 					if (v = n.className) {
  1164 						v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '')
  1292 						v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '');
  1165 
  1293 
  1166 						if (v) {
  1294 						if (v) {
  1167 							ti += 'class: ' + v + ' ';
  1295 							ti += 'class: ' + v + ' ';
  1168 
  1296 
  1169 							if (DOM.isBlock(n) || na == 'img' || na == 'span')
  1297 							if (ed.dom.isBlock(n) || na == 'img' || na == 'span')
  1170 								na += '.' + v;
  1298 								na += '.' + v;
  1171 						}
  1299 						}
  1172 					}
  1300 					}
  1173 
  1301 
  1174 					na = na.replace(/(html:)/g, '');
  1302 					na = na.replace(/(html:)/g, '');
  1292 
  1420 
  1293 		_mceImage : function(ui, val) {
  1421 		_mceImage : function(ui, val) {
  1294 			var ed = this.editor;
  1422 			var ed = this.editor;
  1295 
  1423 
  1296 			// Internal image object like a flash placeholder
  1424 			// Internal image object like a flash placeholder
  1297 			if (ed.dom.getAttrib(ed.selection.getNode(), 'class').indexOf('mceItem') != -1)
  1425 			if (ed.dom.getAttrib(ed.selection.getNode(), 'class', '').indexOf('mceItem') != -1)
  1298 				return;
  1426 				return;
  1299 
  1427 
  1300 			ed.windowManager.open({
  1428 			ed.windowManager.open({
  1301 				url : this.url + '/image.htm',
  1429 				url : this.url + '/image.htm',
  1302 				width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)),
  1430 				width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)),