/**\r
* $RCSfile: tiny_mce_src.js,v $\r
- * $Revision: 1.2 $\r
- * $Date: 2005/09/26 18:00:52 $\r
+ * $Revision: 1.281 $\r
+ * $Date: 2005/12/02 08:12:07 $\r
*\r
* @author Moxiecode\r
* @copyright Copyright © 2004, Moxiecode Systems AB, All rights reserved.\r
\r
function TinyMCE() {\r
this.majorVersion = "2";\r
- this.minorVersion = "0RC3";\r
- this.releaseDate = "2005-09-26";\r
+ this.minorVersion = "0";\r
+ this.releaseDate = "2005-12-01";\r
\r
this.instances = new Array();\r
this.stickyClassesLookup = new Array();\r
this.eventHandlers = new Array();\r
\r
// Browser check\r
+ var ua = navigator.userAgent;\r
this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");\r
- this.isMSIE5 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5') != -1);\r
- this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1);\r
- this.isGecko = navigator.userAgent.indexOf('Gecko') != -1;\r
- this.isSafari = navigator.userAgent.indexOf('Safari') != -1;\r
- this.isMac = navigator.userAgent.indexOf('Mac') != -1;\r
+ this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1);\r
+ this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);\r
+ this.isGecko = ua.indexOf('Gecko') != -1;\r
+ this.isSafari = ua.indexOf('Safari') != -1;\r
+ this.isOpera = ua.indexOf('Opera') != -1;\r
+ this.isMac = ua.indexOf('Mac') != -1;\r
+ this.isNS7 = ua.indexOf('Netscape/7') != -1;\r
+ this.isNS71 = ua.indexOf('Netscape/7.1') != -1;\r
this.dialogCounter = 0;\r
\r
+ // Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those\r
+ if (this.isOpera) {\r
+ this.isMSIE = true;\r
+ this.isGecko = false;\r
+ this.isSafari = false;\r
+ }\r
+\r
// TinyMCE editor id instance counter\r
this.idCounter = 0;\r
};\r
var elements = document.getElementsByTagName('script');\r
\r
for (var i=0; i<elements.length; i++) {\r
- if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip.php") != -1)) {\r
+ if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) {\r
var src = elements[i].src;\r
\r
tinyMCE.srcMode = (src.indexOf('_src') != -1) ? '_src' : '';\r
this.defParam("textarea_trigger", "mce_editable");\r
this.defParam("editor_selector", "");\r
this.defParam("editor_deselector", "mceNoEditor");\r
- this.defParam("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/b[class|style],-em/i[class|style],-strike[class|style],-u[class|style],+p[style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border=0|alt|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],-td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[style|dir|class|align],-h2[style|dir|class|align],-h3[style|dir|class|align],-h4[style|dir|class|align],-h5[style|dir|class|align],-h6[style|dir|class|align],hr[class|style]");\r
+ this.defParam("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/b[class|style],-em/i[class|style],-strike[class|style],-u[class|style],+p[style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border=0|alt|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],-td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[style|dir|class|align],-h2[style|dir|class|align],-h3[style|dir|class|align],-h4[style|dir|class|align],-h5[style|dir|class|align],-h6[style|dir|class|align],hr[class|style],font[face|size|style|id|class|dir|color]");\r
this.defParam("extended_valid_elements", "");\r
this.defParam("invalid_elements", "");\r
this.defParam("encoding", "");\r
this.defParam("remove_linebreaks", true);\r
this.defParam("button_tile_map", false);\r
this.defParam("submit_patch", true);\r
- this.defParam("browsers", "msie,safari,gecko");\r
+ this.defParam("browsers", "msie,safari,gecko,opera");\r
this.defParam("dialog_type", "window");\r
- this.defParam("convert_fonts_to_styles", true);\r
this.defParam("accessibility_warnings", true);\r
+ this.defParam("merge_styles_invalid_parents", "");\r
+ this.defParam("force_hex_style_colors", true);\r
+ this.defParam("trim_span_elements", true);\r
+ this.defParam("convert_fonts_to_spans", false);\r
+ this.defParam("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">');\r
+ this.defParam("font_size_classes", '');\r
+ this.defParam("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large');\r
+ this.defParam("event_elements", 'a,img');\r
+ this.defParam("convert_urls", true);\r
+ this.defParam("table_inline_editing", false);\r
+ this.defParam("object_resizing", true);\r
\r
// Browser check IE\r
if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)\r
if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)\r
return;\r
\r
- // Setup baseHREF\r
+ // Browser check Opera\r
+ if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)\r
+ return;\r
+\r
+ // If not super absolute make it so\r
var baseHREF = tinyMCE.settings['document_base_url'];\r
+ var h = document.location.href;\r
+ var p = h.indexOf('://');\r
+ if (p > 0 && document.location.protocol != "file:") {\r
+ p = h.indexOf('/', p + 3);\r
+ h = h.substring(0, p);\r
+\r
+ if (baseHREF.indexOf('://') == -1)\r
+ baseHREF = h + baseHREF;\r
+\r
+ tinyMCE.settings['document_base_url'] = baseHREF;\r
+ tinyMCE.settings['document_base_prefix'] = h;\r
+ }\r
+\r
+ // Trim away query part\r
if (baseHREF.indexOf('?') != -1)\r
baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));\r
+\r
this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";\r
\r
theme = this.settings['theme'];\r
-\r
- this.blockRegExp = new RegExp("^(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td)$", "i");\r
+ this.blockRegExp = new RegExp("^(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|blockquote|center|dl|dir|fieldset|form|noscript|noframes|menu|isindex)$", "i");\r
this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);\r
+ this.uniqueURL = 'http://tinymce.moxiecode.cp/mce_temp_url'; // Make unique URL non real URL\r
+ this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';\r
\r
// Theme url\r
this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;\r
if (this.configs.length == 0) {\r
// Is Safari enabled\r
if (this.isSafari && this.getParam('safari_warning', true))\r
- alert("Safari support is very limited and should be considered experimental.\nSo there is no need to even submit bugreports on this early version.");\r
+ alert("Safari support is very limited and should be considered experimental.\nSo there is no need to even submit bugreports on this early version.\nYou can disable this message by setting: safari_warning option to false");\r
\r
tinyMCE.addEvent(window, "load", TinyMCE.prototype.onLoad);\r
\r
this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] + '.js');\r
this.loadCSS(this.settings['editor_css']);\r
\r
- // Add theme plugins\r
+ // Add plugins\r
var themePlugins = tinyMCE.getParam('plugins', '', true, ',');\r
if (this.settings['plugins'] != '') {\r
for (var i=0; i<themePlugins.length; i++)\r
this.loadScript(tinyMCE.baseURL + '/plugins/' + themePlugins[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');\r
}\r
\r
+ // Setup entities\r
+ settings['cleanup_entities'] = new Array();\r
+ var entities = tinyMCE.getParam('entities', '', true, ',');\r
+ for (var i=0; i<entities.length; i+=2)\r
+ settings['cleanup_entities']['c' + entities[i]] = entities[i+1];\r
+\r
// Save away this config\r
settings['index'] = this.configs.length;\r
this.configs[this.configs.length] = settings;\r
if (css_file == '')\r
return;\r
\r
- if (tinyMCE.isMSIE)\r
- var styleSheet = doc.createStyleSheet(css_file);\r
- else {\r
+ if (typeof(doc.createStyleSheet) == "undefined") {\r
var elm = doc.createElement("link");\r
\r
elm.rel = "stylesheet";\r
elm.href = css_file;\r
\r
- if (headArr = doc.getElementsByTagName("head"))\r
+ if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0)\r
headArr[0].appendChild(elm);\r
- }\r
+ } else\r
+ var styleSheet = doc.createStyleSheet(css_file);\r
};\r
\r
TinyMCE.prototype.confirmAdd = function(e, settings) {\r
var formElement = document.getElementById(form_element_name);\r
for (var n in tinyMCE.instances) {\r
var inst = tinyMCE.instances[n];\r
- if (typeof(inst) == 'function')\r
+ if (!tinyMCE.isInstance(inst))\r
continue;\r
\r
inst.switchSettings();\r
// Cleanup and set all form fields\r
for (var n in tinyMCE.instances) {\r
var inst = tinyMCE.instances[n];\r
- if (typeof(inst) == 'function')\r
+ if (!tinyMCE.isInstance(inst))\r
continue;\r
\r
inst.switchSettings();\r
// Remove visual aids when cleanup is disabled\r
if (inst.settings['cleanup'] == false) {\r
tinyMCE.handleVisualAid(inst.getBody(), true, false, inst);\r
- tinyMCE._setEventsEnabled(inst.getBody(), false);\r
+ tinyMCE._setEventsEnabled(inst.getBody(), true);\r
}\r
\r
tinyMCE._customCleanup(inst, "submit_content_dom", inst.contentWindow.document.body);\r
'onmousedown','onmouseup','onmouseover','onmousemove',\r
'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup');\r
\r
- var elms = node.getElementsByTagName("a");\r
- for (var i=0; i<elms.length; i++) {\r
- var event = "";\r
+ var evs = tinyMCE.settings['event_elements'].split(',');\r
+ for (var y=0; y<evs.length; y++){\r
+ var elms = node.getElementsByTagName(evs[y]);\r
+ for (var i=0; i<elms.length; i++) {\r
+ var event = "";\r
\r
- for (var x=0; x<events.length; x++) {\r
- if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {\r
- event = tinyMCE.cleanupEventStr("" + event);\r
+ for (var x=0; x<events.length; x++) {\r
+ if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {\r
+ event = tinyMCE.cleanupEventStr("" + event);\r
\r
- if (state)\r
- event = "return true;" + event;\r
- else\r
- event = event.replace(/^return true;/gi, '');\r
+ if (!state)\r
+ event = "return true;" + event;\r
+ else\r
+ event = event.replace(/^return true;/gi, '');\r
\r
- elms[i].removeAttribute(events[x]);\r
- elms[i].setAttribute(events[x], event);\r
+ elms[i].removeAttribute(events[x]);\r
+ elms[i].setAttribute(events[x], event);\r
+ }\r
}\r
}\r
}\r
\r
for (var n in tinyMCE.instances) {\r
var inst = tinyMCE.instances[n];\r
- if (typeof(inst) == 'function')\r
+ if (!tinyMCE.isInstance(inst))\r
continue;\r
\r
inst.switchSettings();\r
\r
for (var i=0; i<formObj.elements.length; i++) {\r
- if (inst.formTargetElementId == formObj.elements[i].name) {\r
- inst.getBody().innerHTML = formObj.elements[i].value;\r
- return;\r
- }\r
+ if (inst.formTargetElementId == formObj.elements[i].name)\r
+ inst.getBody().innerHTML = inst.startContent;\r
}\r
}\r
};\r
this.selectedElement = inst.getFocusElement();\r
this.selectedInstance = inst;\r
tinyMCE.execCommand(command, user_interface, value);\r
+\r
+ // Cancel event so it doesn't call onbeforeonunlaod\r
+ if (tinyMCE.isMSIE && window.event != null)\r
+ tinyMCE.cancelEvent(window.event);\r
}\r
};\r
\r
// Resets the designmode state of the editors in Gecko\r
if (!tinyMCE.isMSIE) {\r
for (var n in tinyMCE.instances) {\r
- if (typeof(tinyMCE.instances[n]) == 'function')\r
+ if (!tinyMCE.isInstance(tinyMCE.instances[n]))\r
continue;\r
\r
try {\r
return;\r
}\r
\r
- if (this.selectedInstance)\r
+ if (this.selectedInstance) {\r
this.selectedInstance.execCommand(command, user_interface, value);\r
- else if (tinyMCE.settings['focus_alert'])\r
+ } else if (tinyMCE.settings['focus_alert'])\r
alert(tinyMCELang['lang_focus_alert']);\r
};\r
\r
if (document.frames[i].event) {\r
var event = document.frames[i].event;\r
\r
- event.target = event.srcElement;\r
+ if (!event.target)\r
+ event.target = event.srcElement;\r
\r
TinyMCE.prototype.handleEvent(event);\r
return;\r
TinyMCE.prototype._createIFrame = function(replace_element) {\r
var iframe = document.createElement("iframe");\r
var id = replace_element.getAttribute("id");\r
+ var aw, ah;\r
+\r
+ aw = "" + tinyMCE.settings['area_width'];\r
+ ah = "" + tinyMCE.settings['area_height'];\r
+\r
+ if (aw.indexOf('%') == -1) {\r
+ aw = parseInt(aw);\r
+ aw = aw < 0 ? 300 : aw;\r
+ aw = aw + "px";\r
+ }\r
+\r
+ if (ah.indexOf('%') == -1) {\r
+ ah = parseInt(ah);\r
+ ah = ah < 0 ? 240 : ah;\r
+ ah = ah + "px";\r
+ }\r
\r
iframe.setAttribute("id", id);\r
//iframe.setAttribute("className", "mceEditorArea");\r
iframe.setAttribute("marginHeight", "0");\r
iframe.setAttribute("leftMargin", "0");\r
iframe.setAttribute("topMargin", "0");\r
- iframe.setAttribute("width", tinyMCE.settings['area_width']);\r
- iframe.setAttribute("height", tinyMCE.settings['area_height']);\r
+ iframe.setAttribute("width", aw);\r
+ iframe.setAttribute("height", ah);\r
iframe.setAttribute("allowtransparency", "true");\r
\r
if (tinyMCE.settings["auto_resize"])\r
iframe.setAttribute("scrolling", "no");\r
\r
// Must have a src element in MSIE HTTPs breaks aswell as absoute URLs\r
- if (tinyMCE.isMSIE)\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera)\r
iframe.setAttribute("src", this.settings['default_document']);\r
\r
- iframe.style.width = tinyMCE.settings['area_width'];\r
- iframe.style.height = tinyMCE.settings['area_height'];\r
+ iframe.style.width = aw;\r
+ iframe.style.height = ah;\r
\r
// MSIE 5.0 issue\r
- if (tinyMCE.isMSIE)\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera)\r
replace_element.outerHTML = iframe.outerHTML;\r
else\r
replace_element.parentNode.replaceChild(iframe, replace_element);\r
var head = doc.getElementsByTagName('head').item(0);\r
var content = inst.startContent;\r
\r
+ tinyMCE.operaOpacityCounter = 100 * tinyMCE.idCounter;\r
+\r
inst.switchSettings();\r
\r
// Not loaded correctly hit it again, Mozilla bug #997860\r
- if (!tinyMCE.isMSIE && doc.title != "blank_page") {\r
+ if (!tinyMCE.isMSIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") {\r
// This part will remove the designMode status\r
- doc.location.href = tinyMCE.baseURL + "/blank.htm";\r
+ // Failes first time in Firefox 1.5b2 on Mac\r
+ try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {}\r
window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000);\r
return;\r
}\r
tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);\r
tinyMCE.executeCallback('init_instance_callback', '_initInstance', 0, inst);\r
\r
+ // Setup span styles\r
+ if (tinyMCE.getParam("convert_fonts_to_spans"))\r
+ inst.getDoc().body.setAttribute('id', 'mceSpanFonts');\r
+\r
if (tinyMCE.settings['nowrap'])\r
doc.body.style.whiteSpace = "nowrap";\r
\r
}\r
\r
// Open closed anchors\r
- content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');\r
- content = content.replace(new RegExp('<a(.*?)name="(.*?)"(.*?)>(.*?)</a>', 'gi'), '<a$1name="$2"$3></a>$4');\r
+// content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');\r
\r
// Call custom cleanup code\r
+ content = tinyMCE.storeAwayURLs(content);\r
content = tinyMCE._customCleanup(inst, "insert_to_editor", content);\r
\r
if (tinyMCE.isMSIE) {\r
body.editorId = editor_id;\r
}\r
\r
+ content = tinyMCE.cleanupHTMLCode(content);\r
+\r
// Fix for bug #958637\r
if (!tinyMCE.isMSIE) {\r
var contentElement = inst.getDoc().createElement("body");\r
contentElement.innerHTML = content;\r
\r
// Remove weridness!\r
- if (tinyMCE.settings['force_p_newlines'])\r
+ if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])\r
content = content.replace(new RegExp('<>', 'g'), "");\r
\r
if (tinyMCE.settings['cleanup_on_startup'])\r
- inst.getBody().innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement);\r
+ tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));\r
else {\r
// Convert all strong/em to b/i\r
content = tinyMCE.regexpReplace(content, "<strong", "<b", "gi");\r
content = tinyMCE.regexpReplace(content, "<em ", "<i ", "gi");\r
content = tinyMCE.regexpReplace(content, "</strong>", "</b>", "gi");\r
content = tinyMCE.regexpReplace(content, "</em>", "</i>", "gi");\r
- inst.getBody().innerHTML = content;\r
+ tinyMCE.setInnerHTML(inst.getBody(), content);\r
}\r
\r
inst.convertAllRelativeURLs();\r
tinyMCE._setHTML(inst.getDoc(), content);\r
\r
// Produces permission denied error in MSIE 5.5\r
- eval('try {inst.getBody().innerHTML = tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody());} catch(e) {}');\r
+ eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');\r
} else\r
tinyMCE._setHTML(inst.getDoc(), content);\r
}\r
\r
// Setup element references\r
var parentElm = document.getElementById(inst.editorId + '_parent');\r
- if (parentElm.lastChild.nodeName.toLowerCase() == "input")\r
- inst.formElement = parentElm.lastChild;\r
+ if (parentElm.lastChild.nodeName == "INPUT")\r
+ inst.formElement = tinyMCE.isGecko ? parentElm.firstChild : parentElm.lastChild;\r
else\r
- inst.formElement = parentElm.nextSibling;\r
+ inst.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;\r
\r
tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);\r
tinyMCE.executeCallback('setupcontent_callback', '_setupContent', 0, editor_id, inst.getBody(), inst.getDoc());\r
// Trigger node change, this call locks buttons for tables and so forth\r
tinyMCE.selectedInstance = inst;\r
tinyMCE.selectedElement = inst.contentWindow.document.body;\r
- tinyMCE.triggerNodeChange(false, true);\r
+\r
+ if (!inst.isHidden())\r
+ tinyMCE.triggerNodeChange(false, true);\r
\r
// Call custom DOM cleanup\r
tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody());\r
tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody());\r
- tinyMCE._setEventsEnabled(inst.getBody(), true);\r
+ tinyMCE._setEventsEnabled(inst.getBody(), false);\r
+ tinyMCE.cleanupAnchors(inst.getDoc());\r
+\r
+ if (tinyMCE.getParam("convert_fonts_to_spans"))\r
+ tinyMCE.convertSpansToFonts(inst.getDoc());\r
\r
inst.startContent = tinyMCE.trim(inst.getBody().innerHTML);\r
inst.undoLevels[inst.undoLevels.length] = inst.startContent;\r
+\r
+ tinyMCE.operaOpacityCounter = -1;\r
+};\r
+\r
+TinyMCE.prototype.cleanupHTMLCode = function(s) {\r
+ s = s.replace(/<p \/>/gi, '<p> </p>');\r
+ s = s.replace(/<p>\s*<\/p>/gi, '<p> </p>');\r
+\r
+ // Open closed tags like <b/> to <b></b>\r
+// tinyMCE.debug("f:" + s);\r
+ s = s.replace(/<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\|>]*?)\/>/gi, '<$1$2$3></$1$2>');\r
+// tinyMCE.debug("e:" + s);\r
+\r
+ // Remove trailing space <b > to <b>\r
+ s = s.replace(new RegExp('\\s+></', 'gi'), '></');\r
+\r
+ // Close tags <img></img> to <img/>\r
+ s = s.replace(/<(img|br|hr)(.*?)><\/(img|br|hr)>/gi, '<$1$2 />');\r
+\r
+ // Weird MSIE bug, <p><hr /></p> breaks runtime?\r
+ if (tinyMCE.isMSIE)\r
+ s = s.replace(/<p><hr \/><\/p>/gi, "<hr>");\r
+\r
+ // Convert relative anchors to absolute URLs ex: #something to file.htm#something\r
+ s = s.replace(new RegExp('(href=\"?)(\\s*?#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");\r
+\r
+ return s;\r
+};\r
+\r
+TinyMCE.prototype.storeAwayURLs = function(s) {\r
+ // Remove all mce_src, mce_href and replace them with new ones\r
+ s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');\r
+ s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');\r
+ s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"');\r
+ s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"');\r
+\r
+ return s;\r
};\r
\r
TinyMCE.prototype.cancelEvent = function(e) {\r
};\r
\r
TinyMCE.prototype.removeTinyMCEFormElements = function(form_obj) {\r
+ // Check if form is valid\r
+ if (typeof(form_obj) == "undefined" || form_obj == null)\r
+ return;\r
+\r
+ // If not a form, find the form\r
+ if (form_obj.nodeName != "FORM") {\r
+ if (form_obj.form)\r
+ form_obj = form_obj.form;\r
+ else\r
+ form_obj = tinyMCE.getParentElement(form_obj, "form");\r
+ }\r
+\r
+ // Still nothing\r
+ if (form_obj == null)\r
+ return;\r
+\r
// Disable all UI form elements that TinyMCE created\r
for (var i=0; i<form_obj.elements.length; i++) {\r
var elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id;\r
if (tinyMCE.selectedInstance._handleBackSpace(e.type)) {\r
// Cancel event\r
tinyMCE.execCommand("mceAddUndoLevel");\r
- e.preventDefault();\r
+ tinyMCE.cancelEvent(e);\r
return false;\r
}\r
}\r
\r
// Mozilla custom key handling\r
- if (tinyMCE.isGecko && e.ctrlKey && tinyMCE.settings['custom_undo_redo']) {\r
+ if (tinyMCE.isGecko && (e.ctrlKey && !e.altKey) && tinyMCE.settings['custom_undo_redo']) {\r
if (tinyMCE.settings['custom_undo_redo_keyboard_shortcuts']) {\r
if (e.charCode == 122) { // Ctrl+Z\r
tinyMCE.selectedInstance.execCommand("Undo");\r
-\r
- // Cancel event\r
- e.preventDefault();\r
+ tinyMCE.cancelEvent(e);\r
return false;\r
}\r
\r
if (e.charCode == 121) { // Ctrl+Y\r
tinyMCE.selectedInstance.execCommand("Redo");\r
-\r
- // Cancel event\r
- e.preventDefault();\r
+ tinyMCE.cancelEvent(e);\r
return false;\r
}\r
}\r
\r
if (e.charCode == 98) { // Ctrl+B\r
tinyMCE.selectedInstance.execCommand("Bold");\r
-\r
- // Cancel event\r
- e.preventDefault();\r
+ tinyMCE.cancelEvent(e);\r
return false;\r
}\r
\r
if (e.charCode == 105) { // Ctrl+I\r
tinyMCE.selectedInstance.execCommand("Italic");\r
-\r
- // Cancel event\r
- e.preventDefault();\r
+ tinyMCE.cancelEvent(e);\r
return false;\r
}\r
\r
if (e.charCode == 117) { // Ctrl+U\r
tinyMCE.selectedInstance.execCommand("Underline");\r
-\r
- // Cancel event\r
- e.preventDefault();\r
+ tinyMCE.cancelEvent(e);\r
return false;\r
}\r
}\r
if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)\r
tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);\r
\r
- // Run image/link fix on Gecko if diffrent document base on paste\r
- if (tinyMCE.isGecko && tinyMCE.settings['document_base_url'] != "" + document.location.href && e.type == "keyup" && e.ctrlKey && e.keyCode == 86)\r
- tinyMCE.selectedInstance.fixBrokenURLs();\r
-\r
// Fix empty elements on return/enter, check where enter occured\r
if (tinyMCE.isMSIE && e.type == "keydown" && e.keyCode == 13)\r
tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement();\r
}\r
}\r
\r
- //tinyMCE.debug(e.keyCode);\r
-\r
// MSIE custom key handling\r
if (tinyMCE.isMSIE && tinyMCE.settings['custom_undo_redo']) {\r
var keys = new Array(8,46); // Backspace,Delete\r
}\r
\r
if (tinyMCE.settings['custom_undo_redo_keyboard_shortcuts']) {\r
- if (e.keyCode == 90 && e.ctrlKey && e.type == "keydown") { // Ctrl+Z\r
+ if (e.keyCode == 90 && (e.ctrlKey && !e.altKey) && e.type == "keydown") { // Ctrl+Z\r
tinyMCE.selectedInstance.execCommand("Undo");\r
tinyMCE.triggerNodeChange(false);\r
}\r
\r
- if (e.keyCode == 89 && e.ctrlKey && e.type == "keydown") { // Ctrl+Y\r
+ if (e.keyCode == 89 && (e.ctrlKey && !e.altKey) && e.type == "keydown") { // Ctrl+Y\r
tinyMCE.selectedInstance.execCommand("Redo");\r
tinyMCE.triggerNodeChange(false);\r
}\r
\r
- if ((e.keyCode == 90 || e.keyCode == 89) && e.ctrlKey) {\r
+ if ((e.keyCode == 90 || e.keyCode == 89) && (e.ctrlKey && !e.altKey)) {\r
// Cancel event\r
e.returnValue = false;\r
e.cancelBubble = true;\r
}\r
}\r
\r
+ // If undo/redo key\r
+ if ((e.keyCode == 90 || e.keyCode == 89) && (e.ctrlKey && !e.altKey))\r
+ return true;\r
+\r
+ // If Ctrl key\r
+ if (e.keyCode == 17)\r
+ return true;\r
+\r
// Handle Undo/Redo when typing content\r
\r
// Start typing (non position key)\r
\r
if (posKey && e.type == "keyup")\r
tinyMCE.triggerNodeChange(false);\r
+\r
+ if (tinyMCE.isMSIE && e.ctrlKey)\r
+ window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);\r
break;\r
\r
case "mousedown":\r
// Check instance event trigged on\r
var targetBody = tinyMCE.getParentElement(e.target, "body");\r
for (var instanceName in tinyMCE.instances) {\r
- if (typeof(tinyMCE.instances[instanceName]) == 'function')\r
+ if (!tinyMCE.isInstance(tinyMCE.instances[instanceName]))\r
continue;\r
\r
var inst = tinyMCE.instances[instanceName];\r
if (!tinyMCE.selectedInstance && e.target.editorId)\r
tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];\r
\r
- // Run image/link fix on Gecko if diffrent document base\r
- if (tinyMCE.isGecko && tinyMCE.settings['document_base_url'] != "" + document.location.href)\r
- window.setTimeout('tinyMCE.getInstanceById("' + inst.editorId + '").fixBrokenURLs();', 10);\r
-\r
return false;\r
break;\r
} // end switch\r
if (element != null && (lockChanged || !element.classLock)) {\r
element.className = class_name;\r
element.oldClassName = class_name;\r
+\r
+ // Fix opacity in Opera\r
+ if (tinyMCE.isOpera) {\r
+ if (class_name == "mceButtonDisabled") {\r
+ var suffix = "";\r
+\r
+ if (!element.mceOldSrc)\r
+ element.mceOldSrc = element.src;\r
+\r
+ if (this.operaOpacityCounter > -1)\r
+ suffix = '?rnd=' + this.operaOpacityCounter++;\r
+\r
+ element.src = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/images/opacity.png" + suffix;\r
+ element.style.backgroundImage = "url('" + element.mceOldSrc + "')";\r
+ } else {\r
+ if (element.mceOldSrc) {\r
+ element.src = element.mceOldSrc;\r
+ element.parentNode.style.backgroundImage = "";\r
+ element.mceOldSrc = null;\r
+ }\r
+ }\r
+ }\r
}\r
};\r
\r
if (selector != '' && tinyMCE.getAttrib(elm, "class").indexOf(selector) == -1)\r
continue;\r
\r
+ if (selector != '')\r
+ trigger = selector != "" ? "true" : "";\r
+\r
if (tinyMCE.getAttrib(elm, "class").indexOf(deselector) != -1)\r
continue;\r
\r
var tmpInstances = new Array();\r
for (var instanceName in tinyMCE.instances) {\r
var instance = tinyMCE.instances[instanceName];\r
- if (typeof(instance) == 'function')\r
+ if (!tinyMCE.isInstance(instance))\r
continue;\r
\r
if (instanceName != editor_id)\r
\r
switch (attrib) {\r
case "background":\r
- val = "url('" + val + "');";\r
+ val = "url('" + val + "')";\r
break;\r
\r
case "bordercolor":\r
if (attribName.indexOf('moz_') != -1)\r
return null;\r
\r
- // Mozilla fix for drag-drop/copy/paste images\r
- if (!tinyMCE.isMSIE && (attribName == "mce_real_href" || attribName == "mce_real_src")) {\r
- if (!tinyMCE.cleanup_on_save) {\r
- var attrib = new Object();\r
-\r
- attrib.name = attribName;\r
- attrib.value = attribValue;\r
-\r
- return attrib;\r
- } else\r
- return null;\r
- }\r
-\r
- // Auto verify \r
- if (attribName == "mce_onclick")\r
- verified = true;\r
+ if (!tinyMCE.cleanup_on_save && (attribName == "mce_href" || attribName == "mce_src"))\r
+ return {name : attribName, value : attribValue};\r
\r
// Verify attrib\r
if (tinyMCE.cleanup_verify_html && !verified) {\r
attribValue = attribValue.toLowerCase();\r
break;\r
\r
+ case "cellspacing":\r
+ if (tinyMCE.isMSIE5)\r
+ attribValue = element_node.cellSpacing;\r
+ break;\r
+\r
+ case "cellpadding":\r
+ if (tinyMCE.isMSIE5)\r
+ attribValue = element_node.cellPadding;\r
+ break;\r
+\r
case "color":\r
if (tinyMCE.isMSIE5 && element_name == "font")\r
attribValue = element_node.color;\r
break;\r
\r
case "class":\r
+ // Remove mceItem classes from anchors\r
+ if (tinyMCE.cleanup_on_save && attribValue.indexOf('mceItemAnchor') != -1)\r
+ attribValue = attribValue.replace(/mceItem[a-z0-9]+/gi, '');\r
+\r
if (element_name == "table" || element_name == "td") {\r
// Handle visual aid\r
if (tinyMCE.cleanup_visual_table_class != "")\r
break;\r
\r
case "style":\r
- attribValue = tinyMCE.serializeStyle(tinyMCE.parseStyle(element_node.style.cssText));\r
+ attribValue = tinyMCE.serializeStyle(tinyMCE.parseStyle(tinyMCE.getAttrib(element_node, "style")));\r
break;\r
\r
// Convert the URLs of these\r
case "href":\r
case "src":\r
- // Fix for dragdrop/copy paste Mozilla issue\r
- if (!tinyMCE.isMSIE && attribName == "href" && element_node.getAttribute("mce_real_href"))\r
- attribValue = element_node.getAttribute("mce_real_href");\r
+ case "longdesc":\r
+ attribValue = tinyMCE.getAttrib(element_node, attribName);\r
\r
- // Fix for dragdrop/copy paste Mozilla issue\r
- if (!tinyMCE.isMSIE && attribName == "src" && element_node.getAttribute("mce_real_src"))\r
- attribValue = element_node.getAttribute("mce_real_src");\r
+ // Use mce_href instead\r
+ var href = tinyMCE.getAttrib(element_node, "mce_href");\r
+ if (attribName == "href" && href != "")\r
+ attribValue = href;\r
\r
- // Force absolute URLs in Firefox\r
- if (tinyMCE.isGecko && !tinyMCE.settings['relative_urls'])\r
+ // Use mce_src instead\r
+ var src = tinyMCE.getAttrib(element_node, "mce_src");\r
+ if (attribName == "src" && src != "")\r
+ attribValue = src;\r
+\r
+ // Always use absolute URLs within TinyMCE\r
+ if (!tinyMCE.cleanup_on_save)\r
attribValue = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], attribValue);\r
+ else if (tinyMCE.getParam('convert_urls'))\r
+ attribValue = eval(tinyMCE.cleanup_urlconverter_callback + "(attribValue, element_node, tinyMCE.cleanup_on_save);");\r
\r
- attribValue = eval(tinyMCE.cleanup_urlconverter_callback + "(attribValue, element_node, tinyMCE.cleanup_on_save);");\r
break;\r
\r
case "colspan":\r
// Skip these\r
case "_moz-userdefined":\r
case "editorid":\r
- case "mce_real_href":\r
- case "mce_real_src":\r
+ case "mce_href":\r
+ case "mce_src":\r
return null;\r
}\r
\r
return attrib;\r
};\r
\r
+TinyMCE.prototype.clearArray = function(ar) {\r
+ // Since stupid people tend to extend core objects like\r
+ // Array with their own crap I needed to make functions that clean away\r
+ // this junk so the arrays get clean and nice as they should be\r
+ for (var key in ar)\r
+ ar[key] = null;\r
+};\r
+\r
+TinyMCE.prototype.isInstance = function(inst) {\r
+ return inst != null && typeof(inst) == "object" && inst.isTinyMCEControl;\r
+};\r
+\r
TinyMCE.prototype.parseStyle = function(str) {\r
var ar = new Array();\r
+\r
+ if (str == null)\r
+ return ar;\r
+\r
var st = str.split(';');\r
\r
+ tinyMCE.clearArray(ar);\r
+\r
for (var i=0; i<st.length; i++) {\r
if (st[i] == '')\r
continue;\r
// Fix style URL\r
val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')");\r
\r
+ // Convert URL\r
+ if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) {\r
+ var m = new RegExp("url\\('(.*?)'\\)").exec(val);\r
+\r
+ if (m.length > 1)\r
+ val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')";\r
+ }\r
+\r
+ // Force HEX colors\r
+ if (tinyMCE.getParam("force_hex_style_colors"))\r
+ val = tinyMCE.convertRGBToHex(val, true);\r
+\r
if (val != "url('')")\r
str += key.toLowerCase() + ": " + val + "; ";\r
}\r
return str;\r
};\r
\r
+TinyMCE.prototype.convertRGBToHex = function(s, k) {\r
+ if (s.toLowerCase().indexOf('rgb') != -1) {\r
+ var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");\r
+ var rgb = s.replace(re, "$1,$2,$3,$4,$5").split(',');\r
+ if (rgb.length == 5) {\r
+ r = parseInt(rgb[1]).toString(16);\r
+ g = parseInt(rgb[2]).toString(16);\r
+ b = parseInt(rgb[3]).toString(16);\r
+\r
+ r = r.length == 1 ? '0' + r : r;\r
+ g = g.length == 1 ? '0' + g : g;\r
+ b = b.length == 1 ? '0' + b : b;\r
+\r
+ s = "#" + r + g + b;\r
+\r
+ if (k)\r
+ s = rgb[0] + s + rgb[4];\r
+ }\r
+ }\r
+\r
+ return s;\r
+};\r
+\r
+TinyMCE.prototype.convertHexToRGB = function(s) {\r
+ if (s.indexOf('#') != -1) {\r
+ s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');\r
+ return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")";\r
+ }\r
+\r
+ return s;\r
+};\r
+\r
TinyMCE.prototype._verifyClass = function(node) {\r
// Sometimes the class gets set to null, weird Gecko bug?\r
if (tinyMCE.isGecko) {\r
if (re.test(node.nodeName)) {\r
// Move attrib to style\r
if ((node.nodeName != "TABLE" || tinyMCE.cleanup_inline_styles) && (width = tinyMCE.getAttrib(node, "width")) != '') {\r
- node.style.width = width.indexOf('%') == -1 ? width : width + "px";\r
+ node.style.width = width.indexOf('%') != -1 ? width : width.replace(/[^0-9]/gi, '') + "px";\r
node.removeAttribute("width");\r
}\r
\r
\r
// Move attrib to style\r
if ((height = tinyMCE.getAttrib(node, "height")) != '') {\r
- node.style.height = height.indexOf('%') == -1 ? height : height + "px";\r
+ height = "" + height; // Force string\r
+ node.style.height = height.indexOf('%') != -1 ? height : height.replace(/[^0-9]/gi, '') + "px";\r
node.removeAttribute("height");\r
}\r
}\r
// Handle inline/outline styles\r
if (tinyMCE.cleanup_inline_styles) {\r
var re = new RegExp("^(TABLE|TD|TR|IMG|HR)$");\r
- if (re.test(node.nodeName)) {\r
+ if (re.test(node.nodeName) && tinyMCE.getAttrib(node, "class").indexOf('mceItem') == -1) {\r
tinyMCE._moveStyle(node, 'width', 'width');\r
tinyMCE._moveStyle(node, 'height', 'height');\r
tinyMCE._moveStyle(node, 'borderWidth', 'border');\r
}\r
}\r
\r
+ if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && elementName == "style")\r
+ return "<style>" + node.innerHTML + "</style>";\r
+\r
// Remove empty tables\r
if (elementName == "table" && !node.hasChildNodes())\r
return "";\r
\r
// Handle element attributes\r
if (node.attributes.length > 0) {\r
+ var lastAttrib = "";\r
+\r
for (var i=0; i<node.attributes.length; i++) {\r
- if (node.attributes[i].specified || (node.attributes[i].nodeValue != null && node.attributes[i].nodeValue.length > 0)) {\r
- // tinyMCE.debug(node.attributes[i].nodeName + "=" + node.attributes[i].nodeValue);\r
+ if (node.attributes[i].specified) {\r
+ // Is the attrib already processed (removed duplicate attributes in opera TD[align=left])\r
+ if (tinyMCE.isOpera) {\r
+ if (node.attributes[i].nodeName == lastAttrib)\r
+ continue;\r
+\r
+ lastAttrib = node.attributes[i].nodeName;\r
+ }\r
+\r
+ // tinyMCE.debug(node.nodeName, node.attributes[i].nodeName, node.attributes[i].nodeValue, node.innerHTML);\r
var attrib = tinyMCE._cleanupAttribute(elementValidAttribs, elementName, node.attributes[i], node);\r
if (attrib && attrib.value != "")\r
elementAttribs += " " + attrib.name + "=" + '"' + this.convertStringToXML("" + attrib.value) + '"';\r
elementAttribs += " summary=" + '"' + this.convertStringToXML(summary) + '"';\r
}\r
\r
+ // Handle missing attributes in MSIE 5.5\r
+ if (tinyMCE.isMSIE5 && /^(td|img|a)$/.test(elementName)) {\r
+ var ma = new Array("scope", "longdesc", "hreflang", "charset", "type");\r
+\r
+ for (var u=0; u<ma.length; u++) {\r
+ if (node.getAttribute(ma[u]) != null) {\r
+ var s = tinyMCE.getAttrib(node, ma[u]);\r
+\r
+ if (s != '')\r
+ elementAttribs += " " + ma[u] + "=" + '"' + this.convertStringToXML(s) + '"';\r
+ }\r
+ }\r
+ }\r
+\r
// MSIE form element issue\r
if (tinyMCE.isMSIE && elementName == "input") {\r
if (node.type) {\r
\r
// Clean up children\r
if (node.hasChildNodes()) {\r
- // Force BR\r
- if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)\r
- output += "<div" + elementAttribs + ">";\r
- else\r
- output += "<" + elementName + elementAttribs + ">";\r
+ // If not empty span\r
+ if (!(elementName == "span" && elementAttribs == "" && tinyMCE.getParam("trim_span_elements"))) {\r
+ // Force BR\r
+ if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)\r
+ output += "<div" + elementAttribs + ">";\r
+ else\r
+ output += "<" + elementName + elementAttribs + ">";\r
+ }\r
\r
for (var i=0; i<node.childNodes.length; i++)\r
output += this.cleanupNode(node.childNodes[i]);\r
\r
- // Force BR\r
- if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)\r
- output += "</div><br />";\r
- else\r
- output += "</" + elementName + ">";\r
+ // If not empty span\r
+ if (!(elementName == "span" && elementAttribs == "" && tinyMCE.getParam("trim_span_elements"))) {\r
+ // Force BR\r
+ if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)\r
+ output += "</div><br />";\r
+ else\r
+ output += "</" + elementName + ">";\r
+ }\r
} else {\r
if (!nonEmptyTag) {\r
if (openTag)\r
\r
case 3: // Text\r
// Do not convert script elements\r
- if (node.parentNode.nodeName.toLowerCase() == "script")\r
+ if (node.parentNode.nodeName == "SCRIPT" || node.parentNode.nodeName == "NOSCRIPT" || node.parentNode.nodeName == "STYLE")\r
return node.nodeValue;\r
\r
return this.convertStringToXML(node.nodeValue);\r
}\r
\r
// Named entities\r
- if (typeof(tinyMCE.cleanup_entities["c" + chr]) != 'undefined' && tinyMCE.cleanup_entities["c" + chr] != '')\r
- output += '&' + tinyMCE.cleanup_entities["c" + chr] + ';';\r
+ if (typeof(tinyMCE.settings['cleanup_entities']["c" + chr]) != 'undefined' && tinyMCE.settings['cleanup_entities']["c" + chr] != '')\r
+ output += '&' + tinyMCE.settings['cleanup_entities']["c" + chr] + ';';\r
else\r
output += '' + String.fromCharCode(chr);\r
}\r
// Set these for performance\r
tinyMCE.settings['cleanup_validElements'] = validElements;\r
tinyMCE.settings['cleanup_invalidElements'] = invalidElements;\r
-\r
- // Setup entities\r
- tinyMCE.settings['cleanup_entities'] = new Array();\r
- var entities = tinyMCE.getParam('entities', '', true, ',');\r
- for (var i=0; i<entities.length; i+=2)\r
- tinyMCE.settings['cleanup_entities']['c' + entities[i]] = entities[i+1];\r
};\r
\r
TinyMCE.prototype._cleanupHTML = function(inst, doc, config, element, visual, on_save) {\r
- if (!tinyMCE.settings['cleanup'])\r
- return element.innerHTML;\r
+ if (!tinyMCE.settings['cleanup']) {\r
+ tinyMCE.handleVisualAid(inst.getBody(), true, false, inst);\r
+\r
+ var html = element.innerHTML;\r
+\r
+ // Remove mce_href/mce_src\r
+ html = html.replace(new RegExp('(mce_href|mce_src)=".*?"', 'gi'), '');\r
+ html = html.replace(/\s+>/gi, '>');\r
+\r
+ return html;\r
+ }\r
+\r
+ if (on_save && tinyMCE.getParam("convert_fonts_to_spans"))\r
+ tinyMCE.convertFontsToSpans(doc);\r
\r
// Call custom cleanup code\r
tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);\r
\r
+ // Move bgcolor to style\r
+ var n = doc.getElementsByTagName("font");\r
+ for (var i=0; i<n.length; i++) {\r
+ var c = "";\r
+ if ((c = tinyMCE.getAttrib(n[i], "bgcolor")) != "") {\r
+ n[i].style.backgroundColor = c;\r
+ tinyMCE.setAttrib(n[i], "bgcolor", "");\r
+ }\r
+ }\r
+\r
// Set these for performance\r
tinyMCE.cleanup_validElements = tinyMCE.settings['cleanup_validElements'];\r
- tinyMCE.cleanup_entities = tinyMCE.settings['cleanup_entities'];\r
tinyMCE.cleanup_invalidElements = tinyMCE.settings['cleanup_invalidElements'];\r
tinyMCE.cleanup_verify_html = tinyMCE.settings['verify_html'];\r
tinyMCE.cleanup_force_br_newlines = tinyMCE.settings['force_br_newlines'];\r
nodes[i].removeAttribute("id");\r
}\r
\r
- element.innerHTML = tinyMCE.regexpReplace(element.innerHTML, '<p>[ \n\r]*<hr.*>[ \n\r]*</p>', '<hr />', 'gi');\r
- element.innerHTML = tinyMCE.regexpReplace(element.innerHTML, '<!([^-(DOCTYPE)]* )|<!/[^-]*>', '', 'gi');\r
+ tinyMCE.setInnerHTML(element, tinyMCE.regexpReplace(element.innerHTML, '<p>[ \n\r]*<hr.*>[ \n\r]*</p>', '<hr />', 'gi'));\r
+ tinyMCE.setInnerHTML(element, tinyMCE.regexpReplace(element.innerHTML, '<!([^-(DOCTYPE)]* )|<!/[^-]*>', '', 'gi'));\r
}\r
\r
var html = this.cleanupNode(element);\r
if (tinyMCE.settings['debug'])\r
tinyMCE.debug("Cleanup process executed in: " + (new Date().getTime()-startTime) + " ms.");\r
\r
- // Remove pesky HR paragraphs\r
+ // Remove pesky HR paragraphs and other crap\r
html = tinyMCE.regexpReplace(html, '<p><hr /></p>', '<hr />');\r
html = tinyMCE.regexpReplace(html, '<p> </p><hr /><p> </p>', '<hr />');\r
html = tinyMCE.regexpReplace(html, '<td>\\s*<br />\\s*</td>', '<td> </td>');\r
+ html = tinyMCE.regexpReplace(html, '<p>\\s*<br />\\s*</p>', '<p> </p>');\r
+ html = tinyMCE.regexpReplace(html, '<p>\\s* \\s*<br />\\s* \\s*</p>', '<p> </p>');\r
+ html = tinyMCE.regexpReplace(html, '<p>\\s* \\s*<br />\\s*</p>', '<p> </p>');\r
+ html = tinyMCE.regexpReplace(html, '<p>\\s*<br />\\s* \\s*</p>', '<p> </p>');\r
\r
// Remove empty anchors\r
html = html.replace(new RegExp('<a>(.*?)</a>', 'gi'), '$1');\r
\r
- // Move contents behind anchors\r
- html = html.replace(new RegExp('<a(.*?)name="(.*?)"(.*?)>(.*?)</a>', 'gi'), '<a$1name="$2"$3></a>$4');\r
-\r
// Remove some mozilla crap\r
if (!tinyMCE.isMSIE)\r
html = html.replace(new RegExp('<o:p _moz-userdefined="" />', 'g'), "");\r
\r
- if (tinyMCE.settings['apply_source_formatting']) {\r
+ if (tinyMCE.settings['remove_linebreaks'])\r
+ html = html.replace(new RegExp('\r|\n', 'g'), ' ');\r
+\r
+ if (tinyMCE.getParam('apply_source_formatting')) {\r
html = html.replace(new RegExp('<(p|div)([^>]*)>', 'g'), "\n<$1$2>\n");\r
html = html.replace(new RegExp('<\/(p|div)([^>]*)>', 'g'), "\n</$1$2>\n");\r
html = html.replace(new RegExp('<br />', 'g'), "<br />\n");\r
html = html.replace(re, "<br />");\r
}\r
\r
- if (tinyMCE.settings['force_p_newlines']) {\r
+ if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt']) {\r
// Remove weridness!\r
var re = new RegExp('<>', 'g');\r
html = html.replace(re, "");\r
}\r
\r
- if (tinyMCE.settings['remove_linebreaks'])\r
- html = html.replace(new RegExp('\r|\n', 'g'), ' ');\r
-\r
// Call custom cleanup code\r
html = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", html);\r
\r
newLink = true;\r
}\r
\r
- href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);");\r
- tinyMCE.setAttrib(linkElement, 'href', href);\r
+ var mhref = href;\r
+ var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);");\r
+ mhref = tinyMCE.getParam('convert_urls') ? href : mhref;\r
+\r
+ tinyMCE.setAttrib(linkElement, 'href', thref);\r
+ tinyMCE.setAttrib(linkElement, 'mce_href', mhref);\r
tinyMCE.setAttrib(linkElement, 'target', target);\r
tinyMCE.setAttrib(linkElement, 'title', title);\r
tinyMCE.setAttrib(linkElement, 'onclick', onclick);\r
\r
if (!this.linkElement && this.selectedInstance) {\r
if (tinyMCE.isSafari) {\r
- tinyMCE.execCommand("mceInsertContent", false, '<a href="#mce_temp_url#">' + this.selectedInstance.getSelectedHTML() + '</a>');\r
+ tinyMCE.execCommand("mceInsertContent", false, '<a href="' + tinyMCE.uniqueURL + '">' + this.selectedInstance.getSelectedHTML() + '</a>');\r
} else\r
- this.selectedInstance.contentDocument.execCommand("createlink", false, "#mce_temp_url#");\r
+ this.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL);\r
\r
- tinyMCE.linkElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", "#mce_temp_url#");\r
+ tinyMCE.linkElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);\r
\r
- var elementArray = this.getElementsByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", "#mce_temp_url#");\r
+ var elementArray = this.getElementsByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);\r
\r
for (var i=0; i<elementArray.length; i++) {\r
- href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);");\r
- tinyMCE.setAttrib(elementArray[i], 'href', href);\r
- tinyMCE.setAttrib(elementArray[i], 'mce_real_href', href);\r
+ var mhref = href;\r
+ var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);");\r
+ mhref = tinyMCE.getParam('convert_urls') ? href : mhref;\r
+\r
+ tinyMCE.setAttrib(elementArray[i], 'href', thref);\r
+ tinyMCE.setAttrib(elementArray[i], 'mce_href', mhref);\r
tinyMCE.setAttrib(elementArray[i], 'target', target);\r
tinyMCE.setAttrib(elementArray[i], 'title', title);\r
tinyMCE.setAttrib(elementArray[i], 'onclick', onclick);\r
}\r
\r
if (this.linkElement) {\r
+ var mhref = href;\r
href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, this.linkElement);");\r
+ mhref = tinyMCE.getParam('convert_urls') ? href : mhref;\r
+\r
tinyMCE.setAttrib(this.linkElement, 'href', href);\r
- tinyMCE.setAttrib(this.linkElement, 'mce_real_href', href);\r
+ tinyMCE.setAttrib(this.linkElement, 'mce_href', mhref);\r
tinyMCE.setAttrib(this.linkElement, 'target', target);\r
tinyMCE.setAttrib(this.linkElement, 'title', title);\r
tinyMCE.setAttrib(this.linkElement, 'onclick', onclick);\r
} else {\r
if (!this.imgElement && this.selectedInstance) {\r
if (tinyMCE.isSafari)\r
- tinyMCE.execCommand("mceInsertContent", false, '<img src="#mce_temp_url#" />');\r
+ tinyMCE.execCommand("mceInsertContent", false, '<img src="' + tinyMCE.uniqueURL + '" />');\r
else\r
- this.selectedInstance.contentDocument.execCommand("insertimage", false, "#mce_temp_url#");\r
+ this.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL);\r
\r
- tinyMCE.imgElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "img", "src", "#mce_temp_url#");\r
+ tinyMCE.imgElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL);\r
}\r
}\r
\r
if (this.imgElement) {\r
var needsRepaint = false;\r
+ var msrc = src;\r
\r
src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);");\r
\r
+ if (tinyMCE.getParam('convert_urls'))\r
+ msrc = src;\r
+\r
if (onmouseover && onmouseover != "")\r
onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';";\r
\r
needsRepaint = true;\r
\r
tinyMCE.setAttrib(this.imgElement, 'src', src);\r
- tinyMCE.setAttrib(this.imgElement, 'mce_real_src', src);\r
+ tinyMCE.setAttrib(this.imgElement, 'mce_src', msrc);\r
tinyMCE.setAttrib(this.imgElement, 'alt', alt);\r
tinyMCE.setAttrib(this.imgElement, 'title', title);\r
tinyMCE.setAttrib(this.imgElement, 'align', align);\r
elements[elements.length] = node;\r
}\r
\r
- if (node.hasChildNodes) {\r
+ if (node && node.hasChildNodes()) {\r
for (var x=0, n=node.childNodes.length; x<n; x++) {\r
var childElements = this.getElementsByAttributeValue(node.childNodes[x], element_name, attrib, value);\r
for (var i=0, m=childElements.length; i<m; i++)\r
}\r
}\r
}\r
- } while (node = node.parentNode);\r
+ } while ((node = node.parentNode) != null);\r
\r
return null;\r
};\r
var host = document.location.hostname;\r
var port = document.location.port;\r
\r
- var fileProto = (prot == "file:");\r
+ // Pass through file protocol\r
+ if (prot == "file:")\r
+ return url;\r
\r
// Something is wrong, remove weirdness\r
url = tinyMCE.regexpReplace(url, '(http|https):///', '/');\r
if (!tinyMCE.isMSIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')\r
return tinyMCE.settings['base_href'] + url;\r
\r
- // Handle absolute url anchors\r
- if (!tinyMCE.settings['relative_urls']) {\r
- var urlParts = tinyMCE.parseURL(url);\r
- var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);\r
+ // Handle relative URLs\r
+ if (on_save && tinyMCE.getParam('relative_urls')) {\r
+ var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);\r
+ if (curl.charAt(0) == '/')\r
+ curl = tinyMCE.settings['document_base_prefix'] + curl;\r
\r
- // If anchor and path is the same page\r
- if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])\r
- return "#" + urlParts['anchor'];\r
+ var urlParts = tinyMCE.parseURL(curl);\r
+ var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);\r
+\r
+ // Force relative\r
+ if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))\r
+ return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);\r
}\r
\r
- // Convert to relative urls\r
- if (on_save && tinyMCE.settings['relative_urls']) {\r
+ // Handle absolute URLs\r
+ if (!tinyMCE.getParam('relative_urls')) {\r
var urlParts = tinyMCE.parseURL(url);\r
+ var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);\r
\r
- // If not absolute url, do nothing (Mozilla)\r
- // WEIRD STUFF?!\r
-/* if (!urlParts['protocol'] && !tinyMCE.isMSIE) {\r
- var urlPrefix = "http://";\r
- urlPrefix += host;\r
- if (port != "")\r
- urlPrefix += ":" + port;\r
-\r
- url = urlPrefix + url;\r
- urlParts = tinyMCE.parseURL(url);\r
- }*/\r
-\r
- var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);\r
+ // Force absolute URLs from relative URLs\r
+ url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);\r
\r
- // Link is within this site\r
- if (urlParts['host'] == tmpUrlParts['host'] && (!urlParts['port'] || urlParts['port'] == tmpUrlParts['port']))\r
- return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], url);\r
+ // If anchor and path is the same page\r
+ if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])\r
+ return "#" + urlParts['anchor'];\r
}\r
\r
// Remove current domain\r
- if (!fileProto && tinyMCE.settings['remove_script_host']) {\r
+ if (tinyMCE.getParam('remove_script_host')) {\r
var start = "", portPart = "";\r
\r
if (port != "")\r
\r
if (url.indexOf(start) == 0)\r
url = url.substring(start.length-1);\r
-\r
- // Add first slash if missing on a absolute URL\r
- if (!tinyMCE.settings['relative_urls'] && url.indexOf('://') == -1 && url.charAt(0) != '/')\r
- url = '/' + url;\r
}\r
\r
return url;\r
urlParts['host'] = url_str.substring(lastPos, pos);\r
\r
// Get port\r
+ urlParts['port'] = "";\r
lastPos = pos;\r
if (url_str.charAt(pos) == ':') {\r
pos = url_str.indexOf('/', lastPos);\r
return urlParts;\r
};\r
\r
+TinyMCE.prototype.serializeURL = function(up) {\r
+ var url = "";\r
+\r
+ if (up['protocol'])\r
+ url += up['protocol'] + "://";\r
+\r
+ if (up['host'])\r
+ url += up['host'];\r
+\r
+ if (up['port'])\r
+ url += ":" + up['port'];\r
+\r
+ if (up['path'])\r
+ url += up['path'];\r
+\r
+ if (up['query'])\r
+ url += "?" + up['query'];\r
+\r
+ if (up['anchor'])\r
+ url += "#" + up['anchor'];\r
+\r
+ return url;\r
+};\r
+\r
/**\r
* Converts an absolute path to relative path.\r
*/\r
TinyMCE.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {\r
+ var baseURL = this.parseURL(base_url);\r
+ var targetURL = this.parseURL(url_to_relative);\r
var strTok1;\r
var strTok2;\r
var breakPoint = 0;\r
- var outputString = "";\r
+ var outPath = "";\r
+ var forceSlash = false;\r
+\r
+ if (targetURL.path == "")\r
+ targetURL.path = "/";\r
+ else\r
+ forceSlash = true;\r
\r
// Crop away last path part\r
- base_url = base_url.substring(0, base_url.lastIndexOf('/'));\r
+ base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));\r
strTok1 = base_url.split('/');\r
- strTok2 = url_to_relative.split('/');\r
+ strTok2 = targetURL.path.split('/');\r
\r
if (strTok1.length >= strTok2.length) {\r
for (var i=0; i<strTok1.length; i++) {\r
}\r
\r
if (breakPoint == 1)\r
- return url_to_relative;\r
+ return targetURL.path;\r
\r
for (var i=0; i<(strTok1.length-(breakPoint-1)); i++)\r
- outputString += "../";\r
+ outPath += "../";\r
\r
for (var i=breakPoint-1; i<strTok2.length; i++) {\r
if (i != (breakPoint-1))\r
- outputString += "/" + strTok2[i];\r
+ outPath += "/" + strTok2[i];\r
else\r
- outputString += strTok2[i];\r
+ outPath += strTok2[i];\r
}\r
\r
- return outputString;\r
+ targetURL.protocol = null;\r
+ targetURL.host = null;\r
+ targetURL.port = null;\r
+ targetURL.path = outPath == "" && forceSlash ? "/" : outPath;\r
+\r
+ // Remove document prefix from local anchors\r
+ var fileName = baseURL.path;\r
+ var pos;\r
+\r
+ if ((pos = fileName.lastIndexOf('/')) != -1)\r
+ fileName = fileName.substring(pos + 1);\r
+\r
+ // Is local anchor\r
+ if (fileName == targetURL.path && targetURL.anchor != "")\r
+ targetURL.path = "";\r
+\r
+ return this.serializeURL(targetURL);\r
};\r
\r
TinyMCE.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {\r
var baseURL = TinyMCE.prototype.parseURL(base_url);\r
var relURL = TinyMCE.prototype.parseURL(relative_url);\r
\r
- if (relative_url == "" || relative_url.charAt(0) == '/' || relative_url.indexOf('://') != -1 || relative_url.indexOf('mailto:') != -1 || relative_url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(relative_url,'[ \t\r\n\+]|%20','').charAt(0) == "#")\r
+ if (relative_url == "" || relative_url.charAt(0) == '/' || relative_url.indexOf('://') != -1 || relative_url.indexOf('mailto:') != -1 || relative_url.indexOf('javascript:') != -1)\r
return relative_url;\r
\r
// Split parts\r
var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');\r
var start = "", end = "";\r
\r
- // Build start part\r
- if (baseURL['protocol'])\r
- start += baseURL['protocol'] + "://";\r
-\r
- if (baseURL['host'])\r
- start += baseURL['host'];\r
-\r
- if (baseURL['port'])\r
- start += ":" + baseURL['port'];\r
-\r
- // Build end part\r
- if (relURL['query'])\r
- end += "?" + relURL['query'];\r
-\r
- if (relURL['anchor'])\r
- end += "#" + relURL['anchor'];\r
+ // Build output URL\r
+ relURL.protocol = baseURL.protocol;\r
+ relURL.host = baseURL.host;\r
+ relURL.port = baseURL.port;\r
\r
// Re-add trailing slash if it's removed\r
- if (relative_url.charAt(relative_url.length-1) == "/")\r
- end += "/";\r
+ if (relURL.path.charAt(relURL.path.length-1) == "/")\r
+ absPath += "/";\r
+\r
+ relURL.path = absPath;\r
\r
- return start + absPath + end;\r
+ return TinyMCE.prototype.serializeURL(relURL);\r
};\r
\r
TinyMCE.prototype.getParam = function(name, default_value, strip_whitespace, split_chr) {\r
TinyMCE.prototype.getLang = function(name, default_value, parse_entities) {\r
var value = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name];\r
\r
- if (parse_entities) {\r
- var el = document.createElement("div");\r
- el.innerHTML = value;\r
- value = el.innerHTML;\r
- }\r
+ if (parse_entities)\r
+ value = tinyMCE.entityDecode(value);\r
\r
return value;\r
};\r
\r
+TinyMCE.prototype.entityDecode = function(s) {\r
+ var e = document.createElement("div");\r
+ e.innerHTML = s;\r
+ return e.innerHTML;\r
+};\r
+\r
TinyMCE.prototype.addToLang = function(prefix, ar) {\r
for (var key in ar) {\r
if (typeof(ar[key]) == 'function')\r
var anySelection = false;\r
var selectedText = inst.getSelectedText();\r
\r
+ inst.switchSettings();\r
+\r
if (tinyMCE.settings["auto_resize"]) {\r
var doc = inst.getDoc();\r
\r
undoLevels = inst.undoLevels.length;\r
}\r
\r
- tinyMCE.executeCallback('handleNodeChangeCallback', '_handleNodeChange', 0, editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection);\r
+ tinyMCE.executeCallback('handleNodeChangeCallback', '_handleNodeChange', 0, editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);\r
}\r
}\r
\r
if (typeof(editor_id) != "undefined")\r
tinyMCE.selectedInstance = tinyMCE.getInstanceById(editor_id);\r
\r
- if (tinyMCE.selectedInstance)\r
- return tinyMCE._cleanupHTML(this.selectedInstance, this.selectedInstance.getDoc(), tinyMCE.settings, this.selectedInstance.getBody(), false, true);\r
+ if (tinyMCE.selectedInstance) {\r
+ var old = this.selectedInstance.getBody().innerHTML;\r
+ var html = tinyMCE._cleanupHTML(this.selectedInstance, this.selectedInstance.getDoc(), tinyMCE.settings, this.selectedInstance.getBody(), false, true);\r
+ tinyMCE.setInnerHTML(this.selectedInstance.getBody(), old);\r
+ return html;\r
+ }\r
\r
return null;\r
};\r
win.resizeTo(width, height);\r
win.focus();\r
} else {\r
- if (tinyMCE.isMSIE && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {\r
+ if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {\r
var features = "resizable:" + resizable \r
+ ";scroll:"\r
+ scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"\r
return className;\r
};\r
\r
-TinyMCE.prototype.handleVisualAid = function(element, deep, state, inst) {\r
- if (!element)\r
+TinyMCE.prototype.handleVisualAid = function(el, deep, state, inst) {\r
+ if (!el)\r
return;\r
\r
var tableElement = null;\r
\r
- switch (element.nodeName) {\r
+ switch (el.nodeName) {\r
case "TABLE":\r
- var oldW = element.style.width;\r
- var oldH = element.style.height;\r
+ var oldW = el.style.width;\r
+ var oldH = el.style.height;\r
+ var bo = tinyMCE.getAttrib(el, "border");\r
+\r
+ bo = bo == "" || bo == "0" ? true : false;\r
\r
- element.className = tinyMCE.getVisualAidClass(element.className, state && element.getAttribute("border") == 0);\r
+ tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));\r
\r
- element.style.width = oldW;\r
- element.style.height = oldH;\r
+ el.style.width = oldW;\r
+ el.style.height = oldH;\r
\r
- for (var y=0; y<element.rows.length; y++) {\r
- for (var x=0; x<element.rows[y].cells.length; x++) {\r
- var className = tinyMCE.getVisualAidClass(element.rows[y].cells[x].className, state && element.getAttribute("border") == 0);\r
- element.rows[y].cells[x].className = className;\r
+ for (var y=0; y<el.rows.length; y++) {\r
+ for (var x=0; x<el.rows[y].cells.length; x++) {\r
+ var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);\r
+ tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);\r
}\r
}\r
\r
break;\r
\r
case "A":\r
- var anchorName = tinyMCE.getAttrib(element, "name");\r
+ var anchorName = tinyMCE.getAttrib(el, "name");\r
\r
if (anchorName != '' && state) {\r
- element.title = anchorName;\r
- element.className = 'mceItemAnchor';\r
+ el.title = anchorName;\r
+ el.className = 'mceItemAnchor';\r
} else if (anchorName != '' && !state)\r
- element.className = '';\r
+ el.className = '';\r
\r
break;\r
}\r
\r
- if (deep && element.hasChildNodes()) {\r
- for (var i=0; i<element.childNodes.length; i++)\r
- tinyMCE.handleVisualAid(element.childNodes[i], deep, state, inst);\r
+ if (deep && el.hasChildNodes()) {\r
+ for (var i=0; i<el.childNodes.length; i++)\r
+ tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst);\r
}\r
};\r
\r
if (name == "class" && !v)\r
v = elm.className;\r
\r
- if (name == "style")\r
+ // Workaround for a issue with Firefox 1.5rc2+\r
+ if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "")\r
+ v = elm.src;\r
+\r
+ // Workaround for a issue with Firefox 1.5rc2+\r
+ if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")\r
+ v = elm.href;\r
+\r
+ if (name == "style" && !tinyMCE.isOpera)\r
v = elm.style.cssText;\r
\r
return (v && v != "") ? v : default_value;\r
element.removeAttribute(name);\r
};\r
\r
-TinyMCE.prototype._setHTML = function(doc, html_content) {\r
- // Force closed anchors open\r
- html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');\r
- html_content = html_content.replace(new RegExp('<a(.*?)name="(.*?)"(.*?)>(.*?)</a>', 'gi'), '<a$1name="$2"$3></a>$4');\r
+TinyMCE.prototype.setStyleAttrib = function(elm, name, value) {\r
+ eval('elm.style.' + name + '=value;');\r
\r
- // Weird MSIE bug, <p><hr /></p> breaks runtime?\r
+ // Style attrib deleted\r
+ if (tinyMCE.isMSIE && value == null || value == '') {\r
+ var str = tinyMCE.serializeStyle(tinyMCE.parseStyle(elm.style.cssText));\r
+ elm.style.cssText = str;\r
+ elm.setAttribute("style", str);\r
+ }\r
+};\r
+\r
+TinyMCE.prototype.convertSpansToFonts = function(doc) {\r
+ var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');\r
+\r
+ var h = doc.body.innerHTML;\r
+ h = h.replace(/<span/gi, '<font');\r
+ h = h.replace(/<\/span/gi, '</font');\r
+ doc.body.innerHTML = h;\r
+\r
+ var s = doc.getElementsByTagName("font");\r
+ for (var i=0; i<s.length; i++) {\r
+ var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();\r
+ var fSize = 0;\r
+\r
+ for (var x=0; x<sizes.length; x++) {\r
+ if (sizes[x] == size) {\r
+ fSize = x + 1;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (fSize > 0) {\r
+ tinyMCE.setAttrib(s[i], 'size', fSize);\r
+ s[i].style.fontSize = '';\r
+ }\r
+\r
+ var fFace = s[i].style.fontFamily;\r
+ if (fFace != null && fFace != "") {\r
+ tinyMCE.setAttrib(s[i], 'face', fFace);\r
+ s[i].style.fontFamily = '';\r
+ }\r
+\r
+ var fColor = s[i].style.color;\r
+ if (fColor != null && fColor != "") {\r
+ tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));\r
+ s[i].style.color = '';\r
+ }\r
+ }\r
+};\r
+\r
+TinyMCE.prototype.convertFontsToSpans = function(doc) {\r
+ var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');\r
+\r
+ var h = doc.body.innerHTML;\r
+ h = h.replace(/<font/gi, '<span');\r
+ h = h.replace(/<\/font/gi, '</span');\r
+ doc.body.innerHTML = h;\r
+\r
+ var fsClasses = tinyMCE.getParam('font_size_classes');\r
+ if (fsClasses != '')\r
+ fsClasses = fsClasses.replace(/\s+/, '').split(',');\r
+ else\r
+ fsClasses = null;\r
+\r
+ var s = doc.getElementsByTagName("span");\r
+ for (var i=0; i<s.length; i++) {\r
+ var fSize, fFace, fColor;\r
+\r
+ fSize = tinyMCE.getAttrib(s[i], 'size');\r
+ fFace = tinyMCE.getAttrib(s[i], 'face');\r
+ fColor = tinyMCE.getAttrib(s[i], 'color');\r
+\r
+ if (fSize != "") {\r
+ fSize = parseInt(fSize);\r
+\r
+ if (fSize > 0 && fSize < 8) {\r
+ if (fsClasses != null)\r
+ tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);\r
+ else\r
+ s[i].style.fontSize = sizes[fSize-1];\r
+ }\r
+\r
+ s[i].removeAttribute('size');\r
+ }\r
+\r
+ if (fFace != "") {\r
+ s[i].style.fontFamily = fFace;\r
+ s[i].removeAttribute('face');\r
+ }\r
+\r
+ if (fColor != "") {\r
+ s[i].style.color = fColor;\r
+ s[i].removeAttribute('color');\r
+ }\r
+ }\r
+};\r
+\r
+/*\r
+TinyMCE.prototype.applyClassesToFonts = function(doc, size) {\r
+ var f = doc.getElementsByTagName("font");\r
+ for (var i=0; i<f.length; i++) {\r
+ var s = tinyMCE.getAttrib(f[i], "size");\r
+\r
+ if (s != "")\r
+ tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);\r
+ }\r
+\r
+ if (typeof(size) != "undefined") {\r
+ var css = "";\r
+\r
+ for (var x=0; x<doc.styleSheets.length; x++) {\r
+ for (var i=0; i<doc.styleSheets[x].rules.length; i++) {\r
+ if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {\r
+ css = doc.styleSheets[x].rules[i].style.cssText;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (css != "")\r
+ break;\r
+ }\r
+\r
+ if (doc.styleSheets[0].rules[0].selectorText == "FONT")\r
+ doc.styleSheets[0].removeRule(0);\r
+\r
+ doc.styleSheets[0].addRule("FONT", css, 0);\r
+ }\r
+};\r
+*/\r
+\r
+TinyMCE.prototype.setInnerHTML = function(e, h) {\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera) {\r
+ e.innerHTML = tinyMCE.uniqueTag + h;\r
+ e.firstChild.removeNode(true);\r
+ } else {\r
+ h = this.fixGeckoBaseHREFBug(1, e, h);\r
+ e.innerHTML = h;\r
+ this.fixGeckoBaseHREFBug(2, e, h);\r
+ }\r
+};\r
+\r
+TinyMCE.prototype.fixGeckoBaseHREFBug = function(m, e, h) {\r
+ if (tinyMCE.isGecko) {\r
+ if (m == 1) {\r
+ h = h.replace(/\ssrc=/gi, " xsrc=");\r
+ h = h.replace(/\shref=/gi, " xhref=");\r
+\r
+ return h;\r
+ } else {\r
+ if (h.indexOf(' xsrc') != -1) {\r
+ var n = e.getElementsByTagName("img");\r
+ for (var i=0; i<n.length; i++) {\r
+ var xsrc = tinyMCE.getAttrib(n[i], "xsrc");\r
+\r
+ if (xsrc != "") {\r
+ n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);\r
+ n[i].removeAttribute("xsrc");\r
+ }\r
+ }\r
+\r
+ // Select image form fields\r
+ var n = e.getElementsByTagName("select");\r
+ for (var i=0; i<n.length; i++) {\r
+ var xsrc = tinyMCE.getAttrib(n[i], "xsrc");\r
+\r
+ if (xsrc != "") {\r
+ n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);\r
+ n[i].removeAttribute("xsrc");\r
+ }\r
+ }\r
+\r
+ // iframes\r
+ var n = e.getElementsByTagName("iframe");\r
+ for (var i=0; i<n.length; i++) {\r
+ var xsrc = tinyMCE.getAttrib(n[i], "xsrc");\r
+\r
+ if (xsrc != "") {\r
+ n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);\r
+ n[i].removeAttribute("xsrc");\r
+ }\r
+ }\r
+ }\r
+\r
+ if (h.indexOf(' xhref') != -1) {\r
+ var n = e.getElementsByTagName("a");\r
+ for (var i=0; i<n.length; i++) {\r
+ var xhref = tinyMCE.getAttrib(n[i], "xhref");\r
+\r
+ if (xhref != "") {\r
+ n[i].href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);\r
+ n[i].removeAttribute("xhref");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return h;\r
+};\r
+\r
+TinyMCE.prototype.getOuterHTML = function(e) {\r
+ if (tinyMCE.isMSIE)\r
+ return e.outerHTML;\r
+\r
+ var d = e.ownerDocument.createElement("body");\r
+ d.appendChild(e);\r
+ return d.innerHTML;\r
+};\r
+\r
+TinyMCE.prototype.setOuterHTML = function(doc, e, h) {\r
if (tinyMCE.isMSIE) {\r
- var re = new RegExp('<p><hr /></p>', 'g');\r
- html_content = html_content.replace(re, "<hr>");\r
+ e.outerHTML = h;\r
+ return;\r
+ }\r
+\r
+ var d = e.ownerDocument.createElement("body");\r
+ d.innerHTML = h;\r
+ e.parentNode.replaceChild(d.firstChild, e);\r
+};\r
+\r
+TinyMCE.prototype.insertAfter = function(nc, rc){\r
+ if (rc.nextSibling)\r
+ rc.parentNode.insertBefore(nc, rc.nextSibling);\r
+ else\r
+ rc.parentNode.appendChild(nc);\r
+};\r
+\r
+TinyMCE.prototype.cleanupAnchors = function(doc) {\r
+ var an = doc.getElementsByTagName("a");\r
+\r
+ for (var i=0; i<an.length; i++) {\r
+ if (tinyMCE.getAttrib(an[i], "name") != "") {\r
+ var cn = an[i].childNodes;\r
+ for (var x=cn.length-1; x>=0; x--)\r
+ tinyMCE.insertAfter(cn[x], an[i]);\r
+ }\r
}\r
+};\r
+\r
+TinyMCE.prototype._setHTML = function(doc, html_content) {\r
+ // Force closed anchors open\r
+ //html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');\r
+\r
+ html_content = tinyMCE.cleanupHTMLCode(html_content);\r
\r
// Try innerHTML if it fails use pasteHTML in MSIE\r
try {\r
- doc.body.innerHTML = html_content;\r
+ tinyMCE.setInnerHTML(doc.body, html_content);\r
} catch (e) {\r
if (this.isMSIE)\r
doc.body.createTextRange().pasteHTML(html_content);\r
for (var i=0; i<paras.length; i++) {\r
var node = paras[i];\r
while ((node = node.parentNode) != null) {\r
- if (node.nodeName.toLowerCase() == "p")\r
+ if (node.nodeName == "P")\r
node.outerHTML = node.innerHTML;\r
}\r
}\r
}\r
\r
// Always set the htmlText output\r
- doc.body.innerHTML = html;\r
+ tinyMCE.setInnerHTML(doc.body, html);\r
}\r
+\r
+ tinyMCE.cleanupAnchors(doc);\r
+\r
+ if (tinyMCE.getParam("convert_fonts_to_spans"))\r
+ tinyMCE.convertSpansToFonts(doc);\r
};\r
\r
TinyMCE.prototype.getImageSrc = function(str) {\r
if (!inst) {\r
for (var n in tinyMCE.instances) {\r
var instance = tinyMCE.instances[n];\r
- if (typeof(instance) == 'function')\r
+ if (!tinyMCE.isInstance(instance))\r
continue;\r
\r
if (instance.formTargetElementId == editor_id) {\r
\r
for (var instanceName in tinyMCE.instances) {\r
instance = tinyMCE.instances[instanceName];\r
- if (typeof(instance) == 'function')\r
+ if (!tinyMCE.isInstance(instance))\r
continue;\r
\r
break;\r
};\r
\r
TinyMCE.prototype.regexpReplace = function(in_str, reg_exp, replace_str, opts) {\r
+ if (in_str == null)\r
+ return in_str;\r
+\r
if (typeof(opts) == "undefined")\r
opts = 'g';\r
\r
str = "" + str;\r
str = str.replace('function anonymous()\n{\n', '');\r
str = str.replace('\n}', '');\r
- str = str.replace(/^return true;/gi, '');\r
+ str = str.replace(/^return true;/gi, ''); // Remove event blocker\r
\r
return str;\r
};\r
debugDiv.className = "debugger";\r
debugDiv.innerHTML = '\\r
Debug output:\\r
- <textarea id="tinymce_debug" style="width: 100%; height: 300px"></textarea>';\r
+ <textarea id="tinymce_debug" style="width: 100%; height: 300px" wrap="nowrap"></textarea>';\r
\r
document.body.appendChild(debugDiv);\r
elm = document.getElementById("tinymce_debug");\r
this.undoIndex = 0;\r
this.typingUndoIndex = -1;\r
this.undoRedo = true;\r
+ this.isTinyMCEControl = true;\r
\r
// Default settings\r
this.settings = settings;\r
};\r
\r
TinyMCEControl.prototype.repaint = function() {\r
- if (tinyMCE.isMSIE)\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera)\r
return;\r
\r
- this.getBody().style.display = 'none';\r
- this.getBody().style.display = 'block';\r
+ // Ugly mozilla hack to remove ghost resize handles\r
+ try {\r
+ this.getBody().style.display = 'none';\r
+ this.getDoc().execCommand('selectall', false, null);\r
+ this.getSel().collapseToStart();\r
+ this.getBody().style.display = 'block';\r
+ } catch (ex) {\r
+ // Could I care less!!\r
+ }\r
};\r
\r
TinyMCEControl.prototype.switchSettings = function() {\r
}\r
};\r
\r
-TinyMCEControl.prototype.fixBrokenURLs = function() {\r
- var body = this.getBody();\r
-\r
- var elms = body.getElementsByTagName("img");\r
- for (var i=0; i<elms.length; i++) {\r
- var src = elms[i].getAttribute('mce_real_src');\r
- if (src && src != "")\r
- elms[i].setAttribute("src", src);\r
- }\r
-\r
- var elms = body.getElementsByTagName("a");\r
- for (var i=0; i<elms.length; i++) {\r
- var href = elms[i].getAttribute('mce_real_href');\r
- if (href && href != "")\r
- elms[i].setAttribute("href", href);\r
- }\r
-};\r
-\r
TinyMCEControl.prototype.convertAllRelativeURLs = function() {\r
var body = this.getBody();\r
\r
// Convert all image URL:s to absolute URL\r
var elms = body.getElementsByTagName("img");\r
for (var i=0; i<elms.length; i++) {\r
- var src = elms[i].getAttribute('src');\r
- if (src && src != "") {\r
+ var src = tinyMCE.getAttrib(elms[i], 'src');\r
+\r
+ var msrc = tinyMCE.getAttrib(elms[i], 'mce_src');\r
+ if (msrc != "")\r
+ src = msrc;\r
+\r
+ if (src != "") {\r
src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], src);\r
elms[i].setAttribute("src", src);\r
- elms[i].setAttribute("mce_real_src", src);\r
}\r
}\r
\r
// Convert all link URL:s to absolute URL\r
var elms = body.getElementsByTagName("a");\r
for (var i=0; i<elms.length; i++) {\r
- var href = elms[i].getAttribute('href');\r
+ var href = tinyMCE.getAttrib(elms[i], 'href');\r
+\r
+ var mhref = tinyMCE.getAttrib(elms[i], 'mce_href');\r
+ if (mhref != "")\r
+ href = mhref;\r
+\r
if (href && href != "") {\r
href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], href);\r
elms[i].setAttribute("href", href);\r
- elms[i].setAttribute("mce_real_href", href);\r
}\r
}\r
};\r
var height = tinyMCE.isMSIE ? document.getElementById(this.editorId).style.pixelHeight : this.targetElement.clientHeight;\r
\r
// Only scroll if out of visible area\r
- if (!tinyMCE.settings['auto_resize'] && !(node.absTop > scrollY && node.absTop < (scrollY - 25 + height)))\r
- this.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25);\r
+ if (!tinyMCE.settings['auto_resize'] && !(pos.absTop > scrollY && pos.absTop < (scrollY - 25 + height)))\r
+ this.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25); \r
};\r
\r
TinyMCEControl.prototype.getBody = function() {\r
};\r
\r
TinyMCEControl.prototype.getSel = function() {\r
- if (tinyMCE.isMSIE)\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera)\r
return this.getDoc().selection;\r
\r
var sel = this.contentWindow.getSelection();\r
if (sel == null)\r
return null;\r
\r
- if (tinyMCE.isMSIE)\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera)\r
return sel.createRange();\r
\r
if (tinyMCE.isSafari) {\r
blockName = "P";\r
}\r
\r
- // Within a list item (use normal behavior)\r
- if ((startBlock != null && startBlock.nodeName == "LI") || (endBlock != null && endBlock.nodeName == "LI"))\r
+ // Within a list use normal behaviour\r
+ if (tinyMCE.getParentElement(startBlock, "OL,UL") != null)\r
return false;\r
\r
// Within a table create new paragraphs\r
startBlock = endBlock = null;\r
\r
// Setup new paragraphs\r
- var paraBefore = (startBlock != null && startBlock.nodeName.toUpperCase() == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);\r
- var paraAfter = (endBlock != null && endBlock.nodeName.toUpperCase() == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);\r
+ var paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);\r
+ var paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);\r
+\r
+ // Is header, then force paragraph under\r
+ if (/^(H[1-6])$/.test(blockName))\r
+ paraAfter = doc.createElement("p");\r
\r
// Setup chop nodes\r
var startChop = startNode;\r
if (endChop.parentNode.nodeName == blockName)\r
endChop = endChop.parentNode;\r
\r
- rng.setEndAfter(endChop);\r
+ // If not after image\r
+ //if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY")\r
+ rng.setEndAfter(endChop);\r
+\r
if (endChop.nodeName != "#text" && endChop.nodeName != "BODY")\r
rngBefore.setEndAfter(endChop);\r
\r
var contents = rng.cloneContents();\r
- if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY")) {\r
- var nodes = contents.firstChild.childNodes;\r
- for (var i=0; i<nodes.length; i++) {\r
- if (nodes[i].nodeName != "BODY")\r
- paraAfter.appendChild(nodes[i]);\r
- }\r
- } else\r
+ if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY"))\r
+ paraAfter.innerHTML = contents.firstChild.innerHTML;\r
+ else\r
paraAfter.appendChild(contents);\r
\r
// Check if it's a empty paragraph\r
paraBefore.normalize();\r
rngBefore.insertNode(paraBefore);\r
\r
-// tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);\r
+ // tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);\r
} else {\r
body.innerHTML = "<" + blockName + "> </" + blockName + "><" + blockName + "> </" + blockName + ">";\r
paraAfter = body.childNodes[1];\r
rngBefore.setStart(startChop, 0);\r
else\r
rngBefore.setStartBefore(startChop);\r
+\r
rngBefore.setEnd(startNode, startOffset);\r
paraBefore.appendChild(rngBefore.cloneContents());\r
\r
rngAfter.setEndAfter(endChop);\r
rngAfter.setStart(endNode, endOffset);\r
var contents = rngAfter.cloneContents();\r
+\r
if (contents.firstChild && contents.firstChild.nodeName == blockName) {\r
- var nodes = contents.firstChild.childNodes;\r
+/* var nodes = contents.firstChild.childNodes;\r
for (var i=0; i<nodes.length; i++) {\r
- if (nodes[i].nodeName.toLowerCase() != "body")\r
+ //tinyMCE.debug(nodes[i].nodeName);\r
+ if (nodes[i].nodeName != "BODY")\r
paraAfter.appendChild(nodes[i]);\r
}\r
+*/\r
+ paraAfter.innerHTML = contents.firstChild.innerHTML;\r
} else\r
paraAfter.appendChild(contents);\r
\r
rng.deleteContents();\r
rng.insertNode(paraAfter);\r
rng.insertNode(paraBefore);\r
- // debug("2", paraBefore.innerHTML, paraAfter.innerHTML);\r
+ //tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML);\r
\r
// Normalize\r
paraAfter.normalize();\r
\r
TinyMCEControl.prototype.autoResetDesignMode = function() {\r
// Add fix for tab/style.display none/block problems in Gecko\r
- if (!tinyMCE.isMSIE && tinyMCE.settings['auto_reset_designmode']) {\r
- var sel = this.getSel();\r
+ if (!tinyMCE.isMSIE && tinyMCE.settings['auto_reset_designmode'] && this.isHidden())\r
+ eval('try { this.getDoc().designMode = "On"; } catch(e) {}');\r
+};\r
\r
- // Weird, wheres that cursor selection?\r
- if (!sel || !sel.rangeCount || sel.rangeCount == 0)\r
- eval('try { this.getDoc().designMode = "On"; } catch(e) {}');\r
- }\r
+TinyMCEControl.prototype.isHidden = function() {\r
+ if (tinyMCE.isMSIE)\r
+ return false;\r
+\r
+ var sel = this.getSel();\r
+\r
+ // Weird, wheres that cursor selection?\r
+ return (!sel || !sel.rangeCount || sel.rangeCount == 0);\r
};\r
\r
TinyMCEControl.prototype.isDirty = function() {\r
ch.removeAttribute("style");\r
};\r
\r
+TinyMCEControl.prototype.setUseCSS = function(b) {\r
+ var doc = this.getDoc();\r
+ try {doc.execCommand("useCSS", false, !b);} catch (ex) {}\r
+ try {doc.execCommand("styleWithCSS", false, b);} catch (ex) {}\r
+\r
+ if (!tinyMCE.getParam("table_inline_editing"))\r
+ try {doc.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {}\r
+\r
+ if (!tinyMCE.getParam("object_resizing"))\r
+ try {doc.execCommand('enableObjectResizing', false, "false");} catch (ex) {}\r
+};\r
+\r
TinyMCEControl.prototype.execCommand = function(command, user_interface, value) {\r
var doc = this.getDoc();\r
var win = this.getWin();\r
\r
// Mozilla issue\r
if (!tinyMCE.isMSIE && !this.useCSS) {\r
- try {doc.execCommand("styleWithCSS", false, false);} catch (ex) {}\r
- try {doc.execCommand("useCSS", false, true);} catch (ex) {}\r
+ this.setUseCSS(false);\r
this.useCSS = true;\r
}\r
\r
var sel = this.getSel();\r
var scmd = value['command'];\r
var sname = value['name'];\r
- var svalue = value['value'];\r
+ var svalue = value['value'] == null ? '' : value['value'];\r
+ //var svalue = value['value'] == null ? '' : value['value'];\r
var wrapper = value['wrapper'] ? value['wrapper'] : "span";\r
var parentElm = null;\r
var invalidRe = new RegExp("^BODY|HTML$", "g");\r
+ var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;\r
\r
// Whole element selected check\r
if (tinyMCE.isMSIE) {\r
var prng = doc.selection.createRange();\r
prng.moveToElementText(pelm);\r
\r
- if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0)\r
- parentElm = pelm;\r
+ if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) {\r
+ if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName))\r
+ parentElm = pelm;\r
+ }\r
}\r
} else {\r
var felm = this.getFocusElement();\r
// Whole element selected\r
if (parentElm && !invalidRe.test(parentElm.nodeName)) {\r
if (scmd == "setstyle")\r
- eval("parentElm.style." + sname + " = svalue;");\r
+ tinyMCE.setStyleAttrib(parentElm, sname, svalue);\r
\r
if (scmd == "setattrib")\r
tinyMCE.setAttrib(parentElm, sname, svalue);\r
continue;\r
\r
if (scmd == "setstyle")\r
- eval("ch[z].style." + sname + " = '';");\r
+ tinyMCE.setStyleAttrib(ch[z], sname, '');\r
\r
if (scmd == "setattrib")\r
tinyMCE.setAttrib(ch[z], sname, '');\r
var spanElm = doc.createElement(wrapper);\r
\r
if (scmd == "setstyle")\r
- eval("spanElm.style." + sname + " = svalue;");\r
+ tinyMCE.setStyleAttrib(spanElm, sname, svalue);\r
\r
if (scmd == "setattrib")\r
tinyMCE.setAttrib(spanElm, sname, svalue);\r
continue;\r
\r
if (scmd == "setstyle")\r
- eval("ch[z].style." + sname + " = '';");\r
+ tinyMCE.setStyleAttrib(ch[z], sname, '');\r
\r
if (scmd == "setattrib")\r
tinyMCE.setAttrib(ch[z], sname, '');\r
// Is I the only child\r
if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) {\r
//tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName);\r
- this._mergeElements(scmd, elm.parentNode, elm, false);\r
+ if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName))\r
+ this._mergeElements(scmd, elm.parentNode, elm, false);\r
}\r
}\r
\r
tmp.appendChild(elm.cloneNode(false));\r
\r
// Is empty span, remove it\r
- tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style|class=""', 'gi'), '');\r
+ tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), '');\r
+ //tinyMCE.debug(tmp.innerHTML);\r
if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {\r
for (var x=0; x<elm.childNodes.length; x++) {\r
if (elm.parentNode != null)\r
break;\r
\r
case "FontName":\r
- if (tinyMCE.getParam("convert_fonts_to_styles"))\r
- this.execCommand("SetStyleInfo", false, {command : "setstyle", name : "fontFamily", value : value});\r
- else\r
+ if (value == null) {\r
+ var s = this.getSel();\r
+\r
+ // Find font and select it\r
+ if (tinyMCE.isGecko && s.isCollapsed) {\r
+ var f = tinyMCE.getParentElement(this.getFocusElement(), "font");\r
+\r
+ if (f != null)\r
+ this.selectNode(f, false);\r
+ }\r
+\r
+ // Remove format\r
+ this.getDoc().execCommand("RemoveFormat", false, null);\r
+\r
+ // Collapse range if font was found\r
+ if (f != null && tinyMCE.isGecko) {\r
+ var r = this.getRng().cloneRange();\r
+ r.collapse(true);\r
+ s.removeAllRanges();\r
+ s.addRange(r);\r
+ }\r
+ } else\r
this.getDoc().execCommand('FontName', false, value);\r
- break;\r
+\r
+ if (tinyMCE.isGecko)\r
+ window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);\r
+\r
+ return;\r
\r
case "FontSize":\r
- if (tinyMCE.getParam("convert_fonts_to_styles")) {\r
- var sizes = new Array('', 8, 10, 12, 14, 18, 24, 36);\r
- var size = sizes[value] == '' ? '' : sizes[value] + 'px';\r
+ this.getDoc().execCommand('FontSize', false, value);\r
\r
- this.execCommand("SetStyleInfo", false, {command : "setstyle", name : "fontSize", value : size});\r
- } else\r
- this.getDoc().execCommand('FontSize', false, value);\r
+ if (tinyMCE.isGecko)\r
+ window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);\r
\r
- break;\r
+ return;\r
\r
case "forecolor":\r
- if (tinyMCE.getParam("convert_fonts_to_styles"))\r
- this.execCommand("SetStyleInfo", false, {command : "setstyle", name : "color", value : value});\r
- else {\r
- if (tinyMCE.isGecko) {\r
- this.getDoc().execCommand("useCSS", false, true);\r
- this.getDoc().execCommand('forecolor', false, value);\r
- this.getDoc().execCommand("useCSS", false, true);\r
- } else\r
- this.getDoc().execCommand('forecolor', false, value);\r
- }\r
+ this.getDoc().execCommand('forecolor', false, value);\r
break;\r
\r
case "HiliteColor":\r
- if (tinyMCE.getParam("convert_fonts_to_styles"))\r
- this.execCommand("SetStyleInfo", false, {command : "setstyle", name : "backgroundColor", value : value});\r
- else {\r
- if (tinyMCE.isGecko) {\r
- this.getDoc().execCommand("useCSS", false, false);\r
- this.getDoc().execCommand('hilitecolor', false, value);\r
- this.getDoc().execCommand("useCSS", false, true);\r
- } else\r
- this.getDoc().execCommand('BackColor', false, value);\r
- }\r
-\r
+ if (tinyMCE.isGecko) {\r
+ this.setUseCSS(true);\r
+ this.getDoc().execCommand('hilitecolor', false, value);\r
+ this.setUseCSS(false);\r
+ } else\r
+ this.getDoc().execCommand('BackColor', false, value);\r
break;\r
\r
case "Cut":\r
// Try executing command\r
eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');\r
\r
+ if (tinyMCE.isOpera && cmdFailed)\r
+ alert('Currently not supported by your browser, use keyboard shortcuts instead.');\r
+\r
// Alert error in gecko if command failed\r
if (tinyMCE.isGecko && cmdFailed) {\r
// Confirm more info\r
value = "";\r
\r
// Call custom cleanup code\r
+ value = tinyMCE.storeAwayURLs(value);\r
value = tinyMCE._customCleanup(this, "insert_to_editor", value);\r
tinyMCE._setHTML(doc, value);\r
- doc.body.innerHTML = tinyMCE._cleanupHTML(this, doc, tinyMCE.settings, doc.body);\r
+ tinyMCE.setInnerHTML(doc.body, tinyMCE._cleanupHTML(this, doc, tinyMCE.settings, doc.body));\r
+ this.convertAllRelativeURLs();\r
tinyMCE.handleVisualAid(doc.body, true, this.visualAid, this);\r
- tinyMCE._setEventsEnabled(doc.body, true);\r
+ tinyMCE._setEventsEnabled(doc.body, false);\r
return true;\r
\r
case "mceLink":\r
\r
onclick = tinyMCE.cleanupEventStr(onclick);\r
\r
- // Fix for drag-drop/copy paste bug in Mozilla\r
- mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_real_href');\r
- if (mceRealHref != "")\r
+ href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");\r
+\r
+ // Use mce_href if defined\r
+ mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href');\r
+ if (mceRealHref != "") {\r
href = mceRealHref;\r
\r
- href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");\r
+ if (tinyMCE.getParam('convert_urls'))\r
+ href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");\r
+ }\r
+\r
action = "update";\r
}\r
\r
if (returnVal && returnVal['href'])\r
tinyMCE.insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']);\r
} else {\r
- tinyMCE.openWindow(this.insertLinkTemplate, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class});\r
+ tinyMCE.openWindow(this.insertLinkTemplate, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"});\r
}\r
break;\r
\r
onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover));\r
onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout));\r
\r
- // Fix for drag-drop/copy paste bug in Mozilla\r
- mceRealSrc = tinyMCE.getAttrib(img, 'mce_real_src');\r
- if (mceRealSrc != "")\r
+ src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");\r
+\r
+ // Use mce_src if defined\r
+ mceRealSrc = tinyMCE.getAttrib(img, 'mce_src');\r
+ if (mceRealSrc != "") {\r
src = mceRealSrc;\r
\r
- src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");\r
+ if (tinyMCE.getParam('convert_urls'))\r
+ src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");\r
+ }\r
\r
if (onmouseover != "")\r
onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);");\r
if (returnVal && returnVal['src'])\r
tinyMCE.insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']);\r
} else\r
- tinyMCE.openWindow(this.insertImageTemplate, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action});\r
+ tinyMCE.openWindow(this.insertImageTemplate, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"});\r
break;\r
\r
case "mceCleanup":\r
tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML);\r
- this.getBody().innerHTML = tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid);\r
+ tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid));\r
+ this.convertAllRelativeURLs();\r
tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);\r
- tinyMCE._setEventsEnabled(this.getBody(), true);\r
+ tinyMCE._setEventsEnabled(this.getBody(), false);\r
this.repaint();\r
tinyMCE.triggerNodeChange();\r
break;\r
\r
case "mceReplaceContent":\r
+ this.getWin().focus();\r
+\r
var selectedText = "";\r
\r
if (tinyMCE.isMSIE) {\r
// Find marker and replace with RAW HTML\r
var html = this.getBody().innerHTML;\r
if ((pos = html.indexOf(key)) != -1)\r
- this.getBody().innerHTML = html.substring(0, pos) + value + html.substring(pos + key.length);\r
+ tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length));\r
\r
// Restore scoll pos\r
this.contentWindow.scrollTo(scrollX, scrollY);\r
break;\r
\r
case "mceInsertContent":\r
+ var insertHTMLFailed = false;\r
+ this.getWin().focus();\r
+\r
+ if (tinyMCE.isGecko || tinyMCE.isOpera) {\r
+ try {\r
+ // Is plain text or HTML\r
+ if (value.indexOf('<') == -1) {\r
+ var r = this.getRng();\r
+ var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value));\r
+ var s = this.getSel();\r
+ var r2 = r.cloneRange();\r
+\r
+ // Insert text at cursor position\r
+ s.removeAllRanges();\r
+ r.deleteContents();\r
+ r.insertNode(n);\r
+\r
+ // Move the cursor to the end of text\r
+ r2.selectNode(n);\r
+ r2.collapse(false);\r
+ s.removeAllRanges();\r
+ s.addRange(r2);\r
+ } else {\r
+ value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value);\r
+ this.getDoc().execCommand('inserthtml', false, value);\r
+ tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);\r
+ }\r
+ } catch (ex) {\r
+ insertHTMLFailed = true;\r
+ }\r
+\r
+ if (!insertHTMLFailed) {\r
+ tinyMCE.triggerNodeChange();\r
+ return;\r
+ }\r
+ }\r
+\r
+ // Ugly hack in Opera due to non working "inserthtml"\r
+ if (tinyMCE.isOpera && insertHTMLFailed) {\r
+ this.getDoc().execCommand("insertimage", false, tinyMCE.uniqueURL);\r
+ var ar = tinyMCE.getElementsByAttributeValue(this.getBody(), "img", "src", tinyMCE.uniqueURL);\r
+ ar[0].outerHTML = value;\r
+ return;\r
+ }\r
+\r
if (!tinyMCE.isMSIE) {\r
+ var isHTML = value.indexOf('<') != -1;\r
var sel = this.getSel();\r
var rng = this.getRng();\r
- var isHTML = value.indexOf('<') != -1;\r
\r
if (isHTML) {\r
if (tinyMCE.isSafari) {\r
rng.collapse(false);\r
} else {\r
var rng = doc.selection.createRange();\r
+ var c = value.indexOf('<!--') != -1;\r
+\r
+ // Fix comment bug, add tag before comments\r
+ if (c)\r
+ value = tinyMCE.uniqueTag + value;\r
\r
if (rng.item)\r
rng.item(0).outerHTML = value;\r
else\r
rng.pasteHTML(value);\r
+\r
+ // Remove unique tag\r
+ if (c) {\r
+ var e = this.getDoc().getElementById('mceTMPElement');\r
+ e.parentNode.removeChild(e);\r
+ }\r
}\r
\r
tinyMCE.triggerNodeChange();\r
\r
var newHTML = tinyMCE.trim(this.getBody().innerHTML);\r
if (newHTML != this.undoLevels[this.undoIndex]) {\r
- // tinyMCE.debug("[" + newHTML + "," + this.undoLevels[this.undoIndex] + "]");\r
-\r
tinyMCE.executeCallback('onchange_callback', '_onchange', 0, this);\r
\r
// Time to compress\r
// Do undo\r
if (this.undoIndex > 0) {\r
this.undoIndex--;\r
- this.getBody().innerHTML = this.undoLevels[this.undoIndex];\r
+ tinyMCE.setInnerHTML(this.getBody(), this.undoLevels[this.undoIndex]);\r
this.repaint();\r
}\r
\r
\r
if (this.undoIndex < (this.undoLevels.length-1)) {\r
this.undoIndex++;\r
- this.getBody().innerHTML = this.undoLevels[this.undoIndex];\r
+ tinyMCE.setInnerHTML(this.getBody(), this.undoLevels[this.undoIndex]);\r
this.repaint();\r
// tinyMCE.debug("Redo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);\r
}\r
n.removeAttribute("dir");\r
n.removeAttribute("style");\r
}\r
- } while (n = n.parentNode);\r
+ } while (n != null && (n = n.parentNode) != null);\r
}\r
break;\r
\r
case "removeformat":\r
var text = this.getSelectedText();\r
\r
+ if (tinyMCE.isOpera) {\r
+ this.getDoc().execCommand("RemoveFormat", false, null);\r
+ return;\r
+ }\r
+\r
if (tinyMCE.isMSIE) {\r
try {\r
var rng = doc.selection.createRange();\r
\r
default:\r
this.getDoc().execCommand(command, user_interface, value);\r
- tinyMCE.triggerNodeChange();\r
+\r
+ if (tinyMCE.isGecko)\r
+ window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);\r
+ else\r
+ tinyMCE.triggerNodeChange();\r
}\r
\r
// Add undo level after modification\r
};\r
\r
TinyMCEControl.prototype.queryCommandValue = function(command) {\r
- return this.getDoc().queryCommandValue(command);\r
+ try {\r
+ return this.getDoc().queryCommandValue(command);\r
+ } catch (ex) {\r
+ return null;\r
+ }\r
};\r
\r
TinyMCEControl.prototype.queryCommandState = function(command) {\r
rng.setStartBefore(replace_element);\r
\r
var fragment = rng.createContextualFragment(html);\r
- replace_element.parentNode.insertBefore(fragment, replace_element);\r
+\r
+ if (tinyMCE.isGecko)\r
+ tinyMCE.insertAfter(fragment, replace_element);\r
+ else\r
+ replace_element.parentNode.insertBefore(fragment, replace_element);\r
} else\r
replace_element.insertAdjacentHTML("beforeBegin", html);\r
}\r
\r
this.targetElement = tElm;\r
this.iframeElement = targetDoc.getElementById(this.editorId);\r
- this.contentDocument = tElm.window.document;\r
- this.contentWindow = tElm.window;\r
+\r
+ if (tinyMCE.isOpera) {\r
+ this.contentDocument = this.iframeElement.contentDocument;\r
+ this.contentWindow = this.iframeElement.contentWindow;\r
+ dynamicIFrame = true;\r
+ } else {\r
+ this.contentDocument = tElm.window.document;\r
+ this.contentWindow = tElm.window;\r
+ }\r
+\r
this.getDoc().designMode = "on";\r
}\r
\r
// Setup base HTML\r
var doc = this.contentDocument;\r
if (dynamicIFrame) {\r
- var html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';\r
+ var html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';\r
\r
try {\r
- this.getDoc().designMode = "on";\r
+ if (!this.isHidden())\r
+ this.getDoc().designMode = "on";\r
+\r
doc.open();\r
doc.write(html);\r
doc.close();\r
};\r
\r
TinyMCEControl.prototype.getFocusElement = function() {\r
- if (tinyMCE.isMSIE) {\r
+ if (tinyMCE.isMSIE && !tinyMCE.isOpera) {\r
var doc = this.getDoc();\r
var rng = doc.selection.createRange();\r
\r
- if (rng.collapse)\r
- rng.collapse(true);\r
+// if (rng.collapse)\r
+// rng.collapse(true);\r
\r
var elm = rng.item ? rng.item(0) : rng.parentElement();\r
} else {\r
+ if (this.isHidden())\r
+ return this.getBody();\r
+\r
var sel = this.getSel();\r
var rng = this.getRng();\r
+\r
var elm = rng.commonAncestorContainer;\r
//var elm = (sel && sel.anchorNode) ? sel.anchorNode : null;\r
\r