From 87e2fddb32da8580f73c5ec0628e9eacfb4e0043 Mon Sep 17 00:00:00 2001 From: svncommit <devs@roundcube.net> Date: Mon, 26 Feb 2007 02:19:44 -0500 Subject: [PATCH] upgrade to TinyMCE v2.1.0 --- program/js/tiny_mce/tiny_mce_src.js | 442 ++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 325 insertions(+), 117 deletions(-) diff --git a/program/js/tiny_mce/tiny_mce_src.js b/program/js/tiny_mce/tiny_mce_src.js index 2a8be73..9f8de6e 100644 --- a/program/js/tiny_mce/tiny_mce_src.js +++ b/program/js/tiny_mce/tiny_mce_src.js @@ -5,8 +5,8 @@ var ua; this.majorVersion = "2"; - this.minorVersion = "0.8"; - this.releaseDate = "2006-10-23"; + this.minorVersion = "1.0"; + this.releaseDate = "2007-02-13"; this.instances = new Array(); this.switchClassCache = new Array(); @@ -186,12 +186,13 @@ this._def("custom_shortcuts", true); this._def("convert_on_click", false); this._def("content_css", ''); - this._def("fix_list_elements", false); + this._def("fix_list_elements", true); this._def("fix_table_elements", false); this._def("strict_loading_mode", document.contentType == 'application/xhtml+xml'); this._def("hidden_tab_class", ''); this._def("display_tab_class", ''); this._def("gecko_spellcheck", false); + this._def("hide_selects_on_submit", true); // Force strict loading mode to false on non Gecko browsers if (this.isMSIE && !this.isOpera) @@ -240,9 +241,9 @@ this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP'; this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i"); this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40); - this.uniqueURL = 'javascript:TINYMCE_UNIQUEURL();'; // Make unique URL non real URL + this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>'; - this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup'); + this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance'); // Theme url this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme; @@ -338,6 +339,11 @@ } catch (e) { } } + + // Setup XML encoding regexps + this.xmlEncodeAposRe = new RegExp('[<>&"\']', 'g'); + this.xmlEncodeRe = new RegExp('[<>&"]', 'g'); +// this.xmlEncodeEnts = {'&':'&','"':'"',"'":''','<':'<','>':'>'}; }, _addUnloadEvents : function() { @@ -570,6 +576,9 @@ tinyMCE.undoLevels = n; tinyMCE.undoIndex = n.length; + // Dispatch remove instance call + tinyMCE.dispatchCallback(ti, 'remove_instance_callback', 'removeInstance', ti); + return ti; }, @@ -731,6 +740,35 @@ tinyMCE.removeMCEControl(value); return; + case "mceToggleEditor": + var inst = tinyMCE.getInstanceById(value), pe, te; + + if (inst) { + pe = document.getElementById(inst.editorId + '_parent'); + te = inst.oldTargetElement; + + if (typeof(inst.enabled) == 'undefined') + inst.enabled = true; + + inst.enabled = !inst.enabled; + + if (!inst.enabled) { + pe.style.display = 'none'; + te.value = inst.getHTML(); + te.style.display = inst.oldTargetDisplay; + tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst); + } else { + pe.style.display = 'block'; + te.style.display = 'none'; + inst.setHTML(te.value); + inst.useCSS = false; + tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst); + } + } else + tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); + + return; + case "mceResetDesignMode": // Resets the designmode state of the editors in Gecko if (!tinyMCE.isIE) { @@ -836,6 +874,7 @@ content = content.replace(/&/g, '&'); } + tinyMCE.selectedInstance = inst; inst.switchSettings(); // Not loaded correctly hit it again, Mozilla bug #997860 @@ -951,10 +990,6 @@ // Fix for bug #957681 //inst.getDoc().designMode = inst.getDoc().designMode; - // Setup element references - var parentElm = inst.targetDoc.getElementById(inst.editorId + '_parent'); - inst.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling; - tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst); tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); @@ -1015,8 +1050,8 @@ storeAwayURLs : function(s) { // Remove all mce_src, mce_href and replace them with new ones - // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); - // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); + // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); + // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); if (!s.match(/(mce_src|mce_href)/gi, s)) { s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"'); @@ -1035,6 +1070,38 @@ return false; }); + } + }, + + removeTinyMCEFormElements : function(form_obj) { + var i, elementId; + + // Skip form element removal + if (!tinyMCE.getParam('hide_selects_on_submit')) + return; + + // Check if form is valid + if (typeof(form_obj) == "undefined" || form_obj == null) + return; + + // If not a form, find the form + if (form_obj.nodeName != "FORM") { + if (form_obj.form) + form_obj = form_obj.form; + else + form_obj = tinyMCE.getParentElement(form_obj, "form"); + } + + // Still nothing + if (form_obj == null) + return; + + // Disable all UI form elements that TinyMCE created + for (i=0; i<form_obj.elements.length; i++) { + elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id; + + if (elementId.indexOf('mce_editor_') == 0) + form_obj.elements[i].disabled = true; } }, @@ -1086,6 +1153,7 @@ return; case "submit": + tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target); tinyMCE.triggerSave(); tinyMCE.isNotDirty = true; return; @@ -1402,9 +1470,9 @@ h += '</a></span>'; } else { if (tinyMCE.isRealIE) - h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">'; + h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">'; else - h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton">'; + h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton">'; h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">'; h += '<img src="' + img + '" title="{$' + lang + '}" /></a>'; @@ -1433,6 +1501,7 @@ }, submitPatch : function() { + tinyMCE.removeTinyMCEFormElements(this); tinyMCE.triggerSave(); tinyMCE.isNotDirty = true; this.mceOldSubmit(); @@ -1649,14 +1718,19 @@ }, triggerNodeChange : function(focus, setup_content) { + var elm, inst, editorId, undoIndex = -1, undoLevels = -1, doc, anySelection = false, st; + if (tinyMCE.selectedInstance) { - var inst = tinyMCE.selectedInstance; - var editorId = inst.editorId; - var elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement(); - var undoIndex = -1, doc; - var undoLevels = -1; - var anySelection = false; - var selectedText = inst.selection.getSelectedText(); + inst = tinyMCE.selectedInstance; + elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement(); + +/* if (elm == inst.lastTriggerEl) + return; + + inst.lastTriggerEl = elm;*/ + + editorId = inst.editorId; + st = inst.selection.getSelectedText(); if (tinyMCE.settings.auto_resize) inst.resizeToContent(); @@ -1667,7 +1741,7 @@ inst.switchSettings(); if (tinyMCE.selectedElement) - anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (selectedText && selectedText.length > 0); + anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0); if (tinyMCE.settings['custom_undo_redo']) { undoIndex = inst.undoRedo.undoIndex; @@ -1753,6 +1827,8 @@ openWindow : function(template, args) { var html, width, height, x, y, resizable, scrollbars, url; + + args = !args ? {} : args; args['mce_template_file'] = template['file']; args['mce_width'] = template['width']; @@ -2129,11 +2205,11 @@ }, getCSSClasses : function(editor_id, doc) { - var output = new Array(); + var inst = tinyMCE.getInstanceById(editor_id); // Is cached, use that - if (typeof(tinyMCE.cssClasses) != "undefined") - return tinyMCE.cssClasses; + if (inst && inst.cssClasses.length > 0) + return inst.cssClasses; if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") { var instance; @@ -2191,13 +2267,13 @@ var cssClass = rule.substring(rule.indexOf('.') + 1); var addClass = true; - for (var p=0; p<output.length && addClass; p++) { - if (output[p] == cssClass) + for (var p=0; p<inst.cssClasses.length && addClass; p++) { + if (inst.cssClasses[p] == cssClass) addClass = false; } if (addClass) - output[output.length] = cssClass; + inst.cssClasses[inst.cssClasses.length] = cssClass; } } } @@ -2206,11 +2282,7 @@ } } - // Cache em - if (output.length > 0) - tinyMCE.cssClasses = output; - - return output; + return inst.cssClasses; }, regexpReplace : function(in_str, reg_exp, replace_str, opts) { @@ -2238,36 +2310,36 @@ }, getControlHTML : function(c) { - var i, l, n, o, v; + var i, l, n, o, v, rtl = tinyMCE.getLang('lang_dir') == 'rtl'; l = tinyMCE.plugins; for (n in l) { o = l[n]; - if (o.getControlHTML && (v = o.getControlHTML(c)) != '') + if (o.getControlHTML && (v = o.getControlHTML(c)) != '') { + if (rtl) + return '<span dir="rtl">' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '</span>'; + return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); + } } o = tinyMCE.themes[tinyMCE.settings['theme']]; - if (o.getControlHTML && (v = o.getControlHTML(c)) != '') + if (o.getControlHTML && (v = o.getControlHTML(c)) != '') { + if (rtl) + return '<span dir="rtl">' + v + '</span>'; + return v; + } return ''; }, evalFunc : function(f, idx, a, o) { - var s = '(', i; + o = !o ? window : o; + f = typeof(f) == 'function' ? f : o[f]; - for (i=idx; i<a.length; i++) { - s += 'a[' + i + ']'; - - if (i < a.length-1) - s += ','; - } - - s += ');'; - - return o ? eval("o." + f + s) : eval("f" + s); + return f.apply(o, Array.prototype.slice.call(a, idx)); }, dispatchCallback : function(i, p, n) { @@ -2289,7 +2361,7 @@ l = tinyMCE.getParam(p, ''); - if (l != '' && (v = tinyMCE.evalFunc(typeof(l) == "function" ? l : eval(l), 3, a)) == s && m > 0) + if (l != '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0) return true; if (ins != null) { @@ -2312,8 +2384,8 @@ return false; }, - xmlEncode : function(s) { - return s ? ('' + s).replace(new RegExp('[<>&"\']', 'g'), function (c, b) { + xmlEncode : function(s, skip_apos) { + return s ? ('' + s).replace(!skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe, function (c, b) { switch (c) { case '&': return '&'; @@ -2390,6 +2462,7 @@ this.hasMouseMoved = false; this.foreColor = this.backColor = "#999999"; this.data = {}; + this.cssClasses = []; this.cleanup.init({ valid_elements : s.valid_elements, @@ -2398,11 +2471,11 @@ entities : s.entities, entity_encoding : s.entity_encoding, debug : s.cleanup_debug, - url_converter : 'TinyMCE_Cleanup.prototype._urlConverter', indent : s.apply_source_formatting, invalid_elements : s.invalid_elements, verify_html : s.verify_html, - fix_content_duplication : s.fix_content_duplication + fix_content_duplication : s.fix_content_duplication, + convert_fonts_to_spans : s.convert_fonts_to_spans }); // Wrap old theme @@ -2593,7 +2666,13 @@ }, handleShortcut : function(e) { - var i, s = this.shortcuts, o; + var i, s, o; + + // Normal key press, then ignore it + if (!e.altKey && !e.ctrlKey) + return false; + + s = this.shortcuts; for (i=0; i<s.length; i++) { o = s[i]; @@ -2702,8 +2781,11 @@ //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value); this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks - if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) - return; + // Don't dispatch key commands + if (!/mceStartTyping|mceEndTyping/.test(command)) { + if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) + return; + } // Fix align on images if (focusElm && focusElm.nodeName == "IMG") { @@ -2825,14 +2907,6 @@ return true; - case "FormatBlock": - if (!this.cleanup.isValid(value)) - return true; - - this.getDoc().execCommand(command, user_interface, value); - tinyMCE.triggerNodeChange(); - break; - case "InsertUnorderedList": case "InsertOrderedList": this.getDoc().execCommand(command, user_interface, value); @@ -2857,6 +2931,9 @@ if (elm) this.execCommand("mceRemoveNode", false, elm); } else { + if (!this.cleanup.isValid(value)) + return true; + if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) value = value.replace(/[^a-z]/gi, ''); @@ -2915,6 +2992,7 @@ break; + case "mceSetStyleInfo": case "SetStyleInfo": var rng = this.getRng(); var sel = this.getSel(); @@ -3246,7 +3324,7 @@ break; case "mceSetCSSClass": - this.execCommand("SetStyleInfo", false, {command : "setattrib", name : "class", value : value}); + this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value}); break; case "mceInsertRawHTML": @@ -3478,6 +3556,7 @@ } break; + case "RemoveFormat": case "removeformat": var text = this.selection.getSelectedText(); @@ -3494,11 +3573,11 @@ // Do nothing } - this.execCommand("SetStyleInfo", false, {command : "removeformat"}); + this.execCommand("mceSetStyleInfo", false, {command : "removeformat"}); } else { this.getDoc().execCommand(command, user_interface, value); - this.execCommand("SetStyleInfo", false, {command : "removeformat"}); + this.execCommand("mceSetStyleInfo", false, {command : "removeformat"}); } // Remove class @@ -3641,6 +3720,7 @@ hc = '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>'; } else { hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />'; + this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline'); this.oldTargetElement.style.display = "none"; } @@ -3666,8 +3746,10 @@ // Just hide the textarea element this.oldTargetElement = replace_element; - if (!tinyMCE.settings['debug']) + if (!tinyMCE.settings['debug']) { + this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline'); this.oldTargetElement.style.display = "none"; + } // Output HTML and set editable if (tinyMCE.isGecko) { @@ -3740,6 +3822,10 @@ // it seems that the document.frames isn't initialized yet? if (tinyMCE.isIE) window.setTimeout("tinyMCE.addEventHandlers(tinyMCE.instances[\"" + this.editorId + "\"]);", 1); + + // Setup element references + var parentElm = this.targetDoc.getElementById(this.editorId + '_parent'); + this.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling; tinyMCE.setupContent(this.editorId, true); @@ -3997,6 +4083,8 @@ if (tinyMCE.getParam("force_hex_style_colors")) val = tinyMCE.convertRGBToHex(val, true); + val = val.replace(/\"/g, '\''); + if (val != "url('')") str += key.toLowerCase() + ": " + val + "; "; } @@ -4043,12 +4131,12 @@ TinyMCE_Engine.prototype.convertSpansToFonts = function(doc) { var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(','); - var h = doc.body.innerHTML; + /*var h = doc.body.innerHTML; h = h.replace(/<span/gi, '<font'); h = h.replace(/<\/span/gi, '</font'); - tinyMCE.setInnerHTML(doc.body, h); + tinyMCE.setInnerHTML(doc.body, h);*/ - var s = doc.getElementsByTagName("font"); + var s = tinyMCE.selectElements(doc, 'span,font'); for (var i=0; i<s.length; i++) { var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase(); var fSize = 0; @@ -4082,10 +4170,10 @@ TinyMCE_Engine.prototype.convertFontsToSpans = function(doc) { var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(','); - var h = doc.body.innerHTML; +/* var h = doc.body.innerHTML; h = h.replace(/<font/gi, '<span'); h = h.replace(/<\/font/gi, '</span'); - tinyMCE.setInnerHTML(doc.body, h); + tinyMCE.setInnerHTML(doc.body, h);*/ var fsClasses = tinyMCE.getParam('font_size_classes'); if (fsClasses != '') @@ -4093,7 +4181,7 @@ else fsClasses = null; - var s = doc.getElementsByTagName("span"); + var s = tinyMCE.selectElements(doc, 'span,font'); for (var i=0; i<s.length; i++) { var fSize, fFace, fColor; @@ -4182,7 +4270,7 @@ for (i=0; i<nl.length; i++) { n = nl[i]; - if ((p = tinyMCE.getParentElement(n, 'p,div,h1,h2,h3,h4,h5,h6')) != null) { + if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) { np = p.cloneNode(false); np.removeAttribute('id'); @@ -4380,6 +4468,8 @@ this.fillStr = s.entity_encoding == "named" ? " " : " "; this.idCount = 0; + this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g'); + this.xmlEncodeAposRe = new RegExp('[\u007F-\uFFFF<>&"\']', 'g'); }, addRuleStr : function(s) { @@ -4403,6 +4493,10 @@ isValid : function(n) { this._setupRules(); // Will initialize cleanup rules + + // Empty is true since it removes formatting + if (!n) + return true; // Clean the name up a bit n = n.replace(/[^a-z0-9]+/gi, '').toUpperCase(); @@ -4606,7 +4700,7 @@ _convertToXML : function(n, xn) { var xd, el, i, l, cn, at, no, hc = false; - if (this._isDuplicate(n)) + if (tinyMCE.isRealIE && this._isDuplicate(n)) return; xd = this.xmlDoc; @@ -4649,11 +4743,11 @@ }, serializeNodeAsHTML : function(n, inn) { - var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr; + var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn; this._setupRules(); // Will initialize cleanup rules - if (this._isDuplicate(n)) + if (tinyMCE.isRealIE && this._isDuplicate(n)) return ''; // Skip non valid child elements @@ -4677,21 +4771,34 @@ if ((tinyMCE.isRealIE) && n.nodeName.indexOf('/') != -1) break; - if (this.vElementsRe.test(n.nodeName) && (!this.iveRe || !this.iveRe.test(n.nodeName)) && !inn) { + nn = n.nodeName; + + // Convert fonts to spans + if (this.settings.convert_fonts_to_spans) { + // On get content FONT -> SPAN + if (this.settings.on_save && nn == 'FONT') + nn = 'SPAN'; + + // On insert content SPAN -> FONT + if (!this.settings.on_save && nn == 'SPAN') + nn = 'FONT'; + } + + if (this.vElementsRe.test(nn) && (!this.iveRe || !this.iveRe.test(nn)) && !inn) { va = true; - r = this.rules[n.nodeName]; + r = this.rules[nn]; if (!r) { at = this.rules; for (no in at) { - if (at[no] && at[no].validRe.test(n.nodeName)) { + if (at[no] && at[no].validRe.test(nn)) { r = at[no]; break; } } } - en = r.isWild ? n.nodeName.toLowerCase() : r.oTagName; + en = r.isWild ? nn.toLowerCase() : r.oTagName; f = r.fill; if (r.removeEmpty && !hc) @@ -4728,13 +4835,13 @@ t = null; // Close these - if (t != null && this.closeElementsRe.test(n.nodeName)) + if (t != null && this.closeElementsRe.test(nn)) return t + ' />'; if (t != null) h += t + '>'; - if (this.isIE && this.codeElementsRe.test(n.nodeName)) + if (this.isIE && this.codeElementsRe.test(nn)) h += n.innerHTML; } break; @@ -4795,8 +4902,8 @@ if (r.forceAttribs && (t = r.forceAttribs[an])) av = t; - if (os && av.length != 0 && this.settings.url_converter.length != 0 && /^(src|href|longdesc)$/.test(an)) - av = eval(this.settings.url_converter + '(this, n, av)'); + if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an)) + av = this._urlConverter(this, n, av); if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av)) return ""; @@ -4806,7 +4913,7 @@ if (av.length != 0) { if (an.indexOf('on') != 0) - av = this.xmlEncode(av); + av = this.xmlEncode(av, 1); return " " + an + "=" + '"' + av + '"'; } @@ -4852,24 +4959,24 @@ return o; }, - xmlEncode : function(s) { - var cl = this; + xmlEncode : function(s, skip_apos) { + var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe; this._setupEntities(); // Will intialize lookup table switch (this.settings.entity_encoding) { case "raw": - return tinyMCE.xmlEncode(s); + return tinyMCE.xmlEncode(s, skip_apos); case "named": - return s.replace(new RegExp('[\u007F-\uFFFF<>&"\']', 'g'), function (c, b) { + return s.replace(re, function (c, b) { b = cl.entities[c.charCodeAt(0)]; return b ? '&' + b + ';' : c; }); case "numeric": - return s.replace(new RegExp('[\u007F-\uFFFF<>&"\']', 'g'), function (c, b) { + return s.replace(re, function (c, b) { return b ? '&#' + c.charCodeAt(0) + ';' : c; }); } @@ -4898,34 +5005,47 @@ }, _getAttrib : function(e, n, d) { + var v, ex, nn; + if (typeof(d) == "undefined") d = ""; if (!e || e.nodeType != 1) return d; - var v = e.getAttribute(n, 0); + try { + v = e.getAttribute(n, 0); + } catch (ex) { + // IE 7 may cast exception on invalid attributes + v = e.getAttribute(n, 2); + } if (n == "class" && !v) v = e.className; - if (this.isIE && n == "http-equiv") - v = e.httpEquiv; + if (this.isIE) { + if (n == "http-equiv") + v = e.httpEquiv; - if (this.isIE && e.nodeName == "FORM" && n == "enctype" && v == "application/x-www-form-urlencoded") - v = ""; + nn = e.nodeName; - if (this.isIE && e.nodeName == "INPUT" && n == "size" && v == "20") - v = ""; + // Skip the default values that IE returns + if (nn == "FORM" && n == "enctype" && v == "application/x-www-form-urlencoded") + v = ""; - if (this.isIE && e.nodeName == "INPUT" && n == "maxlength" && v == "2147483647") - v = ""; + if (nn == "INPUT" && n == "size" && v == "20") + v = ""; - if (n == "style" && !tinyMCE.isOpera) - v = e.style.cssText; + if (nn == "INPUT" && n == "maxlength" && v == "2147483647") + v = ""; + } - if (n == 'style') + if (n == 'style' && v) { + if (!tinyMCE.isOpera) + v = e.style.cssText; + v = tinyMCE.serializeStyle(tinyMCE.parseStyle(v)); + } if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v != "") v = tinyMCE.cleanupEventStr(v); @@ -4936,8 +5056,12 @@ _urlConverter : function(c, n, v) { if (!c.settings.on_save) return tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, v); - else if (tinyMCE.getParam('convert_urls')) - return eval(tinyMCE.settings.urlconverter_callback + "(v, n, true);"); + else if (tinyMCE.getParam('convert_urls')) { + if (!this.urlConverter) + this.urlConverter = eval(tinyMCE.settings.urlconverter_callback); + + return this.urlConverter(v, n, true); + } return v; }, @@ -5099,9 +5223,10 @@ // Convert all strong/em to b/i in Gecko if (tinyMCE.isGecko) { - h = h.replace(/<strong/gi, '<b'); - h = h.replace(/<em(\/?)/gi, '<i'); - h = h.replace(/<em /gi, '<i'); + h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>'); + h = h.replace(/<em([^>]*)>/gi, '<i$1>'); + h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>'); + h = h.replace(/<strong([^>]*)>/gi, '<b$1>'); h = h.replace(/<\/strong>/gi, '</b>'); h = h.replace(/<\/em>/gi, '</i>'); } @@ -5225,7 +5350,12 @@ if (!elm || elm.nodeType != 1) return dv; - v = elm.getAttribute(name); + try { + v = elm.getAttribute(name, 0); + } catch (ex) { + // IE 7 may cast exception on invalid attributes + v = elm.getAttribute(name, 2); + } // Try className for class attrib if (name == "class" && !v) @@ -5409,6 +5539,32 @@ width : w.innerWidth || (m ? de.clientWidth : b.clientWidth), height : w.innerHeight || (m ? de.clientHeight : b.clientHeight) }; +}; + +TinyMCE_Engine.prototype.getStyle = function(n, na, d) { + if (!n) + return false; + + // Gecko + if (tinyMCE.isGecko && n.ownerDocument.defaultView) { + try { + return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na); + } catch (n) { + // Old safari might fail + return null; + } + } + + // Camelcase it, if needed + na = na.replace(/-(\D)/g, function(a, b){ + return b.toUpperCase(); + }); + + // IE & Opera + if (n.currentStyle) + return n.currentStyle[na]; + + return false; }; /* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */ @@ -5876,7 +6032,12 @@ for (i=0; i<ot.length; i++) f(doc, ot[i], tinyMCE.handleEvent); - eval('try { doc.designMode = "On"; } catch(e) {}'); // Force designmode + // Force designmode + try { + doc.designMode = "On"; + } catch (e) { + // Ignore + } } }; @@ -6047,8 +6208,8 @@ h = tinyMCE._cleanupHTML(inst, inst.contentDocument, inst.settings, e, e, false, true, false); // When editing always use fonts internaly - if (tinyMCE.getParam("convert_fonts_to_spans")) - tinyMCE.convertSpansToFonts(inst.getDoc()); + //if (tinyMCE.getParam("convert_fonts_to_spans")) + // tinyMCE.convertSpansToFonts(inst.getDoc()); return h; }, @@ -6251,6 +6412,9 @@ } if (tinyMCE.isGecko || tinyMCE.isOpera) { + if (!sel) + return false; + if (bookmark.rng) { sel.removeAllRanges(); sel.addRange(bookmark.rng); @@ -6462,7 +6626,33 @@ if (tinyMCE.isSafari && !s.getRangeAt) return '' + window.getSelection(); - return s.getRangeAt(0); + if (s.rangeCount > 0) + return s.getRangeAt(0); + + return null; + }, + + isCollapsed : function() { + var r = this.getRng(); + + if (r.item) + return false; + + return r.boundingWidth == 0 || this.getSel().isCollapsed; + }, + + collapse : function(b) { + var r = this.getRng(), s = this.getSel(); + + if (r.select) { + r.collapse(b); + r.select(); + } else { + if (b) + s.collapseToStart(); + else + s.collapseToEnd(); + } }, getFocusElement : function() { @@ -7006,13 +7196,21 @@ }, show : function() { - this.getElement().style.display = 'block'; - this.updateBlocker(); + var el = this.getElement(); + + if (el) { + el.style.display = 'block'; + this.updateBlocker(); + } }, hide : function() { - this.getElement().style.display = 'none'; - this.updateBlocker(); + var el = this.getElement(); + + if (el) { + el.style.display = 'none'; + this.updateBlocker(); + } }, isVisible : function() { @@ -7117,6 +7315,16 @@ return 0; return parseInt(s); + }, + + remove : function() { + var e = this.getElement(), b = this.getBlocker(); + + if (e) + e.parentNode.removeChild(e); + + if (b) + b.parentNode.removeChild(b); } }; @@ -7208,7 +7416,7 @@ break; default: - h += '<tr><td><a href="#" onclick="return tinyMCE.cancelEvent(event);" onmousedown="return tinyMCE.cancelEvent(event);" onmouseup="' + tinyMCE.xmlEncode(m[i].js) + ';return tinyMCE.cancelEvent(event);"><span' + c +'>' + t + '</span></a>'; + h += '<tr><td><a href="' + tinyMCE.xmlEncode(m[i].js) + '" onmousedown="' + tinyMCE.xmlEncode(m[i].js) + ';return tinyMCE.cancelEvent(event);" onclick="return tinyMCE.cancelEvent(event);" onmouseup="return tinyMCE.cancelEvent(event);"><span' + c +'>' + t + '</span></a>'; } h += '</td></tr>'; -- Gitblit v1.9.1