From 4315b0086b14cd5266b4cb824c3bd95aa550240c Mon Sep 17 00:00:00 2001 From: svncommit Date: Tue, 11 Dec 2007 04:20:01 +0000 Subject: added ability to insert attached images in HTML editor --- program/js/tiny_mce/tiny_mce_src.js | 15214 +++++++++++++++++----------------- 1 file changed, 7607 insertions(+), 7607 deletions(-) (limited to 'program/js/tiny_mce/tiny_mce_src.js') diff --git a/program/js/tiny_mce/tiny_mce_src.js b/program/js/tiny_mce/tiny_mce_src.js index 954ca1aa4..d14c85800 100644 --- a/program/js/tiny_mce/tiny_mce_src.js +++ b/program/js/tiny_mce/tiny_mce_src.js @@ -1,7607 +1,7607 @@ - -/* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */ - -function TinyMCE_Engine() { - var ua; - - this.majorVersion = "2"; - this.minorVersion = "1.3"; - this.releaseDate = "2007-11-27"; - - this.instances = []; - this.switchClassCache = []; - this.windowArgs = []; - this.loadedFiles = []; - this.pendingFiles = []; - this.loadingIndex = 0; - this.configs = []; - this.currentConfig = 0; - this.eventHandlers = []; - this.log = []; - this.undoLevels = []; - this.undoIndex = 0; - this.typingUndoIndex = -1; - this.settings = []; - - // Browser check - ua = navigator.userAgent; - this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); - this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1); - this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1); - this.isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1); - this.isGecko = ua.indexOf('Gecko') != -1; // Will also be true on Safari - this.isSafari = ua.indexOf('Safari') != -1; - this.isOpera = window['opera'] && opera.buildNumber ? true : false; - this.isMac = ua.indexOf('Mac') != -1; - this.isNS7 = ua.indexOf('Netscape/7') != -1; - this.isNS71 = ua.indexOf('Netscape/7.1') != -1; - this.dialogCounter = 0; - this.plugins = []; - this.themes = []; - this.menus = []; - this.loadedPlugins = []; - this.buttonMap = []; - this.isLoaded = false; - - // Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those - if (this.isOpera) { - this.isMSIE = true; - this.isGecko = false; - this.isSafari = false; - } - - this.isIE = this.isMSIE; - this.isRealIE = this.isMSIE && !this.isOpera; - - // TinyMCE editor id instance counter - this.idCounter = 0; -}; - -TinyMCE_Engine.prototype = { - init : function(settings) { - var theme, nl, baseHREF = "", i, cssPath, entities, h, p, src, elements = [], head; - - // IE 5.0x is no longer supported since 5.5, 6.0 and 7.0 now exists. We can't support old browsers forever, sorry. - if (this.isMSIE5_0) - return; - - this.settings = settings; - - // Check if valid browser has execcommand support - if (typeof(document.execCommand) == 'undefined') - return; - - // Get script base path - if (!tinyMCE.baseURL) { - // Search through head - head = document.getElementsByTagName('head')[0]; - - if (head) { - for (i=0, nl = head.getElementsByTagName('script'); i'); - this._def("font_size_classes", ''); - this._def("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large', true); - this._def("event_elements", 'a,img', true); - this._def("convert_urls", true); - this._def("table_inline_editing", false); - this._def("object_resizing", true); - this._def("custom_shortcuts", true); - this._def("convert_on_click", false); - this._def("content_css", ''); - this._def("fix_list_elements", true); - this._def("fix_table_elements", false); - this._def("strict_loading_mode", document.contentType == 'application/xhtml+xml'); - this._def("hidden_tab_class", ''); - this._def("display_tab_class", ''); - this._def("gecko_spellcheck", false); - this._def("hide_selects_on_submit", true); - this._def("forced_root_block", false); - this._def("remove_trailing_nbsp", false); - this._def("save_on_tinymce_forms", false); - - // Force strict loading mode to false on non Gecko browsers - if (this.isMSIE && !this.isOpera) - this.settings.strict_loading_mode = false; - - // Browser check IE - if (this.isMSIE && this.settings.browsers.indexOf('msie') == -1) - return; - - // Browser check Gecko - if (this.isGecko && this.settings.browsers.indexOf('gecko') == -1) - return; - - // Browser check Safari - if (this.isSafari && this.settings.browsers.indexOf('safari') == -1) - return; - - // Browser check Opera - if (this.isOpera && this.settings.browsers.indexOf('opera') == -1) - return; - - // If not super absolute make it so - baseHREF = tinyMCE.settings.document_base_url; - h = document.location.href; - p = h.indexOf('://'); - if (p > 0 && document.location.protocol != "file:") { - p = h.indexOf('/', p + 3); - h = h.substring(0, p); - - if (baseHREF.indexOf('://') == -1) - baseHREF = h + baseHREF; - - tinyMCE.settings.document_base_url = baseHREF; - tinyMCE.settings.document_base_prefix = h; - } - - // Trim away query part - if (baseHREF.indexOf('?') != -1) - baseHREF = baseHREF.substring(0, baseHREF.indexOf('?')); - - this.settings.base_href = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/"; - - theme = this.settings.theme; - this.inlineStrict = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment'; - this.inlineTransitional = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment'; - this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP'; - this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i"); - this.posKeyCodes = [13,45,36,35,33,34,37,38,39,40]; - this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL - this.uniqueTag = ''; - this.callbacks = ['onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance']; - - // Theme url - this.settings.theme_href = tinyMCE.baseURL + "/themes/" + theme; - - if (!tinyMCE.isIE || tinyMCE.isOpera) - this.settings.force_br_newlines = false; - - if (tinyMCE.getParam("popups_css", false)) { - cssPath = tinyMCE.getParam("popups_css", ""); - - // Is relative - if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/') - this.settings.popups_css = this.documentBasePath + "/" + cssPath; - else - this.settings.popups_css = cssPath; - } else - this.settings.popups_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css"; - - if (tinyMCE.getParam("editor_css", false)) { - cssPath = tinyMCE.getParam("editor_css", ""); - - // Is relative - if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/') - this.settings.editor_css = this.documentBasePath + "/" + cssPath; - else - this.settings.editor_css = cssPath; - } else { - if (this.settings.editor_css !== '') - this.settings.editor_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css"; - } - - // Only do this once - if (this.configs.length == 0) { - if (typeof(TinyMCECompressed) == "undefined") { - tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad); - - if (tinyMCE.isRealIE) { - if (document.body) - tinyMCE.addEvent(document.body, "readystatechange", TinyMCE_Engine.prototype.onLoad); - else - tinyMCE.addEvent(document, "readystatechange", TinyMCE_Engine.prototype.onLoad); - } - - tinyMCE.addEvent(window, "load", TinyMCE_Engine.prototype.onLoad); - tinyMCE._addUnloadEvents(); - } - } - - this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings.theme + '/editor_template' + tinyMCE.srcMode + '.js'); - this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings.language + '.js'); - this.loadCSS(this.settings.editor_css); - - // Add plugins - p = tinyMCE.getParam('plugins', '', true, ','); - if (p.length > 0) { - for (i=0; i&"]', 'g'); - }, - - _addUnloadEvents : function() { - var st = tinyMCE.settings.add_unload_trigger; - - if (tinyMCE.isIE) { - if (st) { - tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler); - tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler); - } - } else { - if (st) - tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);}); - } - }, - - _def : function(key, def_val, t) { - var v = tinyMCE.getParam(key, def_val); - - v = t ? v.replace(/\s+/g, "") : v; - - this.settings[key] = v; - }, - - hasPlugin : function(n) { - return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; - }, - - addPlugin : function(n, p) { - var op = this.plugins[n]; - - // Use the previous plugin object base URL used when loading external plugins - p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n; - this.plugins[n] = p; - - this.loadNextScript(); - }, - - setPluginBaseURL : function(n, u) { - var op = this.plugins[n]; - - if (op) - op.baseURL = u; - else - this.plugins[n] = {baseURL : u}; - }, - - loadPlugin : function(n, u) { - u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u; - u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u; - this.plugins[n] = {baseURL : u}; - this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js"); - }, - - hasTheme : function(n) { - return typeof(this.themes[n]) != "undefined" && this.themes[n] != null; - }, - - addTheme : function(n, t) { - this.themes[n] = t; - - this.loadNextScript(); - }, - - addMenu : function(n, m) { - this.menus[n] = m; - }, - - hasMenu : function(n) { - return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; - }, - - loadScript : function(url) { - var i; - - for (i=0; i'); - - this.loadedFiles[this.loadedFiles.length] = url; - }, - - loadNextScript : function() { - var d = document, se; - - if (!tinyMCE.settings.strict_loading_mode) - return; - - if (this.loadingIndex < this.pendingFiles.length) { - se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script'); - se.setAttribute('language', 'javascript'); - se.setAttribute('type', 'text/javascript'); - se.setAttribute('src', this.pendingFiles[this.loadingIndex++]); - - d.getElementsByTagName("head")[0].appendChild(se); - } else - this.loadingIndex = -1; // Done with loading - }, - - loadCSS : function(url) { - var ar = url.replace(/\s+/, '').split(','); - var lflen = 0, csslen = 0, skip = false; - var x = 0, i = 0, nl, le; - - for (x = 0,csslen = ar.length; x 0) { - /* Make sure it doesn't exist. */ - for (i=0, lflen=this.loadedFiles.length; i'); - - this.loadedFiles[this.loadedFiles.length] = ar[x]; - } - } - } - }, - - importCSS : function(doc, css) { - var css_ary = css.replace(/\s+/, '').split(','); - var csslen, elm, headArr, x, css_file; - - for (x = 0, csslen = css_ary.length; x 0) { - // Is relative, make absolute - if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/') - css_file = this.documentBasePath + "/" + css_file; - - if (typeof(doc.createStyleSheet) == "undefined") { - elm = doc.createElement("link"); - - elm.rel = "stylesheet"; - elm.href = css_file; - - if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0) - headArr[0].appendChild(elm); - } else - doc.createStyleSheet(css_file); - } - } - }, - - confirmAdd : function(e, settings) { - var elm = tinyMCE.isIE ? event.srcElement : e.target; - var elementId = elm.name ? elm.name : elm.id; - - tinyMCE.settings = settings; - - if (tinyMCE.settings.convert_on_click || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang.lang_edit_confirm))) - tinyMCE.addMCEControl(elm, elementId); - - elm.setAttribute('mce_noask', 'true'); - }, - - updateContent : function(form_element_name) { - var formElement, n, inst, doc; - - // Find MCE instance linked to given form element and copy it's value - formElement = document.getElementById(form_element_name); - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst)) - continue; - - inst.switchSettings(); - - if (inst.formElement == formElement) { - doc = inst.getDoc(); - - tinyMCE._setHTML(doc, inst.formElement.value); - - if (!tinyMCE.isIE) - doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid); - } - } - }, - - addMCEControl : function(replace_element, form_element_name, target_document) { - var id = "mce_editor_" + tinyMCE.idCounter++; - var inst = new TinyMCE_Control(tinyMCE.settings); - - inst.editorId = id; - this.instances[id] = inst; - - inst._onAdd(replace_element, form_element_name, target_document); - }, - - removeInstance : function(ti) { - var t = [], n, i; - - // Remove from instances - for (n in tinyMCE.instances) { - i = tinyMCE.instances[n]; - - if (tinyMCE.isInstance(i) && ti != i) - t[n] = i; - } - - tinyMCE.instances = t; - - // Remove from global undo/redo - n = []; - t = tinyMCE.undoLevels; - - for (i=0; i 0) { - tinyMCE.nextUndoRedoAction = 'Undo'; - inst = this.undoLevels[--this.undoIndex]; - inst.select(); - - if (!tinyMCE.nextUndoRedoInstanceId) - inst.execCommand('Undo'); - } - } else - inst.execCommand('Undo'); - return true; - - case "Redo": - if (this.getParam('custom_undo_redo_global')) { - if (this.undoIndex <= this.undoLevels.length - 1) { - tinyMCE.nextUndoRedoAction = 'Redo'; - inst = this.undoLevels[this.undoIndex++]; - inst.select(); - - if (!tinyMCE.nextUndoRedoInstanceId) - inst.execCommand('Redo'); - } - } else - inst.execCommand('Redo'); - - return true; - - case 'mceFocus': - inst = tinyMCE.getInstanceById(value); - - if (inst) - inst.getWin().focus(); - return; - - case "mceAddControl": - case "mceAddEditor": - tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); - return; - - case "mceAddFrameControl": - tinyMCE.addMCEControl(tinyMCE._getElementById(value.element, value.document), value.element, value.document); - return; - - case "mceRemoveControl": - case "mceRemoveEditor": - tinyMCE.removeMCEControl(value); - return; - - case "mceToggleEditor": - inst = tinyMCE.getInstanceById(value); - - if (inst) { - pe = document.getElementById(inst.editorId + '_parent'); - te = inst.oldTargetElement; - - if (typeof(inst.enabled) == 'undefined') - inst.enabled = true; - - inst.enabled = !inst.enabled; - - if (!inst.enabled) { - pe.style.display = 'none'; - - if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT') - te.value = inst.getHTML(); - else - te.innerHTML = inst.getHTML(); - - te.style.display = inst.oldTargetDisplay; - tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst); - } else { - pe.style.display = 'block'; - te.style.display = 'none'; - - if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT') - inst.setHTML(te.value); - else - inst.setHTML(te.innerHTML); - - inst.useCSS = false; - tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst); - } - } else - tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); - - return; - - case "mceResetDesignMode": - // Resets the designmode state of the editors in Gecko - if (tinyMCE.isGecko) { - for (n in tinyMCE.instances) { - if (!tinyMCE.isInstance(tinyMCE.instances[n])) - continue; - - try { - tinyMCE.instances[n].getDoc().designMode = "off"; - tinyMCE.instances[n].getDoc().designMode = "on"; - tinyMCE.instances[n].useCSS = false; - } catch (e) { - // Ignore any errors - } - } - } - - return; - } - - if (inst) { - inst.execCommand(command, user_interface, value); - } else if (tinyMCE.settings.focus_alert) - alert(tinyMCELang.lang_focus_alert); - }, - - _createIFrame : function(replace_element, doc, win) { - var iframe, id = replace_element.getAttribute("id"); - var aw, ah; - - if (typeof(doc) == "undefined") - doc = document; - - if (typeof(win) == "undefined") - win = window; - - iframe = doc.createElement("iframe"); - - aw = "" + tinyMCE.settings.area_width; - ah = "" + tinyMCE.settings.area_height; - - if (aw.indexOf('%') == -1) { - aw = parseInt(aw); - aw = (isNaN(aw) || aw < 0) ? 300 : aw; - aw = aw + "px"; - } - - if (ah.indexOf('%') == -1) { - ah = parseInt(ah); - ah = (isNaN(ah) || ah < 0) ? 240 : ah; - ah = ah + "px"; - } - - iframe.setAttribute("id", id); - iframe.setAttribute("name", id); - iframe.setAttribute("class", "mceEditorIframe"); - iframe.setAttribute("border", "0"); - iframe.setAttribute("frameBorder", "0"); - iframe.setAttribute("marginWidth", "0"); - iframe.setAttribute("marginHeight", "0"); - iframe.setAttribute("leftMargin", "0"); - iframe.setAttribute("topMargin", "0"); - iframe.setAttribute("width", aw); - iframe.setAttribute("height", ah); - iframe.setAttribute("allowtransparency", "true"); - iframe.className = 'mceEditorIframe'; - - if (tinyMCE.settings.auto_resize) - iframe.setAttribute("scrolling", "no"); - - // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs - if (tinyMCE.isRealIE) - iframe.setAttribute("src", this.settings.default_document); - - iframe.style.width = aw; - iframe.style.height = ah; - - // Ugly hack for Gecko problem in strict mode - if (tinyMCE.settings.strict_loading_mode) - iframe.style.marginBottom = '-5px'; - - // MSIE 5.0 issue - if (tinyMCE.isRealIE) - replace_element.outerHTML = iframe.outerHTML; - else - replace_element.parentNode.replaceChild(iframe, replace_element); - - if (tinyMCE.isRealIE) - return win.frames[id]; - else - return iframe; - }, - - setupContent : function(editor_id) { - var inst = tinyMCE.instances[editor_id], i, doc = inst.getDoc(), head = doc.getElementsByTagName('head').item(0); - var content = inst.startContent, contentElement, body; - - // HTML values get XML encoded in strict mode - if (tinyMCE.settings.strict_loading_mode) { - content = content.replace(/</g, '<'); - content = content.replace(/>/g, '>'); - content = content.replace(/"/g, '"'); - content = content.replace(/&/g, '&'); - } - - tinyMCE.selectedInstance = inst; - inst.switchSettings(); - - // Not loaded correctly hit it again, Mozilla bug #997860 - if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") { - // This part will remove the designMode status - // Failes first time in Firefox 1.5b2 on Mac - try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {} - window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000); - return; - } - - // Wait for it to load - if (!head || !doc.body) { - window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10); - return; - } - - // Import theme specific content CSS the user specific - tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings.theme + "/css/editor_content.css"); - tinyMCE.importCSS(inst.getDoc(), inst.settings.content_css); - tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst); - - // Setup keyboard shortcuts - if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) { - inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo'); - inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo'); - } - - // BlockFormat shortcuts keys - for (i=1; i<=6; i++) - inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, ''); - - inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '

'); - inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '

'); - inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '
'); - - // Add default shortcuts for gecko - if (tinyMCE.isGecko) { - inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold'); - inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic'); - inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline'); - } - - // Setup span styles - if (tinyMCE.getParam("convert_fonts_to_spans")) - inst.getBody().setAttribute('id', 'mceSpanFonts'); - - if (tinyMCE.settings.nowrap) - doc.body.style.whiteSpace = "nowrap"; - - doc.body.dir = this.settings.directionality; - doc.editorId = editor_id; - - // Add on document element in Mozilla - if (!tinyMCE.isIE) - doc.documentElement.editorId = editor_id; - - inst.setBaseHREF(tinyMCE.settings.base_href); - - // Replace new line characters to BRs - if (tinyMCE.settings.convert_newlines_to_brs) { - content = tinyMCE.regexpReplace(content, "\r\n", "
", "gi"); - content = tinyMCE.regexpReplace(content, "\r", "
", "gi"); - content = tinyMCE.regexpReplace(content, "\n", "
", "gi"); - } - - // Open closed anchors - // content = content.replace(new RegExp('', 'gi'), ''); - - // Call custom cleanup code - content = tinyMCE.storeAwayURLs(content); - content = tinyMCE._customCleanup(inst, "insert_to_editor", content); - - if (tinyMCE.isIE) { - // Ugly!!! - window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500); - - if (tinyMCE.settings.force_br_newlines) - doc.styleSheets[0].addRule("p", "margin: 0;"); - - body = inst.getBody(); - body.editorId = editor_id; - } - - content = tinyMCE.cleanupHTMLCode(content); - - // Fix for bug #958637 - if (!tinyMCE.isIE) { - contentElement = inst.getDoc().createElement("body"); - doc = inst.getDoc(); - - contentElement.innerHTML = content; - - if (tinyMCE.settings.cleanup_on_startup) - tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement)); - else - tinyMCE.setInnerHTML(inst.getBody(), content); - - tinyMCE.convertAllRelativeURLs(inst.getBody()); - } else { - if (tinyMCE.settings.cleanup_on_startup) { - tinyMCE._setHTML(inst.getDoc(), content); - - // Produces permission denied error in MSIE 5.5 - try { - tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody())); - } catch(e) { - // Ignore - } - } else - tinyMCE._setHTML(inst.getDoc(), content); - } - - // Fix for bug #957681 - //inst.getDoc().designMode = inst.getDoc().designMode; - - tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings.visual, inst); - tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); - - // Re-add design mode on mozilla - if (!tinyMCE.isIE) - tinyMCE.addEventHandlers(inst); - - // Add blur handler - if (tinyMCE.isIE) { - tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch); - tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953 - - // Workaround for drag drop/copy paste base href bug - if (!tinyMCE.isOpera) { - tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove); - tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch); - tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch); - } - } - - // Trigger node change, this call locks buttons for tables and so forth - inst.select(); - tinyMCE.selectedElement = inst.contentWindow.document.body; - - // Call custom DOM cleanup - tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody()); - tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody()); - tinyMCE._setEventsEnabled(inst.getBody(), false); - tinyMCE.cleanupAnchors(inst.getDoc()); - - if (tinyMCE.getParam("convert_fonts_to_spans")) - tinyMCE.convertSpansToFonts(inst.getDoc()); - - inst.startContent = tinyMCE.trim(inst.getBody().innerHTML); - inst.undoRedo.add({ content : inst.startContent }); - - // Cleanup any mess left from storyAwayURLs - if (tinyMCE.isGecko) { - // Remove mce_src from textnodes and comments - tinyMCE.selectNodes(inst.getBody(), function(n) { - if (n.nodeType == 3 || n.nodeType == 8) - n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); - - return false; - }); - } - - // Remove Gecko spellchecking - if (tinyMCE.isGecko) - inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck"); - - // Cleanup any mess left from storyAwayURLs - tinyMCE._removeInternal(inst.getBody()); - - inst.select(); - tinyMCE.triggerNodeChange(false, true); - }, - - storeAwayURLs : function(s) { - // Remove all mce_src, mce_href and replace them with new ones - // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); - // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); - - if (!s.match(/(mce_src|mce_href)/gi, s)) { - s = s.replace(new RegExp('src\\s*=\\s*[\"\']([^ >\"]*)[\"\']', 'gi'), 'src="$1" mce_src="$1"'); - s = s.replace(new RegExp('href\\s*=\\s*[\"\']([^ >\"]*)[\"\']', 'gi'), 'href="$1" mce_href="$1"'); - } - - return s; - }, - - _removeInternal : function(n) { - if (tinyMCE.isGecko) { - // Remove mce_src from textnodes and comments - tinyMCE.selectNodes(n, function(n) { - if (n.nodeType == 3 || n.nodeType == 8) - n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); - - return false; - }); - } - }, - - removeTinyMCEFormElements : function(form_obj) { - var i, elementId; - - // Skip form element removal - if (!tinyMCE.getParam('hide_selects_on_submit')) - return; - - // Check if form is valid - if (typeof(form_obj) == "undefined" || form_obj == null) - return; - - // If not a form, find the form - if (form_obj.nodeName != "FORM") { - if (form_obj.form) - form_obj = form_obj.form; - else - form_obj = tinyMCE.getParentElement(form_obj, "form"); - } - - // Still nothing - if (form_obj == null) - return; - - // Disable all UI form elements that TinyMCE created - for (i=0; i"); - rng.collapse(false); - rng.select(); - - tinyMCE.execCommand("mceAddUndoLevel"); - tinyMCE.triggerNodeChange(false); - return false; - } - } - - // Backspace or delete - if (e.keyCode == 8 || e.keyCode == 46) { - tinyMCE.selectedElement = e.target; - tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a"); - tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img"); - tinyMCE.triggerNodeChange(false); - } - - return false; - - case "keyup": - case "keydown": - tinyMCE.hideMenus(); - tinyMCE.hasMouseMoved = false; - - if (inst && inst.handleShortcut(e)) - return false; - - inst._fixRootBlocks(); - - if (inst.settings.remove_trailing_nbsp) - inst._fixTrailingNbsp(); - - if (e.target.editorId) - tinyMCE.instances[e.target.editorId].select(); - - if (tinyMCE.selectedInstance) - tinyMCE.selectedInstance.switchSettings(); - - inst = tinyMCE.selectedInstance; - - // Handle backspace - if (tinyMCE.isGecko && tinyMCE.settings.force_p_newlines && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { - // Insert P element instead of BR - if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { - // Cancel event - tinyMCE.execCommand("mceAddUndoLevel"); - e.preventDefault(); - return false; - } - } - - tinyMCE.selectedElement = null; - tinyMCE.selectedNode = null; - elm = tinyMCE.selectedInstance.getFocusElement(); - tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a"); - tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img"); - tinyMCE.selectedElement = elm; - - // Update visualaids on tabs - if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9) - tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings.visual, tinyMCE.selectedInstance); - - // Fix empty elements on return/enter, check where enter occured - if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13) - tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement(); - - // Fix empty elements on return/enter - if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) { - elm = tinyMCE.enterKeyElement; - if (elm) { - var re = new RegExp('^HR|IMG|BR$','g'); // Skip these - var dre = new RegExp('^H[1-6]$','g'); // Add double on these - - if (!elm.hasChildNodes() && !re.test(elm.nodeName)) { - if (dre.test(elm.nodeName)) - elm.innerHTML = "  "; - else - elm.innerHTML = " "; - } - } - } - - // Check if it's a position key - keys = tinyMCE.posKeyCodes; - var posKey = false; - for (i=0; i'; - h += '{$'+lang+'}'; - h += ''; - } else { - // Normal button - h += ''; - h += '{$'+lang+'}'; - h += ''; - } - - return h; - }, - - getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) { - var h = '', m, x; - - mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');'; - cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; - - if (typeof(ui) != "undefined" && ui != null) - cmd += ',' + ui; - - if (typeof(val) != "undefined" && val != null) - cmd += ",'" + val + "'"; - - cmd += ');'; - - // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled - if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { - x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); - - if (tinyMCE.isRealIE) - h += ''; - else - h += ''; - - h += ''; - h += ''; - h += ''; - h += ''; - } else { - if (tinyMCE.isRealIE) - h += ''; - else - h += ''; - - h += ''; - h += ''; - h += ''; - h += ''; - } - - return h; - }, - - _menuButtonEvent : function(e, o) { - if (o.className == 'mceMenuButtonFocus') - return; - - if (e == 'over') - o.className = o.className + ' mceMenuHover'; - else - o.className = o.className.replace(/\s.*$/, ''); - }, - - addButtonMap : function(m) { - var i, a = m.replace(/\s+/, '').split(','); - - for (i=0; i 0) - className += " "; - - className += classNames[i]; - } - - return className; - }, - - handleVisualAid : function(el, deep, state, inst, skip_dispatch) { - var i, x, y, tableElement, anchorName, oldW, oldH, bo, cn; - - if (!el) - return; - - if (!skip_dispatch) - tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst); - - tableElement = null; - - switch (el.nodeName) { - case "TABLE": - oldW = el.style.width; - oldH = el.style.height; - bo = tinyMCE.getAttrib(el, "border"); - - bo = bo == '' || bo == "0" ? true : false; - - tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo)); - - el.style.width = oldW; - el.style.height = oldH; - - for (y=0; y 0) - return inst.cssClasses; - - if (!doc) - return; - - styles = doc.styleSheets; - - if (styles && styles.length > 0) { - for (x=0; x' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + ''; - - return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); - } - } - - o = tinyMCE.themes[tinyMCE.settings.theme]; - if (o.getControlHTML && (v = o.getControlHTML(c)) !== '') { - if (rtl) - return '' + v + ''; - - return v; - } - - return ''; - }, - - evalFunc : function(f, idx, a, o) { - o = !o ? window : o; - f = typeof(f) == 'function' ? f : o[f]; - - return f.apply(o, Array.prototype.slice.call(a, idx)); - }, - - dispatchCallback : function(i, p, n) { - return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments); - }, - - executeCallback : function(i, p, n) { - return this.callFunc(i, p, n, 1, this.executeCallback.arguments); - }, - - execCommandCallback : function(i, p, n) { - return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments); - }, - - callFunc : function(ins, p, n, m, a) { - var l, i, on, o, s, v; - - s = m == 2; - - l = tinyMCE.getParam(p, ''); - - if (l !== '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0) - return true; - - if (ins != null) { - for (i=0, l = ins.plugins; i 0) - return true; - } - } - - l = tinyMCE.themes; - for (on in l) { - o = l[on]; - - if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) - return true; - } - - return false; - }, - - resolveDots : function(s, o) { - var i; - - if (typeof(s) == 'string') { - for (i=0, s=s.split('.'); i': - return '>'; - } - - return c; - }) : s; - }, - - add : function(c, m) { - var n; - - for (n in m) { - if (m.hasOwnProperty(n)) - c.prototype[n] = m[n]; - } - }, - - extend : function(p, np) { - var o = {}, n; - - o.parent = p; - - for (n in p) { - if (p.hasOwnProperty(n)) - o[n] = p[n]; - } - - for (n in np) { - if (np.hasOwnProperty(n)) - o[n] = np[n]; - } - - return o; - }, - - hideMenus : function() { - var e = tinyMCE.lastSelectedMenuBtn; - - if (tinyMCE.lastMenu) { - tinyMCE.lastMenu.hide(); - tinyMCE.lastMenu = null; - } - - if (e) { - tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass); - tinyMCE.lastSelectedMenuBtn = null; - } - } - - }; - -// Global instances -var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors -var tinyMCE = new TinyMCE_Engine(); -var tinyMCELang = {}; - -/* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */ - -function TinyMCE_Control(settings) { - var t, i, tos, fu, p, x, fn, fu, pn, s = settings; - - this.undoRedoLevel = true; - this.isTinyMCE_Control = true; - - // Default settings - this.enabled = true; - this.settings = s; - this.settings.theme = tinyMCE.getParam("theme", "default"); - this.settings.width = tinyMCE.getParam("width", -1); - this.settings.height = tinyMCE.getParam("height", -1); - this.selection = new TinyMCE_Selection(this); - this.undoRedo = new TinyMCE_UndoRedo(this); - this.cleanup = new TinyMCE_Cleanup(); - this.shortcuts = []; - this.hasMouseMoved = false; - this.foreColor = this.backColor = "#999999"; - this.data = {}; - this.cssClasses = []; - - this.cleanup.init({ - valid_elements : s.valid_elements, - extended_valid_elements : s.extended_valid_elements, - valid_child_elements : s.valid_child_elements, - entities : s.entities, - entity_encoding : s.entity_encoding, - debug : s.cleanup_debug, - indent : s.apply_source_formatting, - invalid_elements : s.invalid_elements, - verify_html : s.verify_html, - fix_content_duplication : s.fix_content_duplication, - convert_fonts_to_spans : s.convert_fonts_to_spans - }); - - // Wrap old theme - t = this.settings.theme; - if (!tinyMCE.hasTheme(t)) { - fn = tinyMCE.callbacks; - tos = {}; - - for (i=0; i 0) { - for (i=0; i 1 && tinyMCE.currentConfig != this.settings.index) { - tinyMCE.settings = this.settings; - tinyMCE.currentConfig = this.settings.index; - } - }, - - select : function() { - var oldInst = tinyMCE.selectedInstance; - - if (oldInst != this) { - if (oldInst) - oldInst.execCommand('mceEndTyping'); - - tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst); - tinyMCE.selectedInstance = this; - } - }, - - getBody : function() { - return this.contentBody ? this.contentBody : this.getDoc().body; - }, - - getDoc : function() { -// return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ? - return this.contentWindow.document; - }, - - getWin : function() { - return this.contentWindow; - }, - - getContainerWin : function() { - return this.containerWindow ? this.containerWindow : window; - }, - - getViewPort : function() { - return tinyMCE.getViewPort(this.getWin()); - }, - - getParentNode : function(n, f) { - return tinyMCE.getParentNode(n, f, this.getBody()); - }, - - getParentElement : function(n, na, f) { - return tinyMCE.getParentElement(n, na, f, this.getBody()); - }, - - getParentBlockElement : function(n) { - return tinyMCE.getParentBlockElement(n, this.getBody()); - }, - - resizeToContent : function() { - var d = this.getDoc(), b = d.body, de = d.documentElement; - - this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px'; - }, - - addShortcut : function(m, k, d, cmd, ui, va) { - var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts; - - if (!tinyMCE.getParam('custom_shortcuts')) - return false; - - m = m.toLowerCase(); - k = ie && !n ? k.toUpperCase() : k; - c = n ? null : k.charCodeAt(0); - d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d; - - sc = { - alt : m.indexOf('alt') != -1, - ctrl : m.indexOf('ctrl') != -1, - shift : m.indexOf('shift') != -1, - charCode : c, - keyCode : n ? k : (ie ? c : null), - desc : d, - cmd : cmd, - ui : ui, - val : va - }; - - for (i=0; i 1 && /(^\u00a0|\u00a0$)/.test(v)) { - e.firstChild.nodeValue = v.replace(/(^\u00a0|\u00a0$)/, ''); - s.selectNode(e.firstChild, true, false, false); // Select and collapse - } - } - }, - - _setUseCSS : function(b) { - var d = this.getDoc(); - - try {d.execCommand("useCSS", false, !b);} catch (ex) {} - try {d.execCommand("styleWithCSS", false, b);} catch (ex) {} - - if (!tinyMCE.getParam("table_inline_editing")) - try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {} - - if (!tinyMCE.getParam("object_resizing")) - try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {} - }, - - execCommand : function(command, user_interface, value) { - var i, x, z, align, img, div, doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement(); - - // Is not a undo specific command - if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) - this.undoBookmark = null; - - // Mozilla issue - if (!tinyMCE.isIE && !this.useCSS) { - this._setUseCSS(false); - this.useCSS = true; - } - - //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value); - this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks - - // Don't dispatch key commands - if (!/mceStartTyping|mceEndTyping/.test(command)) { - if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) - return; - } - - // Fix align on images - if (focusElm && focusElm.nodeName == "IMG") { - align = focusElm.getAttribute('align'); - img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm; - - switch (command) { - case "JustifyLeft": - if (align == 'left') { - img.setAttribute('align', ''); // Needed for IE - img.removeAttribute('align'); - } else - img.setAttribute('align', 'left'); - - // Remove the div - div = focusElm.parentNode; - if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) - div.parentNode.replaceChild(img, div); - - this.selection.selectNode(img); - this.repaint(); - tinyMCE.triggerNodeChange(); - return; - - case "JustifyCenter": - img.setAttribute('align', ''); // Needed for IE - img.removeAttribute('align'); - - // Is centered - div = tinyMCE.getParentElement(focusElm, "div"); - if (div && div.style.textAlign == "center") { - // Remove div - if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) - div.parentNode.replaceChild(img, div); - } else { - // Add div - div = this.getDoc().createElement("div"); - div.style.textAlign = 'center'; - div.appendChild(img); - focusElm.parentNode.replaceChild(div, focusElm); - } - - this.selection.selectNode(img); - this.repaint(); - tinyMCE.triggerNodeChange(); - return; - - case "JustifyRight": - if (align == 'right') { - img.setAttribute('align', ''); // Needed for IE - img.removeAttribute('align'); - } else - img.setAttribute('align', 'right'); - - // Remove the div - div = focusElm.parentNode; - if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) - div.parentNode.replaceChild(img, div); - - this.selection.selectNode(img); - this.repaint(); - tinyMCE.triggerNodeChange(); - return; - } - } - - if (tinyMCE.settings.force_br_newlines) { - var alignValue = ""; - - if (doc.selection.type != "Control") { - switch (command) { - case "JustifyLeft": - alignValue = "left"; - break; - - case "JustifyCenter": - alignValue = "center"; - break; - - case "JustifyFull": - alignValue = "justify"; - break; - - case "JustifyRight": - alignValue = "right"; - break; - } - - if (alignValue !== '') { - var rng = doc.selection.createRange(); - - if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null) - divElm.setAttribute("align", alignValue); - else if (rng.pasteHTML && rng.htmlText.length > 0) - rng.pasteHTML('
' + rng.htmlText + "
"); - - tinyMCE.triggerNodeChange(); - return; - } - } - } - - switch (command) { - case "mceRepaint": - this.repaint(); - return true; - - case "JustifyLeft": - case "JustifyCenter": - case "JustifyFull": - case "JustifyRight": - var el = tinyMCE.getParentNode(focusElm, function(n) {return tinyMCE.getAttrib(n, 'align');}); - - if (el) { - el.setAttribute('align', ''); // Needed for IE - el.removeAttribute('align'); - } else - this.getDoc().execCommand(command, user_interface, value); - - tinyMCE.triggerNodeChange(); - - return true; - - case "unlink": - // Unlink if caret is inside link - if (tinyMCE.isGecko && this.getSel().isCollapsed) { - focusElm = tinyMCE.getParentElement(focusElm, 'A'); - - if (focusElm) - this.selection.selectNode(focusElm, false); - } - - this.getDoc().execCommand(command, user_interface, value); - - tinyMCE.isGecko && this.getSel().collapseToEnd(); - - tinyMCE.triggerNodeChange(); - - return true; - - case "InsertUnorderedList": - case "InsertOrderedList": - this.getDoc().execCommand(command, user_interface, value); - tinyMCE.triggerNodeChange(); - break; - - case "Strikethrough": - this.getDoc().execCommand(command, user_interface, value); - tinyMCE.triggerNodeChange(); - break; - - case "mceSelectNode": - this.selection.selectNode(value); - tinyMCE.triggerNodeChange(); - tinyMCE.selectedNode = value; - break; - - case "FormatBlock": - if (value == null || value == '') { - var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp"); - - if (elm) - this.execCommand("mceRemoveNode", false, elm); - } else { - if (!this.cleanup.isValid(value)) - return true; - - if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) - value = value.replace(/[^a-z]/gi, ''); - - if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) { - var b = this.selection.getBookmark(); - this.getDoc().execCommand("FormatBlock", false, '

'); - tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value); - this.selection.moveToBookmark(b); - } else - this.getDoc().execCommand("FormatBlock", false, value); - } - - tinyMCE.triggerNodeChange(); - - break; - - case "mceRemoveNode": - if (!value) - value = tinyMCE.getParentElement(this.getFocusElement()); - - if (tinyMCE.isIE) { - value.outerHTML = value.innerHTML; - } else { - var rng = value.ownerDocument.createRange(); - rng.setStartBefore(value); - rng.setEndAfter(value); - rng.deleteContents(); - rng.insertNode(rng.createContextualFragment(value.innerHTML)); - } - - tinyMCE.triggerNodeChange(); - - break; - - case "mceSelectNodeDepth": - var parentNode = this.getFocusElement(); - for (i=0; parentNode; i++) { - if (parentNode.nodeName.toLowerCase() == "body") - break; - - if (parentNode.nodeName.toLowerCase() == "#text") { - i--; - parentNode = parentNode.parentNode; - continue; - } - - if (i == value) { - this.selection.selectNode(parentNode, false); - tinyMCE.triggerNodeChange(); - tinyMCE.selectedNode = parentNode; - return; - } - - parentNode = parentNode.parentNode; - } - - break; - - case "mceSetStyleInfo": - case "SetStyleInfo": - var rng = this.getRng(); - var sel = this.getSel(); - var scmd = value.command; - var sname = value.name; - var svalue = value.value == null ? '' : value.value; - //var svalue = value['value'] == null ? '' : value['value']; - var wrapper = value.wrapper ? value.wrapper : "span"; - var parentElm = null; - var invalidRe = new RegExp("^BODY|HTML$", "g"); - var invalidParentsRe = tinyMCE.settings.merge_styles_invalid_parents !== '' ? new RegExp(tinyMCE.settings.merge_styles_invalid_parents, "gi") : null; - - // Whole element selected check - if (tinyMCE.isIE) { - // Control range - if (rng.item) - parentElm = rng.item(0); - else { - var pelm = rng.parentElement(); - var prng = doc.selection.createRange(); - prng.moveToElementText(pelm); - - if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) { - if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName)) - parentElm = pelm; - } - } - } else { - var felm = this.getFocusElement(); - if (sel.isCollapsed || (new RegExp('td|tr|tbody|table|img', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode)) - parentElm = felm; - } - - // Whole element selected - if (parentElm && !invalidRe.test(parentElm.nodeName)) { - if (scmd == "setstyle") - tinyMCE.setStyleAttrib(parentElm, sname, svalue); - - if (scmd == "setattrib") - tinyMCE.setAttrib(parentElm, sname, svalue); - - if (scmd == "removeformat") { - parentElm.style.cssText = ''; - tinyMCE.setAttrib(parentElm, 'class', ''); - } - - // Remove style/attribs from all children - var ch = tinyMCE.getNodeTree(parentElm, [], 1); - for (z=0; z=0; i--) { - var elm = nodes[i]; - var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true"; - - elm.removeAttribute("mce_new"); - - // Is only child a element - if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) { - //tinyMCE.debug("merge1" + isNew); - this._mergeElements(scmd, elm, elm.childNodes[0], isNew); - continue; - } - - // Is I the only child - if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) { - //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName); - if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName)) - this._mergeElements(scmd, elm.parentNode, elm, false); - } - } - - // Remove empty wrappers - var nodes = doc.getElementsByTagName(wrapper); - for (i=nodes.length-1; i>=0; i--) { - var elm = nodes[i], isEmpty = true; - - // Check if it has any attribs - var tmp = doc.createElement("body"); - tmp.appendChild(elm.cloneNode(false)); - - // Is empty span, remove it - tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), ''); - //tinyMCE.debug(tmp.innerHTML); - if (new RegExp('', 'gi').test(tmp.innerHTML)) { - for (x=0; x 0) { - value = tinyMCE.replaceVar(value, "selection", selectedText); - tinyMCE.execCommand('mceInsertContent', false, value); - } - - this._addBogusBR(); - tinyMCE.triggerNodeChange(); - break; - - case "mceSetAttribute": - if (typeof(value) == 'object') { - var targetElms = (typeof(value.targets) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value.targets; - var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms); - - if (targetNode) { - targetNode.setAttribute(value.name, value.value); - tinyMCE.triggerNodeChange(); - } - } - break; - - case "mceSetCSSClass": - this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value}); - break; - - case "mceInsertRawHTML": - var key = 'tiny_mce_marker'; - - this.execCommand('mceBeginUndoLevel'); - - // Insert marker key - this.execCommand('mceInsertContent', false, key); - - // Store away scroll pos - var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft; - var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop; - - // Find marker and replace with RAW HTML - var html = this.getBody().innerHTML; - if ((pos = html.indexOf(key)) != -1) - tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length)); - - // Restore scoll pos - this.contentWindow.scrollTo(scrollX, scrollY); - - this.execCommand('mceEndUndoLevel'); - - break; - - case "mceInsertContent": - // Force empty string - if (!value) - value = ''; - - var insertHTMLFailed = false; - - // Removed since it produced problems in IE - // this.getWin().focus(); - - if (tinyMCE.isGecko || tinyMCE.isOpera) { - try { - // Is plain text or HTML, &,   etc will be encoded wrong in FF - if (value.indexOf('<') == -1 && !value.match(/(&| |<|>)/g)) { - var r = this.getRng(); - var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value)); - var s = this.getSel(); - var r2 = r.cloneRange(); - - // Insert text at cursor position - s.removeAllRanges(); - r.deleteContents(); - r.insertNode(n); - - // Move the cursor to the end of text - r2.selectNode(n); - r2.collapse(false); - s.removeAllRanges(); - s.addRange(r2); - } else { - value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value); - this.getDoc().execCommand('inserthtml', false, value); - tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); - } - } catch (ex) { - insertHTMLFailed = true; - } - - if (!insertHTMLFailed) { - tinyMCE.triggerNodeChange(); - return; - } - } - - if (!tinyMCE.isIE) { - var isHTML = value.indexOf('<') != -1; - var sel = this.getSel(); - var rng = this.getRng(); - - if (isHTML) { - if (tinyMCE.isSafari) { - var tmpRng = this.getDoc().createRange(); - - tmpRng.setStart(this.getBody(), 0); - tmpRng.setEnd(this.getBody(), 0); - - value = tmpRng.createContextualFragment(value); - } else - value = rng.createContextualFragment(value); - } else { - // Setup text node - value = doc.createTextNode(tinyMCE.entityDecode(value)); - } - - // Insert plain text in Safari - if (tinyMCE.isSafari && !isHTML) { - this.execCommand('InsertText', false, value.nodeValue); - tinyMCE.triggerNodeChange(); - return true; - } else if (tinyMCE.isSafari && isHTML) { - rng.deleteContents(); - rng.insertNode(value); - tinyMCE.triggerNodeChange(); - return true; - } - - rng.deleteContents(); - - // If target node is text do special treatment, (Mozilla 1.3 fix) - if (rng.startContainer.nodeType == 3) { - var node = rng.startContainer.splitText(rng.startOffset); - node.parentNode.insertBefore(value, node); - } else - rng.insertNode(value); - - if (!isHTML) { - // Removes weird selection trails - sel.selectAllChildren(doc.body); - sel.removeAllRanges(); - - // Move cursor to end of content - var rng = doc.createRange(); - - rng.selectNode(value); - rng.collapse(false); - - sel.addRange(rng); - } else - rng.collapse(false); - - tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); - } else { - var rng = doc.selection.createRange(), tmpRng = null; - var c = value.indexOf('"; - } - - if (hc) { - cn = n.childNodes; - - for (i=0, l=cn.length; i'; - - return h; - }, - - _serializeAttribute : function(n, r, an) { - var av = '', t, os = this.settings.on_save; - - if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0)) - return ''; - - if (os && this.mceAttribs[an]) - av = this._getAttrib(n, this.mceAttribs[an]); - - if (av.length == 0) - av = this._getAttrib(n, an); - - if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) { - av = t; - - if (av == "mce_empty") - return " " + an + '=""'; - } - - if (r.forceAttribs && (t = r.forceAttribs[an])) - av = t; - - if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an)) - av = this._urlConverter(this, n, av); - - if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av)) - return ""; - - if (av.length != 0 && av == "{$uid}") - av = "uid_" + (this.idCount++); - - if (av.length != 0) { - if (an.indexOf('on') != 0) - av = this.xmlEncode(av, 1); - - return " " + an + "=" + '"' + av + '"'; - } - - return ""; - }, - - formatHTML : function(h) { - var s = this.settings, p = '', i = 0, li = 0, o = '', l; - - // Replace BR in pre elements to \n - h = h.replace(/]*)>(.*?)<\/pre>/gi, function (a, b, c) { - c = c.replace(//gi, '\n'); - return '' + c + ''; - }); - - h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :) - h = '\n' + h; - h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting - h = h.replace(this.nlBeforeRe, '\n<$1$2>'); - h = h.replace(this.nlAfterRe, '<$1$2>\n'); - h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n'); - h += '\n'; - - //tinyMCE.debug(h); - - while ((i = h.indexOf('\n', i + 1)) != -1) { - if ((l = h.substring(li + 1, i)).length != 0) { - if (this.ouRe.test(l) && p.length >= s.indent_levels) - p = p.substring(s.indent_levels); - - o += p + l + '\n'; - - if (this.inRe.test(l)) - p += this.inStr; - } - - li = i; - } - - //tinyMCE.debug(h); - - return o; - }, - - xmlEncode : function(s) { - var cl = this, re = this.xmlEncodeRe; - - if (!this.entitiesDone) - this._setupEntities(); // Will intialize lookup table - - switch (this.settings.entity_encoding) { - case "raw": - return tinyMCE.xmlEncode(s); - - case "named": - return s.replace(re, function (c) { - var b = cl.entities[c.charCodeAt(0)]; - - return b ? '&' + b + ';' : c; - }); - - case "numeric": - return s.replace(re, function (c) { - return '&#' + c.charCodeAt(0) + ';'; - }); - } - - return s; - }, - - split : function(re, s) { - var i, l, o = [], c = s.split(re); - - for (i=0, l=c.length; i' : '>' + h + ''; - - return o; - }, - - createTag : function(d, tn, a, h) { - var o = d.createElement(tn), n; - - if (a) { - for (n in a) { - if (typeof(a[n]) != 'function' && a[n] != null) - tinyMCE.setAttrib(o, n, a[n]); - } - } - - if (h) - o.innerHTML = h; - - return o; - }, - - getElementByAttributeValue : function(n, e, a, v) { - return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0]; - }, - - getElementsByAttributeValue : function(n, e, a, v) { - var i, nl = n.getElementsByTagName(e), o = []; - - for (i=0; i]*)>/gi, ''); - h = h.replace(/]*)>/gi, ''); - h = h.replace(/]*)>/gi, ''); - h = h.replace(/]*)>/gi, ''); - h = h.replace(/<\/strong>/gi, ''); - h = h.replace(/<\/em>/gi, ''); - } - - if (tinyMCE.isRealIE) { - // Since MSIE handles invalid HTML better that valid XHTML we - // need to make some things invalid.


gets converted to
. - h = h.replace(/\s\/>/g, '>'); - - // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones - h = h.replace(/]*)>\u00A0?<\/p>/gi, ' 

'); // Keep empty paragraphs - h = h.replace(/]*)>\s* \s*<\/p>/gi, ' 

'); // Keep empty paragraphs - h = h.replace(/]*)>\s+<\/p>/gi, ' 

'); // Keep empty paragraphs - - // Remove first comment - e.innerHTML = tinyMCE.uniqueTag + h; - e.firstChild.removeNode(true); - - // Remove weird auto generated empty paragraphs unless it's supposed to be there - nl = e.getElementsByTagName("p"); - for (i=nl.length-1; i>=0; i--) { - n = nl[i]; - - if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep) - n.parentNode.removeChild(n); - } - } else { - h = this.fixGeckoBaseHREFBug(1, e, h); - e.innerHTML = h; - this.fixGeckoBaseHREFBug(2, e, h); - } - }, - - getOuterHTML : function(e) { - var d; - - if (tinyMCE.isIE) - return e.outerHTML; - - d = e.ownerDocument.createElement("body"); - d.appendChild(e.cloneNode(true)); - - return d.innerHTML; - }, - - setOuterHTML : function(e, h, d) { - var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t; - - if (tinyMCE.isIE && e.nodeType == 1) - e.outerHTML = h; - else { - t = d.createElement("body"); - t.innerHTML = h; - - for (i=0, nl=t.childNodes; i-1; i--) { - if (ar[i].specified && ar[i].nodeValue) - ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue); - } - - ar = e.childNodes; - for (i=0; i= strTok2.length) { - for (i=0; i= strTok2.length || strTok1[i] != strTok2[i]) { - breakPoint = i + 1; - break; - } - } - } - - if (strTok1.length < strTok2.length) { - for (i=0; i= strTok1.length || strTok1[i] != strTok2[i]) { - breakPoint = i + 1; - break; - } - } - } - - if (breakPoint == 1) - return targetURL.path; - - for (i=0; i<(strTok1.length-(breakPoint-1)); i++) - outPath += "../"; - - for (i=breakPoint-1; i=0; i--) { - if (baseURLParts[i].length == 0) - continue; - - newBaseURLParts[newBaseURLParts.length] = baseURLParts[i]; - } - baseURLParts = newBaseURLParts.reverse(); - - // Merge relURLParts chunks - newRelURLParts = []; - numBack = 0; - for (i=relURLParts.length-1; i>=0; i--) { - if (relURLParts[i].length == 0 || relURLParts[i] == ".") - continue; - - if (relURLParts[i] == '..') { - numBack++; - continue; - } - - if (numBack > 0) { - numBack--; - continue; - } - - newRelURLParts[newRelURLParts.length] = relURLParts[i]; - } - - relURLParts = newRelURLParts.reverse(); - - // Remove end from absolute path - len = baseURLParts.length-numBack; - absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/'); - start = ""; - end = ""; - - // Build output URL - relURL.protocol = baseURL.protocol; - relURL.host = baseURL.host; - relURL.port = baseURL.port; - - // Re-add trailing slash if it's removed - if (relURL.path.charAt(relURL.path.length-1) == "/") - absPath += "/"; - - relURL.path = absPath; - - return this.serializeURL(relURL); - }, - - convertURL : function(url, node, on_save) { - var dl = document.location, start, portPart, urlParts, baseUrlParts, tmpUrlParts, curl; - var prot = dl.protocol, host = dl.hostname, port = dl.port; - - // Pass through file protocol - if (prot == "file:") - return url; - - // Something is wrong, remove weirdness - url = tinyMCE.regexpReplace(url, '(http|https):///', '/'); - - // Mailto link or anchor (Pass through) - if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || /^[ \t\r\n\+]*[#\?]/.test(url)) - return url; - - // Fix relative/Mozilla - if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/') - return tinyMCE.settings.base_href + url; - - // Handle relative URLs - if (on_save && tinyMCE.getParam('relative_urls')) { - curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url); - if (curl.charAt(0) == '/') - curl = tinyMCE.settings.document_base_prefix + curl; - - urlParts = tinyMCE.parseURL(curl); - tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings.document_base_url); - - // Force relative - if (urlParts.host == tmpUrlParts.host && (urlParts.port == tmpUrlParts.port)) - return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings.document_base_url, curl); - } - - // Handle absolute URLs - if (!tinyMCE.getParam('relative_urls')) { - urlParts = tinyMCE.parseURL(url); - baseUrlParts = tinyMCE.parseURL(tinyMCE.settings.base_href); - - // Force absolute URLs from relative URLs - url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url); - - // If anchor and path is the same page - if (urlParts.anchor && urlParts.path == baseUrlParts.path) - return "#" + urlParts.anchor; - } - - // Remove current domain - if (tinyMCE.getParam('remove_script_host')) { - start = ""; - portPart = ""; - - if (port !== '') - portPart = ":" + port; - - start = prot + "//" + host + portPart + "/"; - - if (url.indexOf(start) == 0) - url = url.substring(start.length-1); - } - - return url; - }, - - convertAllRelativeURLs : function(body) { - var i, elms, src, href, mhref, msrc; - - // Convert all image URL:s to absolute URL - elms = body.getElementsByTagName("img"); - for (i=0; i bookmark.index) { - try { - rng.addElement(nl[bookmark.index]); - } catch (ex) { - // Might be thrown if the node no longer exists - } - } - } else { - // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs - try { - // Incorrect bookmark - if (bookmark.start < 0) - return true; - - rng = inst.getSel().createRange(); - rng.moveToElementText(inst.getBody()); - rng.collapse(true); - rng.moveStart('character', bookmark.start); - rng.moveEnd('character', bookmark.length); - } catch (ex) { - return true; - } - } - - rng.select(); - - win.scrollTo(bookmark.scrollX, bookmark.scrollY); - return true; - } - - if (tinyMCE.isGecko || tinyMCE.isOpera) { - if (!sel) - return false; - - if (bookmark.rng) { - sel.removeAllRanges(); - sel.addRange(bookmark.rng); - } - - if (bookmark.start != -1 && bookmark.end != -1) { - try { - sd = this._getTextPos(b, bookmark.start, bookmark.end); - rng = doc.createRange(); - rng.setStart(sd.startNode, sd.startOffset); - rng.setEnd(sd.endNode, sd.endOffset); - sel.removeAllRanges(); - sel.addRange(rng); - - if (!tinyMCE.isOpera) - win.focus(); - } catch (ex) { - // Ignore - } - } - - /* - if (typeof(bookmark.index) != 'undefined') { - tinyMCE.selectElements(b, 'IMG', function (n) { - if (bookmark.index-- == 0) { - // Select image in Gecko here - } - - return false; - }); - } - */ - - win.scrollTo(bookmark.scrollX, bookmark.scrollY); - return true; - } - - return false; - }, - - _getPosText : function(r, sn, en) { - var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; - - while ((n = w.nextNode()) != null) { - if (n == sn) - d.start = p; - - if (n == en) { - d.end = p; - return d; - } - - p += n.nodeValue ? n.nodeValue.length : 0; - } - - return null; - }, - - _getTextPos : function(r, sp, ep) { - var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; - - while ((n = w.nextNode()) != null) { - p += n.nodeValue ? n.nodeValue.length : 0; - - if (p >= sp && !d.startNode) { - d.startNode = n; - d.startOffset = sp - (p - n.nodeValue.length); - } - - if (p >= ep) { - d.endNode = n; - d.endOffset = ep - (p - n.nodeValue.length); - - return d; - } - } - - return null; - }, - - selectNode : function(node, collapse, select_text_node, to_start) { - var inst = this.instance, sel, rng, nodes; - - if (!node) - return; - - if (typeof(collapse) == "undefined") - collapse = true; - - if (typeof(select_text_node) == "undefined") - select_text_node = false; - - if (typeof(to_start) == "undefined") - to_start = true; - - if (inst.settings.auto_resize) - inst.resizeToContent(); - - if (tinyMCE.isRealIE) { - rng = inst.getDoc().body.createTextRange(); - - try { - rng.moveToElementText(node); - - if (collapse) - rng.collapse(to_start); - - rng.select(); - } catch (e) { - // Throws illigal agrument in MSIE some times - } - } else { - sel = this.getSel(); - - if (!sel) - return; - - if (tinyMCE.isSafari) { - sel.setBaseAndExtent(node, 0, node, node.innerText.length); - - if (collapse) { - if (to_start) - sel.collapseToStart(); - else - sel.collapseToEnd(); - } - - this.scrollToNode(node); - - return; - } - - rng = inst.getDoc().createRange(); - - if (select_text_node) { - // Find first textnode in tree - nodes = tinyMCE.getNodeTree(node, [], 3); - if (nodes.length > 0) - rng.selectNodeContents(nodes[0]); - else - rng.selectNodeContents(node); - } else - rng.selectNode(node); - - if (collapse) { - // Special treatment of textnode collapse - if (!to_start && node.nodeType == 3) { - rng.setStart(node, node.nodeValue.length); - rng.setEnd(node, node.nodeValue.length); - } else - rng.collapse(to_start); - } - - sel.removeAllRanges(); - sel.addRange(rng); - } - - this.scrollToNode(node); - - // Set selected element - tinyMCE.selectedElement = null; - if (node.nodeType == 1) - tinyMCE.selectedElement = node; - }, - - scrollToNode : function(node) { - var inst = this.instance, w = inst.getWin(), vp = inst.getViewPort(), pos = tinyMCE.getAbsPosition(node), cvp, p, cwin; - - // Only scroll if out of visible area - if (pos.absLeft < vp.left || pos.absLeft > vp.left + vp.width || pos.absTop < vp.top || pos.absTop > vp.top + (vp.height-25)) - w.scrollTo(pos.absLeft, pos.absTop - vp.height + 25); - - // Scroll container window - if (inst.settings.auto_resize) { - cwin = inst.getContainerWin(); - cvp = tinyMCE.getViewPort(cwin); - p = this.getAbsPosition(node); - - if (p.absLeft < cvp.left || p.absLeft > cvp.left + cvp.width || p.absTop < cvp.top || p.absTop > cvp.top + cvp.height) - cwin.scrollTo(p.absLeft, p.absTop - cvp.height + 25); - } - }, - - getAbsPosition : function(n) { - var pos = tinyMCE.getAbsPosition(n), ipos = tinyMCE.getAbsPosition(this.instance.iframeElement); - - return { - absLeft : ipos.absLeft + pos.absLeft, - absTop : ipos.absTop + pos.absTop - }; - }, - - getSel : function() { - var inst = this.instance; - - if (tinyMCE.isRealIE) - return inst.getDoc().selection; - - return inst.contentWindow.getSelection(); - }, - - getRng : function() { - var s = this.getSel(); - - if (s == null) - return null; - - if (tinyMCE.isRealIE) - return s.createRange(); - - if (tinyMCE.isSafari && !s.getRangeAt) - return '' + window.getSelection(); - - if (s.rangeCount > 0) - return s.getRangeAt(0); - - return null; - }, - - isCollapsed : function() { - var r = this.getRng(); - - if (r.item) - return false; - - return r.boundingWidth == 0 || this.getSel().isCollapsed; - }, - - collapse : function(b) { - var r = this.getRng(), s = this.getSel(); - - if (r.select) { - r.collapse(b); - r.select(); - } else { - if (b) - s.collapseToStart(); - else - s.collapseToEnd(); - } - }, - - getFocusElement : function() { - var inst = this.instance, doc, rng, sel, elm; - - if (tinyMCE.isRealIE) { - doc = inst.getDoc(); - rng = doc.selection.createRange(); - - // if (rng.collapse) - // rng.collapse(true); - - elm = rng.item ? rng.item(0) : rng.parentElement(); - } else { - if (!tinyMCE.isSafari && inst.isHidden()) - return inst.getBody(); - - sel = this.getSel(); - rng = this.getRng(); - - if (!sel || !rng) - return null; - - elm = rng.commonAncestorContainer; - //elm = (sel && sel.anchorNode) ? sel.anchorNode : null; - - // Handle selection a image or other control like element such as anchors - if (!rng.collapsed) { - // Is selection small - if (rng.startContainer == rng.endContainer) { - if (rng.startOffset - rng.endOffset < 2) { - if (rng.startContainer.hasChildNodes()) - elm = rng.startContainer.childNodes[rng.startOffset]; - } - } - } - - // Get the element parent of the node - elm = tinyMCE.getParentElement(elm); - - //if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") - // elm = tinyMCE.selectedElement; - } - - return elm; - } - - }; - -/* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */ - -function TinyMCE_UndoRedo(inst) { - this.instance = inst; - this.undoLevels = []; - this.undoIndex = 0; - this.typingUndoIndex = -1; - this.undoRedo = true; -}; - -TinyMCE_UndoRedo.prototype = { - add : function(l) { - var b, customUndoLevels, newHTML, inst = this.instance, i, ul, ur; - - if (l) { - this.undoLevels[this.undoLevels.length] = l; - return true; - } - - if (this.typingUndoIndex != -1) { - this.undoIndex = this.typingUndoIndex; - - if (tinyMCE.typingUndoIndex != -1) - tinyMCE.undoIndex = tinyMCE.typingUndoIndex; - } - - newHTML = tinyMCE.trim(inst.getBody().innerHTML); - if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) { - //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content); - - // Is dirty again - inst.isNotDirty = false; - - tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst); - - // Time to compress - customUndoLevels = tinyMCE.settings.custom_undo_redo_levels; - if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) { - for (i=0; i 0) { - this.undoIndex--; - - tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); - inst.repaint(); - - if (inst.settings.custom_undo_redo_restore_selection) - inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); - } - }, - - redo : function() { - var inst = this.instance; - - tinyMCE.execCommand("mceEndTyping"); - - if (this.undoIndex < (this.undoLevels.length-1)) { - this.undoIndex++; - - tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); - inst.repaint(); - - if (inst.settings.custom_undo_redo_restore_selection) - inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); - } - - tinyMCE.triggerNodeChange(); - } - - }; - -/* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */ - -var TinyMCE_ForceParagraphs = { - _insertPara : function(inst, e) { - var doc = inst.getDoc(), sel = inst.getSel(), body = inst.getBody(), win = inst.contentWindow, rng = sel.getRangeAt(0); - var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock; - var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null; - var paraBefore, paraAfter, startChop, endChop, contents, i; - - function isEmpty(para) { - var nodes; - - function isEmptyHTML(html) { - return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == ''; - } - - // Check for images - if (para.getElementsByTagName("img").length > 0) - return false; - - // Check for tables - if (para.getElementsByTagName("table").length > 0) - return false; - - // Check for HRs - if (para.getElementsByTagName("hr").length > 0) - return false; - - // Check all textnodes - nodes = tinyMCE.getNodeTree(para, [], 3); - for (i=0; i <" + blockName + "> "; - paraAfter = body.childNodes[1]; - } - - inst.selection.moveToBookmark(b); - inst.selection.selectNode(paraAfter, true, true); - - return true; - } - - // Place first part within new paragraph - if (startChop.nodeName == blockName) - rngBefore.setStart(startChop, 0); - else - rngBefore.setStartBefore(startChop); - - rngBefore.setEnd(startNode, startOffset); - paraBefore.appendChild(rngBefore.cloneContents()); - - // Place secound part within new paragraph - rngAfter.setEndAfter(endChop); - rngAfter.setStart(endNode, endOffset); - contents = rngAfter.cloneContents(); - - if (contents.firstChild && contents.firstChild.nodeName == blockName) { - /* var nodes = contents.firstChild.childNodes; - for (i=0; i= r.startOffset && nv.charAt(r.startOffset - 1) == ' ') - s = true;*/ - - // Only remove BRs if we are at the end of line #bug 1464152 - if (nv != null && r.startOffset == nv.length) - sn.nextSibling.parentNode.removeChild(sn.nextSibling); - } - - if (inst.settings.auto_resize) - inst.resizeToContent(); - - return s; - } - - }; - -/* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */ - -function TinyMCE_Layer(id, bm) { - this.id = id; - this.blockerElement = null; - this.events = false; - this.element = null; - this.blockMode = typeof(bm) != 'undefined' ? bm : true; - this.doc = document; -}; - -TinyMCE_Layer.prototype = { - moveRelativeTo : function(re, p) { - var rep = this.getAbsPosition(re), e = this.getElement(), x, y; - var w = parseInt(re.offsetWidth), h = parseInt(re.offsetHeight); - var ew = parseInt(e.offsetWidth), eh = parseInt(e.offsetHeight); - - switch (p) { - case "tl": - x = rep.absLeft; - y = rep.absTop; - break; - - case "tr": - x = rep.absLeft + w; - y = rep.absTop; - break; - - case "bl": - x = rep.absLeft; - y = rep.absTop + h; - break; - - case "br": - x = rep.absLeft + w; - y = rep.absTop + h; - break; - - case "cc": - x = rep.absLeft + (w / 2) - (ew / 2); - y = rep.absTop + (h / 2) - (eh / 2); - break; - } - - this.moveTo(x, y); - }, - - moveBy : function(x, y) { - var e = this.getElement(); - this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y); - }, - - moveTo : function(x, y) { - var e = this.getElement(); - - e.style.left = x + "px"; - e.style.top = y + "px"; - - this.updateBlocker(); - }, - - resizeBy : function(w, h) { - var e = this.getElement(); - this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h); - }, - - resizeTo : function(w, h) { - var e = this.getElement(); - - if (w != null) - e.style.width = w + "px"; - - if (h != null) - e.style.height = h + "px"; - - this.updateBlocker(); - }, - - show : function() { - var el = this.getElement(); - - if (el) { - el.style.display = 'block'; - this.updateBlocker(); - } - }, - - hide : function() { - var el = this.getElement(); - - if (el) { - el.style.display = 'none'; - this.updateBlocker(); - } - }, - - isVisible : function() { - return this.getElement().style.display == 'block'; - }, - - getElement : function() { - if (!this.element) - this.element = this.doc.getElementById(this.id); - - return this.element; - }, - - setBlockMode : function(s) { - this.blockMode = s; - }, - - updateBlocker : function() { - var e, b, x, y, w, h; - - b = this.getBlocker(); - if (b) { - if (this.blockMode) { - e = this.getElement(); - x = this.parseInt(e.style.left); - y = this.parseInt(e.style.top); - w = this.parseInt(e.offsetWidth); - h = this.parseInt(e.offsetHeight); - - b.style.left = x + 'px'; - b.style.top = y + 'px'; - b.style.width = w + 'px'; - b.style.height = h + 'px'; - b.style.display = e.style.display; - } else - b.style.display = 'none'; - } - }, - - getBlocker : function() { - var d, b; - - if (!this.blockerElement && this.blockMode) { - d = this.doc; - b = d.getElementById(this.id + "_blocker"); - - if (!b) { - b = d.createElement("iframe"); - - b.setAttribute('id', this.id + "_blocker"); - b.style.cssText = 'display: none; position: absolute; left: 0; top: 0'; - b.src = 'javascript:false;'; - b.frameBorder = '0'; - b.scrolling = 'no'; - - d.body.appendChild(b); - } - - this.blockerElement = b; - } - - return this.blockerElement; - }, - - getAbsPosition : function(n) { - var p = {absLeft : 0, absTop : 0}; - - while (n) { - p.absLeft += n.offsetLeft; - p.absTop += n.offsetTop; - n = n.offsetParent; - } - - return p; - }, - - create : function(n, c, p, h) { - var d = this.doc, e = d.createElement(n); - - e.setAttribute('id', this.id); - - if (c) - e.className = c; - - if (!p) - p = d.body; - - if (h) - e.innerHTML = h; - - p.appendChild(e); - - return this.element = e; - }, - - exists : function() { - return this.doc.getElementById(this.id) != null; - }, - - parseInt : function(s) { - if (s == null || s == '') - return 0; - - return parseInt(s); - }, - - remove : function() { - var e = this.getElement(), b = this.getBlocker(); - - if (e) - e.parentNode.removeChild(e); - - if (b) - b.parentNode.removeChild(b); - } - - }; - -/* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */ - -function TinyMCE_Menu() { - var id; - - if (typeof(tinyMCE.menuCounter) == "undefined") - tinyMCE.menuCounter = 0; - - id = "mc_menu_" + tinyMCE.menuCounter++; - - TinyMCE_Layer.call(this, id, true); - - this.id = id; - this.items = []; - this.needsUpdate = true; -}; - -TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, { - init : function(s) { - var n; - - // Default params - this.settings = { - separator_class : 'mceMenuSeparator', - title_class : 'mceMenuTitle', - disabled_class : 'mceMenuDisabled', - menu_class : 'mceMenu', - drop_menu : true - }; - - for (n in s) - this.settings[n] = s[n]; - - this.create('div', this.settings.menu_class); - }, - - clear : function() { - this.items = []; - }, - - addTitle : function(t) { - this.add({type : 'title', text : t}); - }, - - addDisabled : function(t) { - this.add({type : 'disabled', text : t}); - }, - - addSeparator : function() { - this.add({type : 'separator'}); - }, - - addItem : function(t, js) { - this.add({text : t, js : js}); - }, - - add : function(mi) { - this.items[this.items.length] = mi; - this.needsUpdate = true; - }, - - update : function() { - var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings; - - if (this.settings.drop_menu) - h += ''; - - h += ''; - - for (i=0; i'; - } - - h += '
'; - break; - - case 'title': - h += '
' + t + ''; - break; - - case 'disabled': - h += '
' + t + ''; - break; - - default: - h += '
' + t + ''; - } - - h += '
'; - - e.innerHTML = h; - - this.needsUpdate = false; - this.updateBlocker(); - }, - - show : function() { - var nl, i; - - if (tinyMCE.lastMenu == this) - return; - - if (this.needsUpdate) - this.update(); - - if (tinyMCE.lastMenu && tinyMCE.lastMenu != this) - tinyMCE.lastMenu.hide(); - - TinyMCE_Layer.prototype.show.call(this); - - if (!tinyMCE.isOpera) { - // Accessibility stuff -/* nl = this.getElement().getElementsByTagName("a"); - if (nl.length > 0) - nl[0].focus();*/ - } - - tinyMCE.lastMenu = this; - } - - }); - -/* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */ - -tinyMCE.add(TinyMCE_Engine, { - debug : function() { - var m = "", a, i, l = tinyMCE.log.length; - - for (i=0, a = this.debug.arguments; i'); + this._def("font_size_classes", ''); + this._def("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large', true); + this._def("event_elements", 'a,img', true); + this._def("convert_urls", true); + this._def("table_inline_editing", false); + this._def("object_resizing", true); + this._def("custom_shortcuts", true); + this._def("convert_on_click", false); + this._def("content_css", ''); + this._def("fix_list_elements", true); + this._def("fix_table_elements", false); + this._def("strict_loading_mode", document.contentType == 'application/xhtml+xml'); + this._def("hidden_tab_class", ''); + this._def("display_tab_class", ''); + this._def("gecko_spellcheck", false); + this._def("hide_selects_on_submit", true); + this._def("forced_root_block", false); + this._def("remove_trailing_nbsp", false); + this._def("save_on_tinymce_forms", false); + + // Force strict loading mode to false on non Gecko browsers + if (this.isMSIE && !this.isOpera) + this.settings.strict_loading_mode = false; + + // Browser check IE + if (this.isMSIE && this.settings.browsers.indexOf('msie') == -1) + return; + + // Browser check Gecko + if (this.isGecko && this.settings.browsers.indexOf('gecko') == -1) + return; + + // Browser check Safari + if (this.isSafari && this.settings.browsers.indexOf('safari') == -1) + return; + + // Browser check Opera + if (this.isOpera && this.settings.browsers.indexOf('opera') == -1) + return; + + // If not super absolute make it so + baseHREF = tinyMCE.settings.document_base_url; + h = document.location.href; + p = h.indexOf('://'); + if (p > 0 && document.location.protocol != "file:") { + p = h.indexOf('/', p + 3); + h = h.substring(0, p); + + if (baseHREF.indexOf('://') == -1) + baseHREF = h + baseHREF; + + tinyMCE.settings.document_base_url = baseHREF; + tinyMCE.settings.document_base_prefix = h; + } + + // Trim away query part + if (baseHREF.indexOf('?') != -1) + baseHREF = baseHREF.substring(0, baseHREF.indexOf('?')); + + this.settings.base_href = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/"; + + theme = this.settings.theme; + this.inlineStrict = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment'; + this.inlineTransitional = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment'; + this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP'; + this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i"); + this.posKeyCodes = [13,45,36,35,33,34,37,38,39,40]; + this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL + this.uniqueTag = ''; + this.callbacks = ['onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance']; + + // Theme url + this.settings.theme_href = tinyMCE.baseURL + "/themes/" + theme; + + if (!tinyMCE.isIE || tinyMCE.isOpera) + this.settings.force_br_newlines = false; + + if (tinyMCE.getParam("popups_css", false)) { + cssPath = tinyMCE.getParam("popups_css", ""); + + // Is relative + if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/') + this.settings.popups_css = this.documentBasePath + "/" + cssPath; + else + this.settings.popups_css = cssPath; + } else + this.settings.popups_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css"; + + if (tinyMCE.getParam("editor_css", false)) { + cssPath = tinyMCE.getParam("editor_css", ""); + + // Is relative + if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/') + this.settings.editor_css = this.documentBasePath + "/" + cssPath; + else + this.settings.editor_css = cssPath; + } else { + if (this.settings.editor_css !== '') + this.settings.editor_css = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css"; + } + + // Only do this once + if (this.configs.length == 0) { + if (typeof(TinyMCECompressed) == "undefined") { + tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad); + + if (tinyMCE.isRealIE) { + if (document.body) + tinyMCE.addEvent(document.body, "readystatechange", TinyMCE_Engine.prototype.onLoad); + else + tinyMCE.addEvent(document, "readystatechange", TinyMCE_Engine.prototype.onLoad); + } + + tinyMCE.addEvent(window, "load", TinyMCE_Engine.prototype.onLoad); + tinyMCE._addUnloadEvents(); + } + } + + this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings.theme + '/editor_template' + tinyMCE.srcMode + '.js'); + this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings.language + '.js'); + this.loadCSS(this.settings.editor_css); + + // Add plugins + p = tinyMCE.getParam('plugins', '', true, ','); + if (p.length > 0) { + for (i=0; i&"]', 'g'); + }, + + _addUnloadEvents : function() { + var st = tinyMCE.settings.add_unload_trigger; + + if (tinyMCE.isIE) { + if (st) { + tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler); + tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler); + } + } else { + if (st) + tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);}); + } + }, + + _def : function(key, def_val, t) { + var v = tinyMCE.getParam(key, def_val); + + v = t ? v.replace(/\s+/g, "") : v; + + this.settings[key] = v; + }, + + hasPlugin : function(n) { + return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; + }, + + addPlugin : function(n, p) { + var op = this.plugins[n]; + + // Use the previous plugin object base URL used when loading external plugins + p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n; + this.plugins[n] = p; + + this.loadNextScript(); + }, + + setPluginBaseURL : function(n, u) { + var op = this.plugins[n]; + + if (op) + op.baseURL = u; + else + this.plugins[n] = {baseURL : u}; + }, + + loadPlugin : function(n, u) { + u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u; + u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u; + this.plugins[n] = {baseURL : u}; + this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js"); + }, + + hasTheme : function(n) { + return typeof(this.themes[n]) != "undefined" && this.themes[n] != null; + }, + + addTheme : function(n, t) { + this.themes[n] = t; + + this.loadNextScript(); + }, + + addMenu : function(n, m) { + this.menus[n] = m; + }, + + hasMenu : function(n) { + return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null; + }, + + loadScript : function(url) { + var i; + + for (i=0; i'); + + this.loadedFiles[this.loadedFiles.length] = url; + }, + + loadNextScript : function() { + var d = document, se; + + if (!tinyMCE.settings.strict_loading_mode) + return; + + if (this.loadingIndex < this.pendingFiles.length) { + se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script'); + se.setAttribute('language', 'javascript'); + se.setAttribute('type', 'text/javascript'); + se.setAttribute('src', this.pendingFiles[this.loadingIndex++]); + + d.getElementsByTagName("head")[0].appendChild(se); + } else + this.loadingIndex = -1; // Done with loading + }, + + loadCSS : function(url) { + var ar = url.replace(/\s+/, '').split(','); + var lflen = 0, csslen = 0, skip = false; + var x = 0, i = 0, nl, le; + + for (x = 0,csslen = ar.length; x 0) { + /* Make sure it doesn't exist. */ + for (i=0, lflen=this.loadedFiles.length; i'); + + this.loadedFiles[this.loadedFiles.length] = ar[x]; + } + } + } + }, + + importCSS : function(doc, css) { + var css_ary = css.replace(/\s+/, '').split(','); + var csslen, elm, headArr, x, css_file; + + for (x = 0, csslen = css_ary.length; x 0) { + // Is relative, make absolute + if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/') + css_file = this.documentBasePath + "/" + css_file; + + if (typeof(doc.createStyleSheet) == "undefined") { + elm = doc.createElement("link"); + + elm.rel = "stylesheet"; + elm.href = css_file; + + if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0) + headArr[0].appendChild(elm); + } else + doc.createStyleSheet(css_file); + } + } + }, + + confirmAdd : function(e, settings) { + var elm = tinyMCE.isIE ? event.srcElement : e.target; + var elementId = elm.name ? elm.name : elm.id; + + tinyMCE.settings = settings; + + if (tinyMCE.settings.convert_on_click || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang.lang_edit_confirm))) + tinyMCE.addMCEControl(elm, elementId); + + elm.setAttribute('mce_noask', 'true'); + }, + + updateContent : function(form_element_name) { + var formElement, n, inst, doc; + + // Find MCE instance linked to given form element and copy it's value + formElement = document.getElementById(form_element_name); + for (n in tinyMCE.instances) { + inst = tinyMCE.instances[n]; + + if (!tinyMCE.isInstance(inst)) + continue; + + inst.switchSettings(); + + if (inst.formElement == formElement) { + doc = inst.getDoc(); + + tinyMCE._setHTML(doc, inst.formElement.value); + + if (!tinyMCE.isIE) + doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid); + } + } + }, + + addMCEControl : function(replace_element, form_element_name, target_document) { + var id = "mce_editor_" + tinyMCE.idCounter++; + var inst = new TinyMCE_Control(tinyMCE.settings); + + inst.editorId = id; + this.instances[id] = inst; + + inst._onAdd(replace_element, form_element_name, target_document); + }, + + removeInstance : function(ti) { + var t = [], n, i; + + // Remove from instances + for (n in tinyMCE.instances) { + i = tinyMCE.instances[n]; + + if (tinyMCE.isInstance(i) && ti != i) + t[n] = i; + } + + tinyMCE.instances = t; + + // Remove from global undo/redo + n = []; + t = tinyMCE.undoLevels; + + for (i=0; i 0) { + tinyMCE.nextUndoRedoAction = 'Undo'; + inst = this.undoLevels[--this.undoIndex]; + inst.select(); + + if (!tinyMCE.nextUndoRedoInstanceId) + inst.execCommand('Undo'); + } + } else + inst.execCommand('Undo'); + return true; + + case "Redo": + if (this.getParam('custom_undo_redo_global')) { + if (this.undoIndex <= this.undoLevels.length - 1) { + tinyMCE.nextUndoRedoAction = 'Redo'; + inst = this.undoLevels[this.undoIndex++]; + inst.select(); + + if (!tinyMCE.nextUndoRedoInstanceId) + inst.execCommand('Redo'); + } + } else + inst.execCommand('Redo'); + + return true; + + case 'mceFocus': + inst = tinyMCE.getInstanceById(value); + + if (inst) + inst.getWin().focus(); + return; + + case "mceAddControl": + case "mceAddEditor": + tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); + return; + + case "mceAddFrameControl": + tinyMCE.addMCEControl(tinyMCE._getElementById(value.element, value.document), value.element, value.document); + return; + + case "mceRemoveControl": + case "mceRemoveEditor": + tinyMCE.removeMCEControl(value); + return; + + case "mceToggleEditor": + inst = tinyMCE.getInstanceById(value); + + if (inst) { + pe = document.getElementById(inst.editorId + '_parent'); + te = inst.oldTargetElement; + + if (typeof(inst.enabled) == 'undefined') + inst.enabled = true; + + inst.enabled = !inst.enabled; + + if (!inst.enabled) { + pe.style.display = 'none'; + + if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT') + te.value = inst.getHTML(); + else + te.innerHTML = inst.getHTML(); + + te.style.display = inst.oldTargetDisplay; + tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst); + } else { + pe.style.display = 'block'; + te.style.display = 'none'; + + if (te.nodeName == 'TEXTAREA' || te.nodeName == 'INPUT') + inst.setHTML(te.value); + else + inst.setHTML(te.innerHTML); + + inst.useCSS = false; + tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst); + } + } else + tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); + + return; + + case "mceResetDesignMode": + // Resets the designmode state of the editors in Gecko + if (tinyMCE.isGecko) { + for (n in tinyMCE.instances) { + if (!tinyMCE.isInstance(tinyMCE.instances[n])) + continue; + + try { + tinyMCE.instances[n].getDoc().designMode = "off"; + tinyMCE.instances[n].getDoc().designMode = "on"; + tinyMCE.instances[n].useCSS = false; + } catch (e) { + // Ignore any errors + } + } + } + + return; + } + + if (inst) { + inst.execCommand(command, user_interface, value); + } else if (tinyMCE.settings.focus_alert) + alert(tinyMCELang.lang_focus_alert); + }, + + _createIFrame : function(replace_element, doc, win) { + var iframe, id = replace_element.getAttribute("id"); + var aw, ah; + + if (typeof(doc) == "undefined") + doc = document; + + if (typeof(win) == "undefined") + win = window; + + iframe = doc.createElement("iframe"); + + aw = "" + tinyMCE.settings.area_width; + ah = "" + tinyMCE.settings.area_height; + + if (aw.indexOf('%') == -1) { + aw = parseInt(aw); + aw = (isNaN(aw) || aw < 0) ? 300 : aw; + aw = aw + "px"; + } + + if (ah.indexOf('%') == -1) { + ah = parseInt(ah); + ah = (isNaN(ah) || ah < 0) ? 240 : ah; + ah = ah + "px"; + } + + iframe.setAttribute("id", id); + iframe.setAttribute("name", id); + iframe.setAttribute("class", "mceEditorIframe"); + iframe.setAttribute("border", "0"); + iframe.setAttribute("frameBorder", "0"); + iframe.setAttribute("marginWidth", "0"); + iframe.setAttribute("marginHeight", "0"); + iframe.setAttribute("leftMargin", "0"); + iframe.setAttribute("topMargin", "0"); + iframe.setAttribute("width", aw); + iframe.setAttribute("height", ah); + iframe.setAttribute("allowtransparency", "true"); + iframe.className = 'mceEditorIframe'; + + if (tinyMCE.settings.auto_resize) + iframe.setAttribute("scrolling", "no"); + + // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs + if (tinyMCE.isRealIE) + iframe.setAttribute("src", this.settings.default_document); + + iframe.style.width = aw; + iframe.style.height = ah; + + // Ugly hack for Gecko problem in strict mode + if (tinyMCE.settings.strict_loading_mode) + iframe.style.marginBottom = '-5px'; + + // MSIE 5.0 issue + if (tinyMCE.isRealIE) + replace_element.outerHTML = iframe.outerHTML; + else + replace_element.parentNode.replaceChild(iframe, replace_element); + + if (tinyMCE.isRealIE) + return win.frames[id]; + else + return iframe; + }, + + setupContent : function(editor_id) { + var inst = tinyMCE.instances[editor_id], i, doc = inst.getDoc(), head = doc.getElementsByTagName('head').item(0); + var content = inst.startContent, contentElement, body; + + // HTML values get XML encoded in strict mode + if (tinyMCE.settings.strict_loading_mode) { + content = content.replace(/</g, '<'); + content = content.replace(/>/g, '>'); + content = content.replace(/"/g, '"'); + content = content.replace(/&/g, '&'); + } + + tinyMCE.selectedInstance = inst; + inst.switchSettings(); + + // Not loaded correctly hit it again, Mozilla bug #997860 + if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") { + // This part will remove the designMode status + // Failes first time in Firefox 1.5b2 on Mac + try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {} + window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000); + return; + } + + // Wait for it to load + if (!head || !doc.body) { + window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10); + return; + } + + // Import theme specific content CSS the user specific + tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings.theme + "/css/editor_content.css"); + tinyMCE.importCSS(inst.getDoc(), inst.settings.content_css); + tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst); + + // Setup keyboard shortcuts + if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) { + inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo'); + inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo'); + } + + // BlockFormat shortcuts keys + for (i=1; i<=6; i++) + inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, ''); + + inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '

'); + inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '

'); + inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '
'); + + // Add default shortcuts for gecko + if (tinyMCE.isGecko) { + inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold'); + inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic'); + inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline'); + } + + // Setup span styles + if (tinyMCE.getParam("convert_fonts_to_spans")) + inst.getBody().setAttribute('id', 'mceSpanFonts'); + + if (tinyMCE.settings.nowrap) + doc.body.style.whiteSpace = "nowrap"; + + doc.body.dir = this.settings.directionality; + doc.editorId = editor_id; + + // Add on document element in Mozilla + if (!tinyMCE.isIE) + doc.documentElement.editorId = editor_id; + + inst.setBaseHREF(tinyMCE.settings.base_href); + + // Replace new line characters to BRs + if (tinyMCE.settings.convert_newlines_to_brs) { + content = tinyMCE.regexpReplace(content, "\r\n", "
", "gi"); + content = tinyMCE.regexpReplace(content, "\r", "
", "gi"); + content = tinyMCE.regexpReplace(content, "\n", "
", "gi"); + } + + // Open closed anchors + // content = content.replace(new RegExp('', 'gi'), ''); + + // Call custom cleanup code + content = tinyMCE.storeAwayURLs(content); + content = tinyMCE._customCleanup(inst, "insert_to_editor", content); + + if (tinyMCE.isIE) { + // Ugly!!! + window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500); + + if (tinyMCE.settings.force_br_newlines) + doc.styleSheets[0].addRule("p", "margin: 0;"); + + body = inst.getBody(); + body.editorId = editor_id; + } + + content = tinyMCE.cleanupHTMLCode(content); + + // Fix for bug #958637 + if (!tinyMCE.isIE) { + contentElement = inst.getDoc().createElement("body"); + doc = inst.getDoc(); + + contentElement.innerHTML = content; + + if (tinyMCE.settings.cleanup_on_startup) + tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement)); + else + tinyMCE.setInnerHTML(inst.getBody(), content); + + tinyMCE.convertAllRelativeURLs(inst.getBody()); + } else { + if (tinyMCE.settings.cleanup_on_startup) { + tinyMCE._setHTML(inst.getDoc(), content); + + // Produces permission denied error in MSIE 5.5 + try { + tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody())); + } catch(e) { + // Ignore + } + } else + tinyMCE._setHTML(inst.getDoc(), content); + } + + // Fix for bug #957681 + //inst.getDoc().designMode = inst.getDoc().designMode; + + tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings.visual, inst); + tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); + + // Re-add design mode on mozilla + if (!tinyMCE.isIE) + tinyMCE.addEventHandlers(inst); + + // Add blur handler + if (tinyMCE.isIE) { + tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch); + tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953 + + // Workaround for drag drop/copy paste base href bug + if (!tinyMCE.isOpera) { + tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove); + tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch); + tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch); + } + } + + // Trigger node change, this call locks buttons for tables and so forth + inst.select(); + tinyMCE.selectedElement = inst.contentWindow.document.body; + + // Call custom DOM cleanup + tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody()); + tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody()); + tinyMCE._setEventsEnabled(inst.getBody(), false); + tinyMCE.cleanupAnchors(inst.getDoc()); + + if (tinyMCE.getParam("convert_fonts_to_spans")) + tinyMCE.convertSpansToFonts(inst.getDoc()); + + inst.startContent = tinyMCE.trim(inst.getBody().innerHTML); + inst.undoRedo.add({ content : inst.startContent }); + + // Cleanup any mess left from storyAwayURLs + if (tinyMCE.isGecko) { + // Remove mce_src from textnodes and comments + tinyMCE.selectNodes(inst.getBody(), function(n) { + if (n.nodeType == 3 || n.nodeType == 8) + n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); + + return false; + }); + } + + // Remove Gecko spellchecking + if (tinyMCE.isGecko) + inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck"); + + // Cleanup any mess left from storyAwayURLs + tinyMCE._removeInternal(inst.getBody()); + + inst.select(); + tinyMCE.triggerNodeChange(false, true); + }, + + storeAwayURLs : function(s) { + // Remove all mce_src, mce_href and replace them with new ones + // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); + // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); + + if (!s.match(/(mce_src|mce_href)/gi, s)) { + s = s.replace(new RegExp('src\\s*=\\s*[\"\']([^ >\"]*)[\"\']', 'gi'), 'src="$1" mce_src="$1"'); + s = s.replace(new RegExp('href\\s*=\\s*[\"\']([^ >\"]*)[\"\']', 'gi'), 'href="$1" mce_href="$1"'); + } + + return s; + }, + + _removeInternal : function(n) { + if (tinyMCE.isGecko) { + // Remove mce_src from textnodes and comments + tinyMCE.selectNodes(n, function(n) { + if (n.nodeType == 3 || n.nodeType == 8) + n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); + + return false; + }); + } + }, + + removeTinyMCEFormElements : function(form_obj) { + var i, elementId; + + // Skip form element removal + if (!tinyMCE.getParam('hide_selects_on_submit')) + return; + + // Check if form is valid + if (typeof(form_obj) == "undefined" || form_obj == null) + return; + + // If not a form, find the form + if (form_obj.nodeName != "FORM") { + if (form_obj.form) + form_obj = form_obj.form; + else + form_obj = tinyMCE.getParentElement(form_obj, "form"); + } + + // Still nothing + if (form_obj == null) + return; + + // Disable all UI form elements that TinyMCE created + for (i=0; i"); + rng.collapse(false); + rng.select(); + + tinyMCE.execCommand("mceAddUndoLevel"); + tinyMCE.triggerNodeChange(false); + return false; + } + } + + // Backspace or delete + if (e.keyCode == 8 || e.keyCode == 46) { + tinyMCE.selectedElement = e.target; + tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a"); + tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img"); + tinyMCE.triggerNodeChange(false); + } + + return false; + + case "keyup": + case "keydown": + tinyMCE.hideMenus(); + tinyMCE.hasMouseMoved = false; + + if (inst && inst.handleShortcut(e)) + return false; + + inst._fixRootBlocks(); + + if (inst.settings.remove_trailing_nbsp) + inst._fixTrailingNbsp(); + + if (e.target.editorId) + tinyMCE.instances[e.target.editorId].select(); + + if (tinyMCE.selectedInstance) + tinyMCE.selectedInstance.switchSettings(); + + inst = tinyMCE.selectedInstance; + + // Handle backspace + if (tinyMCE.isGecko && tinyMCE.settings.force_p_newlines && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { + // Insert P element instead of BR + if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { + // Cancel event + tinyMCE.execCommand("mceAddUndoLevel"); + e.preventDefault(); + return false; + } + } + + tinyMCE.selectedElement = null; + tinyMCE.selectedNode = null; + elm = tinyMCE.selectedInstance.getFocusElement(); + tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a"); + tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img"); + tinyMCE.selectedElement = elm; + + // Update visualaids on tabs + if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9) + tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings.visual, tinyMCE.selectedInstance); + + // Fix empty elements on return/enter, check where enter occured + if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13) + tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement(); + + // Fix empty elements on return/enter + if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) { + elm = tinyMCE.enterKeyElement; + if (elm) { + var re = new RegExp('^HR|IMG|BR$','g'); // Skip these + var dre = new RegExp('^H[1-6]$','g'); // Add double on these + + if (!elm.hasChildNodes() && !re.test(elm.nodeName)) { + if (dre.test(elm.nodeName)) + elm.innerHTML = "  "; + else + elm.innerHTML = " "; + } + } + } + + // Check if it's a position key + keys = tinyMCE.posKeyCodes; + var posKey = false; + for (i=0; i'; + h += '{$'+lang+'}'; + h += ''; + } else { + // Normal button + h += ''; + h += '{$'+lang+'}'; + h += ''; + } + + return h; + }, + + getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) { + var h = '', m, x; + + mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');'; + cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; + + if (typeof(ui) != "undefined" && ui != null) + cmd += ',' + ui; + + if (typeof(val) != "undefined" && val != null) + cmd += ",'" + val + "'"; + + cmd += ');'; + + // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled + if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { + x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); + + if (tinyMCE.isRealIE) + h += ''; + else + h += ''; + + h += ''; + h += ''; + h += ''; + h += ''; + } else { + if (tinyMCE.isRealIE) + h += ''; + else + h += ''; + + h += ''; + h += ''; + h += ''; + h += ''; + } + + return h; + }, + + _menuButtonEvent : function(e, o) { + if (o.className == 'mceMenuButtonFocus') + return; + + if (e == 'over') + o.className = o.className + ' mceMenuHover'; + else + o.className = o.className.replace(/\s.*$/, ''); + }, + + addButtonMap : function(m) { + var i, a = m.replace(/\s+/, '').split(','); + + for (i=0; i 0) + className += " "; + + className += classNames[i]; + } + + return className; + }, + + handleVisualAid : function(el, deep, state, inst, skip_dispatch) { + var i, x, y, tableElement, anchorName, oldW, oldH, bo, cn; + + if (!el) + return; + + if (!skip_dispatch) + tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst); + + tableElement = null; + + switch (el.nodeName) { + case "TABLE": + oldW = el.style.width; + oldH = el.style.height; + bo = tinyMCE.getAttrib(el, "border"); + + bo = bo == '' || bo == "0" ? true : false; + + tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo)); + + el.style.width = oldW; + el.style.height = oldH; + + for (y=0; y 0) + return inst.cssClasses; + + if (!doc) + return; + + styles = doc.styleSheets; + + if (styles && styles.length > 0) { + for (x=0; x' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + ''; + + return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); + } + } + + o = tinyMCE.themes[tinyMCE.settings.theme]; + if (o.getControlHTML && (v = o.getControlHTML(c)) !== '') { + if (rtl) + return '' + v + ''; + + return v; + } + + return ''; + }, + + evalFunc : function(f, idx, a, o) { + o = !o ? window : o; + f = typeof(f) == 'function' ? f : o[f]; + + return f.apply(o, Array.prototype.slice.call(a, idx)); + }, + + dispatchCallback : function(i, p, n) { + return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments); + }, + + executeCallback : function(i, p, n) { + return this.callFunc(i, p, n, 1, this.executeCallback.arguments); + }, + + execCommandCallback : function(i, p, n) { + return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments); + }, + + callFunc : function(ins, p, n, m, a) { + var l, i, on, o, s, v; + + s = m == 2; + + l = tinyMCE.getParam(p, ''); + + if (l !== '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0) + return true; + + if (ins != null) { + for (i=0, l = ins.plugins; i 0) + return true; + } + } + + l = tinyMCE.themes; + for (on in l) { + o = l[on]; + + if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) + return true; + } + + return false; + }, + + resolveDots : function(s, o) { + var i; + + if (typeof(s) == 'string') { + for (i=0, s=s.split('.'); i': + return '>'; + } + + return c; + }) : s; + }, + + add : function(c, m) { + var n; + + for (n in m) { + if (m.hasOwnProperty(n)) + c.prototype[n] = m[n]; + } + }, + + extend : function(p, np) { + var o = {}, n; + + o.parent = p; + + for (n in p) { + if (p.hasOwnProperty(n)) + o[n] = p[n]; + } + + for (n in np) { + if (np.hasOwnProperty(n)) + o[n] = np[n]; + } + + return o; + }, + + hideMenus : function() { + var e = tinyMCE.lastSelectedMenuBtn; + + if (tinyMCE.lastMenu) { + tinyMCE.lastMenu.hide(); + tinyMCE.lastMenu = null; + } + + if (e) { + tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass); + tinyMCE.lastSelectedMenuBtn = null; + } + } + + }; + +// Global instances +var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors +var tinyMCE = new TinyMCE_Engine(); +var tinyMCELang = {}; + +/* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */ + +function TinyMCE_Control(settings) { + var t, i, tos, fu, p, x, fn, fu, pn, s = settings; + + this.undoRedoLevel = true; + this.isTinyMCE_Control = true; + + // Default settings + this.enabled = true; + this.settings = s; + this.settings.theme = tinyMCE.getParam("theme", "default"); + this.settings.width = tinyMCE.getParam("width", -1); + this.settings.height = tinyMCE.getParam("height", -1); + this.selection = new TinyMCE_Selection(this); + this.undoRedo = new TinyMCE_UndoRedo(this); + this.cleanup = new TinyMCE_Cleanup(); + this.shortcuts = []; + this.hasMouseMoved = false; + this.foreColor = this.backColor = "#999999"; + this.data = {}; + this.cssClasses = []; + + this.cleanup.init({ + valid_elements : s.valid_elements, + extended_valid_elements : s.extended_valid_elements, + valid_child_elements : s.valid_child_elements, + entities : s.entities, + entity_encoding : s.entity_encoding, + debug : s.cleanup_debug, + indent : s.apply_source_formatting, + invalid_elements : s.invalid_elements, + verify_html : s.verify_html, + fix_content_duplication : s.fix_content_duplication, + convert_fonts_to_spans : s.convert_fonts_to_spans + }); + + // Wrap old theme + t = this.settings.theme; + if (!tinyMCE.hasTheme(t)) { + fn = tinyMCE.callbacks; + tos = {}; + + for (i=0; i 0) { + for (i=0; i 1 && tinyMCE.currentConfig != this.settings.index) { + tinyMCE.settings = this.settings; + tinyMCE.currentConfig = this.settings.index; + } + }, + + select : function() { + var oldInst = tinyMCE.selectedInstance; + + if (oldInst != this) { + if (oldInst) + oldInst.execCommand('mceEndTyping'); + + tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst); + tinyMCE.selectedInstance = this; + } + }, + + getBody : function() { + return this.contentBody ? this.contentBody : this.getDoc().body; + }, + + getDoc : function() { +// return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ? + return this.contentWindow.document; + }, + + getWin : function() { + return this.contentWindow; + }, + + getContainerWin : function() { + return this.containerWindow ? this.containerWindow : window; + }, + + getViewPort : function() { + return tinyMCE.getViewPort(this.getWin()); + }, + + getParentNode : function(n, f) { + return tinyMCE.getParentNode(n, f, this.getBody()); + }, + + getParentElement : function(n, na, f) { + return tinyMCE.getParentElement(n, na, f, this.getBody()); + }, + + getParentBlockElement : function(n) { + return tinyMCE.getParentBlockElement(n, this.getBody()); + }, + + resizeToContent : function() { + var d = this.getDoc(), b = d.body, de = d.documentElement; + + this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px'; + }, + + addShortcut : function(m, k, d, cmd, ui, va) { + var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts; + + if (!tinyMCE.getParam('custom_shortcuts')) + return false; + + m = m.toLowerCase(); + k = ie && !n ? k.toUpperCase() : k; + c = n ? null : k.charCodeAt(0); + d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d; + + sc = { + alt : m.indexOf('alt') != -1, + ctrl : m.indexOf('ctrl') != -1, + shift : m.indexOf('shift') != -1, + charCode : c, + keyCode : n ? k : (ie ? c : null), + desc : d, + cmd : cmd, + ui : ui, + val : va + }; + + for (i=0; i 1 && /(^\u00a0|\u00a0$)/.test(v)) { + e.firstChild.nodeValue = v.replace(/(^\u00a0|\u00a0$)/, ''); + s.selectNode(e.firstChild, true, false, false); // Select and collapse + } + } + }, + + _setUseCSS : function(b) { + var d = this.getDoc(); + + try {d.execCommand("useCSS", false, !b);} catch (ex) {} + try {d.execCommand("styleWithCSS", false, b);} catch (ex) {} + + if (!tinyMCE.getParam("table_inline_editing")) + try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {} + + if (!tinyMCE.getParam("object_resizing")) + try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {} + }, + + execCommand : function(command, user_interface, value) { + var i, x, z, align, img, div, doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement(); + + // Is not a undo specific command + if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) + this.undoBookmark = null; + + // Mozilla issue + if (!tinyMCE.isIE && !this.useCSS) { + this._setUseCSS(false); + this.useCSS = true; + } + + //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value); + this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks + + // Don't dispatch key commands + if (!/mceStartTyping|mceEndTyping/.test(command)) { + if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) + return; + } + + // Fix align on images + if (focusElm && focusElm.nodeName == "IMG") { + align = focusElm.getAttribute('align'); + img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm; + + switch (command) { + case "JustifyLeft": + if (align == 'left') { + img.setAttribute('align', ''); // Needed for IE + img.removeAttribute('align'); + } else + img.setAttribute('align', 'left'); + + // Remove the div + div = focusElm.parentNode; + if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) + div.parentNode.replaceChild(img, div); + + this.selection.selectNode(img); + this.repaint(); + tinyMCE.triggerNodeChange(); + return; + + case "JustifyCenter": + img.setAttribute('align', ''); // Needed for IE + img.removeAttribute('align'); + + // Is centered + div = tinyMCE.getParentElement(focusElm, "div"); + if (div && div.style.textAlign == "center") { + // Remove div + if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) + div.parentNode.replaceChild(img, div); + } else { + // Add div + div = this.getDoc().createElement("div"); + div.style.textAlign = 'center'; + div.appendChild(img); + focusElm.parentNode.replaceChild(div, focusElm); + } + + this.selection.selectNode(img); + this.repaint(); + tinyMCE.triggerNodeChange(); + return; + + case "JustifyRight": + if (align == 'right') { + img.setAttribute('align', ''); // Needed for IE + img.removeAttribute('align'); + } else + img.setAttribute('align', 'right'); + + // Remove the div + div = focusElm.parentNode; + if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) + div.parentNode.replaceChild(img, div); + + this.selection.selectNode(img); + this.repaint(); + tinyMCE.triggerNodeChange(); + return; + } + } + + if (tinyMCE.settings.force_br_newlines) { + var alignValue = ""; + + if (doc.selection.type != "Control") { + switch (command) { + case "JustifyLeft": + alignValue = "left"; + break; + + case "JustifyCenter": + alignValue = "center"; + break; + + case "JustifyFull": + alignValue = "justify"; + break; + + case "JustifyRight": + alignValue = "right"; + break; + } + + if (alignValue !== '') { + var rng = doc.selection.createRange(); + + if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null) + divElm.setAttribute("align", alignValue); + else if (rng.pasteHTML && rng.htmlText.length > 0) + rng.pasteHTML('
' + rng.htmlText + "
"); + + tinyMCE.triggerNodeChange(); + return; + } + } + } + + switch (command) { + case "mceRepaint": + this.repaint(); + return true; + + case "JustifyLeft": + case "JustifyCenter": + case "JustifyFull": + case "JustifyRight": + var el = tinyMCE.getParentNode(focusElm, function(n) {return tinyMCE.getAttrib(n, 'align');}); + + if (el) { + el.setAttribute('align', ''); // Needed for IE + el.removeAttribute('align'); + } else + this.getDoc().execCommand(command, user_interface, value); + + tinyMCE.triggerNodeChange(); + + return true; + + case "unlink": + // Unlink if caret is inside link + if (tinyMCE.isGecko && this.getSel().isCollapsed) { + focusElm = tinyMCE.getParentElement(focusElm, 'A'); + + if (focusElm) + this.selection.selectNode(focusElm, false); + } + + this.getDoc().execCommand(command, user_interface, value); + + tinyMCE.isGecko && this.getSel().collapseToEnd(); + + tinyMCE.triggerNodeChange(); + + return true; + + case "InsertUnorderedList": + case "InsertOrderedList": + this.getDoc().execCommand(command, user_interface, value); + tinyMCE.triggerNodeChange(); + break; + + case "Strikethrough": + this.getDoc().execCommand(command, user_interface, value); + tinyMCE.triggerNodeChange(); + break; + + case "mceSelectNode": + this.selection.selectNode(value); + tinyMCE.triggerNodeChange(); + tinyMCE.selectedNode = value; + break; + + case "FormatBlock": + if (value == null || value == '') { + var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp"); + + if (elm) + this.execCommand("mceRemoveNode", false, elm); + } else { + if (!this.cleanup.isValid(value)) + return true; + + if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) + value = value.replace(/[^a-z]/gi, ''); + + if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) { + var b = this.selection.getBookmark(); + this.getDoc().execCommand("FormatBlock", false, '

'); + tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value); + this.selection.moveToBookmark(b); + } else + this.getDoc().execCommand("FormatBlock", false, value); + } + + tinyMCE.triggerNodeChange(); + + break; + + case "mceRemoveNode": + if (!value) + value = tinyMCE.getParentElement(this.getFocusElement()); + + if (tinyMCE.isIE) { + value.outerHTML = value.innerHTML; + } else { + var rng = value.ownerDocument.createRange(); + rng.setStartBefore(value); + rng.setEndAfter(value); + rng.deleteContents(); + rng.insertNode(rng.createContextualFragment(value.innerHTML)); + } + + tinyMCE.triggerNodeChange(); + + break; + + case "mceSelectNodeDepth": + var parentNode = this.getFocusElement(); + for (i=0; parentNode; i++) { + if (parentNode.nodeName.toLowerCase() == "body") + break; + + if (parentNode.nodeName.toLowerCase() == "#text") { + i--; + parentNode = parentNode.parentNode; + continue; + } + + if (i == value) { + this.selection.selectNode(parentNode, false); + tinyMCE.triggerNodeChange(); + tinyMCE.selectedNode = parentNode; + return; + } + + parentNode = parentNode.parentNode; + } + + break; + + case "mceSetStyleInfo": + case "SetStyleInfo": + var rng = this.getRng(); + var sel = this.getSel(); + var scmd = value.command; + var sname = value.name; + var svalue = value.value == null ? '' : value.value; + //var svalue = value['value'] == null ? '' : value['value']; + var wrapper = value.wrapper ? value.wrapper : "span"; + var parentElm = null; + var invalidRe = new RegExp("^BODY|HTML$", "g"); + var invalidParentsRe = tinyMCE.settings.merge_styles_invalid_parents !== '' ? new RegExp(tinyMCE.settings.merge_styles_invalid_parents, "gi") : null; + + // Whole element selected check + if (tinyMCE.isIE) { + // Control range + if (rng.item) + parentElm = rng.item(0); + else { + var pelm = rng.parentElement(); + var prng = doc.selection.createRange(); + prng.moveToElementText(pelm); + + if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) { + if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName)) + parentElm = pelm; + } + } + } else { + var felm = this.getFocusElement(); + if (sel.isCollapsed || (new RegExp('td|tr|tbody|table|img', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode)) + parentElm = felm; + } + + // Whole element selected + if (parentElm && !invalidRe.test(parentElm.nodeName)) { + if (scmd == "setstyle") + tinyMCE.setStyleAttrib(parentElm, sname, svalue); + + if (scmd == "setattrib") + tinyMCE.setAttrib(parentElm, sname, svalue); + + if (scmd == "removeformat") { + parentElm.style.cssText = ''; + tinyMCE.setAttrib(parentElm, 'class', ''); + } + + // Remove style/attribs from all children + var ch = tinyMCE.getNodeTree(parentElm, [], 1); + for (z=0; z=0; i--) { + var elm = nodes[i]; + var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true"; + + elm.removeAttribute("mce_new"); + + // Is only child a element + if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) { + //tinyMCE.debug("merge1" + isNew); + this._mergeElements(scmd, elm, elm.childNodes[0], isNew); + continue; + } + + // Is I the only child + if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) { + //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName); + if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName)) + this._mergeElements(scmd, elm.parentNode, elm, false); + } + } + + // Remove empty wrappers + var nodes = doc.getElementsByTagName(wrapper); + for (i=nodes.length-1; i>=0; i--) { + var elm = nodes[i], isEmpty = true; + + // Check if it has any attribs + var tmp = doc.createElement("body"); + tmp.appendChild(elm.cloneNode(false)); + + // Is empty span, remove it + tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), ''); + //tinyMCE.debug(tmp.innerHTML); + if (new RegExp('', 'gi').test(tmp.innerHTML)) { + for (x=0; x 0) { + value = tinyMCE.replaceVar(value, "selection", selectedText); + tinyMCE.execCommand('mceInsertContent', false, value); + } + + this._addBogusBR(); + tinyMCE.triggerNodeChange(); + break; + + case "mceSetAttribute": + if (typeof(value) == 'object') { + var targetElms = (typeof(value.targets) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value.targets; + var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms); + + if (targetNode) { + targetNode.setAttribute(value.name, value.value); + tinyMCE.triggerNodeChange(); + } + } + break; + + case "mceSetCSSClass": + this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value}); + break; + + case "mceInsertRawHTML": + var key = 'tiny_mce_marker'; + + this.execCommand('mceBeginUndoLevel'); + + // Insert marker key + this.execCommand('mceInsertContent', false, key); + + // Store away scroll pos + var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft; + var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop; + + // Find marker and replace with RAW HTML + var html = this.getBody().innerHTML; + if ((pos = html.indexOf(key)) != -1) + tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length)); + + // Restore scoll pos + this.contentWindow.scrollTo(scrollX, scrollY); + + this.execCommand('mceEndUndoLevel'); + + break; + + case "mceInsertContent": + // Force empty string + if (!value) + value = ''; + + var insertHTMLFailed = false; + + // Removed since it produced problems in IE + // this.getWin().focus(); + + if (tinyMCE.isGecko || tinyMCE.isOpera) { + try { + // Is plain text or HTML, &,   etc will be encoded wrong in FF + if (value.indexOf('<') == -1 && !value.match(/(&| |<|>)/g)) { + var r = this.getRng(); + var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value)); + var s = this.getSel(); + var r2 = r.cloneRange(); + + // Insert text at cursor position + s.removeAllRanges(); + r.deleteContents(); + r.insertNode(n); + + // Move the cursor to the end of text + r2.selectNode(n); + r2.collapse(false); + s.removeAllRanges(); + s.addRange(r2); + } else { + value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value); + this.getDoc().execCommand('inserthtml', false, value); + tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); + } + } catch (ex) { + insertHTMLFailed = true; + } + + if (!insertHTMLFailed) { + tinyMCE.triggerNodeChange(); + return; + } + } + + if (!tinyMCE.isIE) { + var isHTML = value.indexOf('<') != -1; + var sel = this.getSel(); + var rng = this.getRng(); + + if (isHTML) { + if (tinyMCE.isSafari) { + var tmpRng = this.getDoc().createRange(); + + tmpRng.setStart(this.getBody(), 0); + tmpRng.setEnd(this.getBody(), 0); + + value = tmpRng.createContextualFragment(value); + } else + value = rng.createContextualFragment(value); + } else { + // Setup text node + value = doc.createTextNode(tinyMCE.entityDecode(value)); + } + + // Insert plain text in Safari + if (tinyMCE.isSafari && !isHTML) { + this.execCommand('InsertText', false, value.nodeValue); + tinyMCE.triggerNodeChange(); + return true; + } else if (tinyMCE.isSafari && isHTML) { + rng.deleteContents(); + rng.insertNode(value); + tinyMCE.triggerNodeChange(); + return true; + } + + rng.deleteContents(); + + // If target node is text do special treatment, (Mozilla 1.3 fix) + if (rng.startContainer.nodeType == 3) { + var node = rng.startContainer.splitText(rng.startOffset); + node.parentNode.insertBefore(value, node); + } else + rng.insertNode(value); + + if (!isHTML) { + // Removes weird selection trails + sel.selectAllChildren(doc.body); + sel.removeAllRanges(); + + // Move cursor to end of content + var rng = doc.createRange(); + + rng.selectNode(value); + rng.collapse(false); + + sel.addRange(rng); + } else + rng.collapse(false); + + tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); + } else { + var rng = doc.selection.createRange(), tmpRng = null; + var c = value.indexOf('"; + } + + if (hc) { + cn = n.childNodes; + + for (i=0, l=cn.length; i'; + + return h; + }, + + _serializeAttribute : function(n, r, an) { + var av = '', t, os = this.settings.on_save; + + if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0)) + return ''; + + if (os && this.mceAttribs[an]) + av = this._getAttrib(n, this.mceAttribs[an]); + + if (av.length == 0) + av = this._getAttrib(n, an); + + if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) { + av = t; + + if (av == "mce_empty") + return " " + an + '=""'; + } + + if (r.forceAttribs && (t = r.forceAttribs[an])) + av = t; + + if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an)) + av = this._urlConverter(this, n, av); + + if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av)) + return ""; + + if (av.length != 0 && av == "{$uid}") + av = "uid_" + (this.idCount++); + + if (av.length != 0) { + if (an.indexOf('on') != 0) + av = this.xmlEncode(av, 1); + + return " " + an + "=" + '"' + av + '"'; + } + + return ""; + }, + + formatHTML : function(h) { + var s = this.settings, p = '', i = 0, li = 0, o = '', l; + + // Replace BR in pre elements to \n + h = h.replace(/]*)>(.*?)<\/pre>/gi, function (a, b, c) { + c = c.replace(//gi, '\n'); + return '' + c + ''; + }); + + h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :) + h = '\n' + h; + h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting + h = h.replace(this.nlBeforeRe, '\n<$1$2>'); + h = h.replace(this.nlAfterRe, '<$1$2>\n'); + h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n'); + h += '\n'; + + //tinyMCE.debug(h); + + while ((i = h.indexOf('\n', i + 1)) != -1) { + if ((l = h.substring(li + 1, i)).length != 0) { + if (this.ouRe.test(l) && p.length >= s.indent_levels) + p = p.substring(s.indent_levels); + + o += p + l + '\n'; + + if (this.inRe.test(l)) + p += this.inStr; + } + + li = i; + } + + //tinyMCE.debug(h); + + return o; + }, + + xmlEncode : function(s) { + var cl = this, re = this.xmlEncodeRe; + + if (!this.entitiesDone) + this._setupEntities(); // Will intialize lookup table + + switch (this.settings.entity_encoding) { + case "raw": + return tinyMCE.xmlEncode(s); + + case "named": + return s.replace(re, function (c) { + var b = cl.entities[c.charCodeAt(0)]; + + return b ? '&' + b + ';' : c; + }); + + case "numeric": + return s.replace(re, function (c) { + return '&#' + c.charCodeAt(0) + ';'; + }); + } + + return s; + }, + + split : function(re, s) { + var i, l, o = [], c = s.split(re); + + for (i=0, l=c.length; i' : '>' + h + ''; + + return o; + }, + + createTag : function(d, tn, a, h) { + var o = d.createElement(tn), n; + + if (a) { + for (n in a) { + if (typeof(a[n]) != 'function' && a[n] != null) + tinyMCE.setAttrib(o, n, a[n]); + } + } + + if (h) + o.innerHTML = h; + + return o; + }, + + getElementByAttributeValue : function(n, e, a, v) { + return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0]; + }, + + getElementsByAttributeValue : function(n, e, a, v) { + var i, nl = n.getElementsByTagName(e), o = []; + + for (i=0; i]*)>/gi, ''); + h = h.replace(/]*)>/gi, ''); + h = h.replace(/]*)>/gi, ''); + h = h.replace(/]*)>/gi, ''); + h = h.replace(/<\/strong>/gi, ''); + h = h.replace(/<\/em>/gi, ''); + } + + if (tinyMCE.isRealIE) { + // Since MSIE handles invalid HTML better that valid XHTML we + // need to make some things invalid.


gets converted to
. + h = h.replace(/\s\/>/g, '>'); + + // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones + h = h.replace(/]*)>\u00A0?<\/p>/gi, ' 

'); // Keep empty paragraphs + h = h.replace(/]*)>\s* \s*<\/p>/gi, ' 

'); // Keep empty paragraphs + h = h.replace(/]*)>\s+<\/p>/gi, ' 

'); // Keep empty paragraphs + + // Remove first comment + e.innerHTML = tinyMCE.uniqueTag + h; + e.firstChild.removeNode(true); + + // Remove weird auto generated empty paragraphs unless it's supposed to be there + nl = e.getElementsByTagName("p"); + for (i=nl.length-1; i>=0; i--) { + n = nl[i]; + + if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep) + n.parentNode.removeChild(n); + } + } else { + h = this.fixGeckoBaseHREFBug(1, e, h); + e.innerHTML = h; + this.fixGeckoBaseHREFBug(2, e, h); + } + }, + + getOuterHTML : function(e) { + var d; + + if (tinyMCE.isIE) + return e.outerHTML; + + d = e.ownerDocument.createElement("body"); + d.appendChild(e.cloneNode(true)); + + return d.innerHTML; + }, + + setOuterHTML : function(e, h, d) { + var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t; + + if (tinyMCE.isIE && e.nodeType == 1) + e.outerHTML = h; + else { + t = d.createElement("body"); + t.innerHTML = h; + + for (i=0, nl=t.childNodes; i-1; i--) { + if (ar[i].specified && ar[i].nodeValue) + ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue); + } + + ar = e.childNodes; + for (i=0; i= strTok2.length) { + for (i=0; i= strTok2.length || strTok1[i] != strTok2[i]) { + breakPoint = i + 1; + break; + } + } + } + + if (strTok1.length < strTok2.length) { + for (i=0; i= strTok1.length || strTok1[i] != strTok2[i]) { + breakPoint = i + 1; + break; + } + } + } + + if (breakPoint == 1) + return targetURL.path; + + for (i=0; i<(strTok1.length-(breakPoint-1)); i++) + outPath += "../"; + + for (i=breakPoint-1; i=0; i--) { + if (baseURLParts[i].length == 0) + continue; + + newBaseURLParts[newBaseURLParts.length] = baseURLParts[i]; + } + baseURLParts = newBaseURLParts.reverse(); + + // Merge relURLParts chunks + newRelURLParts = []; + numBack = 0; + for (i=relURLParts.length-1; i>=0; i--) { + if (relURLParts[i].length == 0 || relURLParts[i] == ".") + continue; + + if (relURLParts[i] == '..') { + numBack++; + continue; + } + + if (numBack > 0) { + numBack--; + continue; + } + + newRelURLParts[newRelURLParts.length] = relURLParts[i]; + } + + relURLParts = newRelURLParts.reverse(); + + // Remove end from absolute path + len = baseURLParts.length-numBack; + absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/'); + start = ""; + end = ""; + + // Build output URL + relURL.protocol = baseURL.protocol; + relURL.host = baseURL.host; + relURL.port = baseURL.port; + + // Re-add trailing slash if it's removed + if (relURL.path.charAt(relURL.path.length-1) == "/") + absPath += "/"; + + relURL.path = absPath; + + return this.serializeURL(relURL); + }, + + convertURL : function(url, node, on_save) { + var dl = document.location, start, portPart, urlParts, baseUrlParts, tmpUrlParts, curl; + var prot = dl.protocol, host = dl.hostname, port = dl.port; + + // Pass through file protocol + if (prot == "file:") + return url; + + // Something is wrong, remove weirdness + url = tinyMCE.regexpReplace(url, '(http|https):///', '/'); + + // Mailto link or anchor (Pass through) + if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || /^[ \t\r\n\+]*[#\?]/.test(url)) + return url; + + // Fix relative/Mozilla + if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/') + return tinyMCE.settings.base_href + url; + + // Handle relative URLs + if (on_save && tinyMCE.getParam('relative_urls')) { + curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url); + if (curl.charAt(0) == '/') + curl = tinyMCE.settings.document_base_prefix + curl; + + urlParts = tinyMCE.parseURL(curl); + tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings.document_base_url); + + // Force relative + if (urlParts.host == tmpUrlParts.host && (urlParts.port == tmpUrlParts.port)) + return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings.document_base_url, curl); + } + + // Handle absolute URLs + if (!tinyMCE.getParam('relative_urls')) { + urlParts = tinyMCE.parseURL(url); + baseUrlParts = tinyMCE.parseURL(tinyMCE.settings.base_href); + + // Force absolute URLs from relative URLs + url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url); + + // If anchor and path is the same page + if (urlParts.anchor && urlParts.path == baseUrlParts.path) + return "#" + urlParts.anchor; + } + + // Remove current domain + if (tinyMCE.getParam('remove_script_host')) { + start = ""; + portPart = ""; + + if (port !== '') + portPart = ":" + port; + + start = prot + "//" + host + portPart + "/"; + + if (url.indexOf(start) == 0) + url = url.substring(start.length-1); + } + + return url; + }, + + convertAllRelativeURLs : function(body) { + var i, elms, src, href, mhref, msrc; + + // Convert all image URL:s to absolute URL + elms = body.getElementsByTagName("img"); + for (i=0; i bookmark.index) { + try { + rng.addElement(nl[bookmark.index]); + } catch (ex) { + // Might be thrown if the node no longer exists + } + } + } else { + // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs + try { + // Incorrect bookmark + if (bookmark.start < 0) + return true; + + rng = inst.getSel().createRange(); + rng.moveToElementText(inst.getBody()); + rng.collapse(true); + rng.moveStart('character', bookmark.start); + rng.moveEnd('character', bookmark.length); + } catch (ex) { + return true; + } + } + + rng.select(); + + win.scrollTo(bookmark.scrollX, bookmark.scrollY); + return true; + } + + if (tinyMCE.isGecko || tinyMCE.isOpera) { + if (!sel) + return false; + + if (bookmark.rng) { + sel.removeAllRanges(); + sel.addRange(bookmark.rng); + } + + if (bookmark.start != -1 && bookmark.end != -1) { + try { + sd = this._getTextPos(b, bookmark.start, bookmark.end); + rng = doc.createRange(); + rng.setStart(sd.startNode, sd.startOffset); + rng.setEnd(sd.endNode, sd.endOffset); + sel.removeAllRanges(); + sel.addRange(rng); + + if (!tinyMCE.isOpera) + win.focus(); + } catch (ex) { + // Ignore + } + } + + /* + if (typeof(bookmark.index) != 'undefined') { + tinyMCE.selectElements(b, 'IMG', function (n) { + if (bookmark.index-- == 0) { + // Select image in Gecko here + } + + return false; + }); + } + */ + + win.scrollTo(bookmark.scrollX, bookmark.scrollY); + return true; + } + + return false; + }, + + _getPosText : function(r, sn, en) { + var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; + + while ((n = w.nextNode()) != null) { + if (n == sn) + d.start = p; + + if (n == en) { + d.end = p; + return d; + } + + p += n.nodeValue ? n.nodeValue.length : 0; + } + + return null; + }, + + _getTextPos : function(r, sp, ep) { + var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; + + while ((n = w.nextNode()) != null) { + p += n.nodeValue ? n.nodeValue.length : 0; + + if (p >= sp && !d.startNode) { + d.startNode = n; + d.startOffset = sp - (p - n.nodeValue.length); + } + + if (p >= ep) { + d.endNode = n; + d.endOffset = ep - (p - n.nodeValue.length); + + return d; + } + } + + return null; + }, + + selectNode : function(node, collapse, select_text_node, to_start) { + var inst = this.instance, sel, rng, nodes; + + if (!node) + return; + + if (typeof(collapse) == "undefined") + collapse = true; + + if (typeof(select_text_node) == "undefined") + select_text_node = false; + + if (typeof(to_start) == "undefined") + to_start = true; + + if (inst.settings.auto_resize) + inst.resizeToContent(); + + if (tinyMCE.isRealIE) { + rng = inst.getDoc().body.createTextRange(); + + try { + rng.moveToElementText(node); + + if (collapse) + rng.collapse(to_start); + + rng.select(); + } catch (e) { + // Throws illigal agrument in MSIE some times + } + } else { + sel = this.getSel(); + + if (!sel) + return; + + if (tinyMCE.isSafari) { + sel.setBaseAndExtent(node, 0, node, node.innerText.length); + + if (collapse) { + if (to_start) + sel.collapseToStart(); + else + sel.collapseToEnd(); + } + + this.scrollToNode(node); + + return; + } + + rng = inst.getDoc().createRange(); + + if (select_text_node) { + // Find first textnode in tree + nodes = tinyMCE.getNodeTree(node, [], 3); + if (nodes.length > 0) + rng.selectNodeContents(nodes[0]); + else + rng.selectNodeContents(node); + } else + rng.selectNode(node); + + if (collapse) { + // Special treatment of textnode collapse + if (!to_start && node.nodeType == 3) { + rng.setStart(node, node.nodeValue.length); + rng.setEnd(node, node.nodeValue.length); + } else + rng.collapse(to_start); + } + + sel.removeAllRanges(); + sel.addRange(rng); + } + + this.scrollToNode(node); + + // Set selected element + tinyMCE.selectedElement = null; + if (node.nodeType == 1) + tinyMCE.selectedElement = node; + }, + + scrollToNode : function(node) { + var inst = this.instance, w = inst.getWin(), vp = inst.getViewPort(), pos = tinyMCE.getAbsPosition(node), cvp, p, cwin; + + // Only scroll if out of visible area + if (pos.absLeft < vp.left || pos.absLeft > vp.left + vp.width || pos.absTop < vp.top || pos.absTop > vp.top + (vp.height-25)) + w.scrollTo(pos.absLeft, pos.absTop - vp.height + 25); + + // Scroll container window + if (inst.settings.auto_resize) { + cwin = inst.getContainerWin(); + cvp = tinyMCE.getViewPort(cwin); + p = this.getAbsPosition(node); + + if (p.absLeft < cvp.left || p.absLeft > cvp.left + cvp.width || p.absTop < cvp.top || p.absTop > cvp.top + cvp.height) + cwin.scrollTo(p.absLeft, p.absTop - cvp.height + 25); + } + }, + + getAbsPosition : function(n) { + var pos = tinyMCE.getAbsPosition(n), ipos = tinyMCE.getAbsPosition(this.instance.iframeElement); + + return { + absLeft : ipos.absLeft + pos.absLeft, + absTop : ipos.absTop + pos.absTop + }; + }, + + getSel : function() { + var inst = this.instance; + + if (tinyMCE.isRealIE) + return inst.getDoc().selection; + + return inst.contentWindow.getSelection(); + }, + + getRng : function() { + var s = this.getSel(); + + if (s == null) + return null; + + if (tinyMCE.isRealIE) + return s.createRange(); + + if (tinyMCE.isSafari && !s.getRangeAt) + return '' + window.getSelection(); + + if (s.rangeCount > 0) + return s.getRangeAt(0); + + return null; + }, + + isCollapsed : function() { + var r = this.getRng(); + + if (r.item) + return false; + + return r.boundingWidth == 0 || this.getSel().isCollapsed; + }, + + collapse : function(b) { + var r = this.getRng(), s = this.getSel(); + + if (r.select) { + r.collapse(b); + r.select(); + } else { + if (b) + s.collapseToStart(); + else + s.collapseToEnd(); + } + }, + + getFocusElement : function() { + var inst = this.instance, doc, rng, sel, elm; + + if (tinyMCE.isRealIE) { + doc = inst.getDoc(); + rng = doc.selection.createRange(); + + // if (rng.collapse) + // rng.collapse(true); + + elm = rng.item ? rng.item(0) : rng.parentElement(); + } else { + if (!tinyMCE.isSafari && inst.isHidden()) + return inst.getBody(); + + sel = this.getSel(); + rng = this.getRng(); + + if (!sel || !rng) + return null; + + elm = rng.commonAncestorContainer; + //elm = (sel && sel.anchorNode) ? sel.anchorNode : null; + + // Handle selection a image or other control like element such as anchors + if (!rng.collapsed) { + // Is selection small + if (rng.startContainer == rng.endContainer) { + if (rng.startOffset - rng.endOffset < 2) { + if (rng.startContainer.hasChildNodes()) + elm = rng.startContainer.childNodes[rng.startOffset]; + } + } + } + + // Get the element parent of the node + elm = tinyMCE.getParentElement(elm); + + //if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") + // elm = tinyMCE.selectedElement; + } + + return elm; + } + + }; + +/* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */ + +function TinyMCE_UndoRedo(inst) { + this.instance = inst; + this.undoLevels = []; + this.undoIndex = 0; + this.typingUndoIndex = -1; + this.undoRedo = true; +}; + +TinyMCE_UndoRedo.prototype = { + add : function(l) { + var b, customUndoLevels, newHTML, inst = this.instance, i, ul, ur; + + if (l) { + this.undoLevels[this.undoLevels.length] = l; + return true; + } + + if (this.typingUndoIndex != -1) { + this.undoIndex = this.typingUndoIndex; + + if (tinyMCE.typingUndoIndex != -1) + tinyMCE.undoIndex = tinyMCE.typingUndoIndex; + } + + newHTML = tinyMCE.trim(inst.getBody().innerHTML); + if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) { + //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content); + + // Is dirty again + inst.isNotDirty = false; + + tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst); + + // Time to compress + customUndoLevels = tinyMCE.settings.custom_undo_redo_levels; + if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) { + for (i=0; i 0) { + this.undoIndex--; + + tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); + inst.repaint(); + + if (inst.settings.custom_undo_redo_restore_selection) + inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); + } + }, + + redo : function() { + var inst = this.instance; + + tinyMCE.execCommand("mceEndTyping"); + + if (this.undoIndex < (this.undoLevels.length-1)) { + this.undoIndex++; + + tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content); + inst.repaint(); + + if (inst.settings.custom_undo_redo_restore_selection) + inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); + } + + tinyMCE.triggerNodeChange(); + } + + }; + +/* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */ + +var TinyMCE_ForceParagraphs = { + _insertPara : function(inst, e) { + var doc = inst.getDoc(), sel = inst.getSel(), body = inst.getBody(), win = inst.contentWindow, rng = sel.getRangeAt(0); + var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock; + var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null; + var paraBefore, paraAfter, startChop, endChop, contents, i; + + function isEmpty(para) { + var nodes; + + function isEmptyHTML(html) { + return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == ''; + } + + // Check for images + if (para.getElementsByTagName("img").length > 0) + return false; + + // Check for tables + if (para.getElementsByTagName("table").length > 0) + return false; + + // Check for HRs + if (para.getElementsByTagName("hr").length > 0) + return false; + + // Check all textnodes + nodes = tinyMCE.getNodeTree(para, [], 3); + for (i=0; i <" + blockName + "> "; + paraAfter = body.childNodes[1]; + } + + inst.selection.moveToBookmark(b); + inst.selection.selectNode(paraAfter, true, true); + + return true; + } + + // Place first part within new paragraph + if (startChop.nodeName == blockName) + rngBefore.setStart(startChop, 0); + else + rngBefore.setStartBefore(startChop); + + rngBefore.setEnd(startNode, startOffset); + paraBefore.appendChild(rngBefore.cloneContents()); + + // Place secound part within new paragraph + rngAfter.setEndAfter(endChop); + rngAfter.setStart(endNode, endOffset); + contents = rngAfter.cloneContents(); + + if (contents.firstChild && contents.firstChild.nodeName == blockName) { + /* var nodes = contents.firstChild.childNodes; + for (i=0; i= r.startOffset && nv.charAt(r.startOffset - 1) == ' ') + s = true;*/ + + // Only remove BRs if we are at the end of line #bug 1464152 + if (nv != null && r.startOffset == nv.length) + sn.nextSibling.parentNode.removeChild(sn.nextSibling); + } + + if (inst.settings.auto_resize) + inst.resizeToContent(); + + return s; + } + + }; + +/* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */ + +function TinyMCE_Layer(id, bm) { + this.id = id; + this.blockerElement = null; + this.events = false; + this.element = null; + this.blockMode = typeof(bm) != 'undefined' ? bm : true; + this.doc = document; +}; + +TinyMCE_Layer.prototype = { + moveRelativeTo : function(re, p) { + var rep = this.getAbsPosition(re), e = this.getElement(), x, y; + var w = parseInt(re.offsetWidth), h = parseInt(re.offsetHeight); + var ew = parseInt(e.offsetWidth), eh = parseInt(e.offsetHeight); + + switch (p) { + case "tl": + x = rep.absLeft; + y = rep.absTop; + break; + + case "tr": + x = rep.absLeft + w; + y = rep.absTop; + break; + + case "bl": + x = rep.absLeft; + y = rep.absTop + h; + break; + + case "br": + x = rep.absLeft + w; + y = rep.absTop + h; + break; + + case "cc": + x = rep.absLeft + (w / 2) - (ew / 2); + y = rep.absTop + (h / 2) - (eh / 2); + break; + } + + this.moveTo(x, y); + }, + + moveBy : function(x, y) { + var e = this.getElement(); + this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y); + }, + + moveTo : function(x, y) { + var e = this.getElement(); + + e.style.left = x + "px"; + e.style.top = y + "px"; + + this.updateBlocker(); + }, + + resizeBy : function(w, h) { + var e = this.getElement(); + this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h); + }, + + resizeTo : function(w, h) { + var e = this.getElement(); + + if (w != null) + e.style.width = w + "px"; + + if (h != null) + e.style.height = h + "px"; + + this.updateBlocker(); + }, + + show : function() { + var el = this.getElement(); + + if (el) { + el.style.display = 'block'; + this.updateBlocker(); + } + }, + + hide : function() { + var el = this.getElement(); + + if (el) { + el.style.display = 'none'; + this.updateBlocker(); + } + }, + + isVisible : function() { + return this.getElement().style.display == 'block'; + }, + + getElement : function() { + if (!this.element) + this.element = this.doc.getElementById(this.id); + + return this.element; + }, + + setBlockMode : function(s) { + this.blockMode = s; + }, + + updateBlocker : function() { + var e, b, x, y, w, h; + + b = this.getBlocker(); + if (b) { + if (this.blockMode) { + e = this.getElement(); + x = this.parseInt(e.style.left); + y = this.parseInt(e.style.top); + w = this.parseInt(e.offsetWidth); + h = this.parseInt(e.offsetHeight); + + b.style.left = x + 'px'; + b.style.top = y + 'px'; + b.style.width = w + 'px'; + b.style.height = h + 'px'; + b.style.display = e.style.display; + } else + b.style.display = 'none'; + } + }, + + getBlocker : function() { + var d, b; + + if (!this.blockerElement && this.blockMode) { + d = this.doc; + b = d.getElementById(this.id + "_blocker"); + + if (!b) { + b = d.createElement("iframe"); + + b.setAttribute('id', this.id + "_blocker"); + b.style.cssText = 'display: none; position: absolute; left: 0; top: 0'; + b.src = 'javascript:false;'; + b.frameBorder = '0'; + b.scrolling = 'no'; + + d.body.appendChild(b); + } + + this.blockerElement = b; + } + + return this.blockerElement; + }, + + getAbsPosition : function(n) { + var p = {absLeft : 0, absTop : 0}; + + while (n) { + p.absLeft += n.offsetLeft; + p.absTop += n.offsetTop; + n = n.offsetParent; + } + + return p; + }, + + create : function(n, c, p, h) { + var d = this.doc, e = d.createElement(n); + + e.setAttribute('id', this.id); + + if (c) + e.className = c; + + if (!p) + p = d.body; + + if (h) + e.innerHTML = h; + + p.appendChild(e); + + return this.element = e; + }, + + exists : function() { + return this.doc.getElementById(this.id) != null; + }, + + parseInt : function(s) { + if (s == null || s == '') + return 0; + + return parseInt(s); + }, + + remove : function() { + var e = this.getElement(), b = this.getBlocker(); + + if (e) + e.parentNode.removeChild(e); + + if (b) + b.parentNode.removeChild(b); + } + + }; + +/* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */ + +function TinyMCE_Menu() { + var id; + + if (typeof(tinyMCE.menuCounter) == "undefined") + tinyMCE.menuCounter = 0; + + id = "mc_menu_" + tinyMCE.menuCounter++; + + TinyMCE_Layer.call(this, id, true); + + this.id = id; + this.items = []; + this.needsUpdate = true; +}; + +TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, { + init : function(s) { + var n; + + // Default params + this.settings = { + separator_class : 'mceMenuSeparator', + title_class : 'mceMenuTitle', + disabled_class : 'mceMenuDisabled', + menu_class : 'mceMenu', + drop_menu : true + }; + + for (n in s) + this.settings[n] = s[n]; + + this.create('div', this.settings.menu_class); + }, + + clear : function() { + this.items = []; + }, + + addTitle : function(t) { + this.add({type : 'title', text : t}); + }, + + addDisabled : function(t) { + this.add({type : 'disabled', text : t}); + }, + + addSeparator : function() { + this.add({type : 'separator'}); + }, + + addItem : function(t, js) { + this.add({text : t, js : js}); + }, + + add : function(mi) { + this.items[this.items.length] = mi; + this.needsUpdate = true; + }, + + update : function() { + var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings; + + if (this.settings.drop_menu) + h += ''; + + h += ''; + + for (i=0; i'; + } + + h += '
'; + break; + + case 'title': + h += '
' + t + ''; + break; + + case 'disabled': + h += '
' + t + ''; + break; + + default: + h += '
' + t + ''; + } + + h += '
'; + + e.innerHTML = h; + + this.needsUpdate = false; + this.updateBlocker(); + }, + + show : function() { + var nl, i; + + if (tinyMCE.lastMenu == this) + return; + + if (this.needsUpdate) + this.update(); + + if (tinyMCE.lastMenu && tinyMCE.lastMenu != this) + tinyMCE.lastMenu.hide(); + + TinyMCE_Layer.prototype.show.call(this); + + if (!tinyMCE.isOpera) { + // Accessibility stuff +/* nl = this.getElement().getElementsByTagName("a"); + if (nl.length > 0) + nl[0].focus();*/ + } + + tinyMCE.lastMenu = this; + } + + }); + +/* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */ + +tinyMCE.add(TinyMCE_Engine, { + debug : function() { + var m = "", a, i, l = tinyMCE.log.length; + + for (i=0, a = this.debug.arguments; i