/* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */ function TinyMCE_Engine() { this.majorVersion = "2"; this.minorVersion = "0.6.1"; this.releaseDate = "2006-05-04"; this.instances = new Array(); this.switchClassCache = new Array(); this.windowArgs = new Array(); this.loadedFiles = new Array(); this.pendingFiles = new Array(); this.loadingIndex = 0; this.configs = new Array(); this.currentConfig = 0; this.eventHandlers = new Array(); // Browser check var 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.isGecko = ua.indexOf('Gecko') != -1; this.isSafari = ua.indexOf('Safari') != -1; this.isOpera = ua.indexOf('Opera') != -1; 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 = new Array(); this.themes = new Array(); this.menus = new Array(); this.loadedPlugins = new Array(); this.buttonMap = new Array(); 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; } // TinyMCE editor id instance counter this.idCounter = 0; }; TinyMCE_Engine.prototype = { init : function(settings) { var theme; this.settings = settings; // Check if valid browser has execcommand support if (typeof(document.execCommand) == 'undefined') return; // Get script base path if (!tinyMCE.baseURL) { var elements = document.getElementsByTagName('script'); for (var i=0; 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", false); 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", ''); // 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 var baseHREF = tinyMCE.settings['document_base_url']; var h = document.location.href; var 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.blockRegExp = new RegExp("^(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|blockquote|center|dl|dt|dd|dir|fieldset|form|noscript|noframes|menu|isindex|samp)$", "i"); this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40); this.uniqueURL = 'javascript:TINYMCE_UNIQUEURL();'; // Make unique URL non real URL this.uniqueTag = ''; this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup'); // Theme url this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme; if (!tinyMCE.isMSIE) this.settings['force_br_newlines'] = false; if (tinyMCE.getParam("popups_css", false)) { var 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)) { var 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 this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css"; if (tinyMCE.settings['debug']) { var msg = "Debug: \n"; msg += "baseURL: " + this.baseURL + "\n"; msg += "documentBasePath: " + this.documentBasePath + "\n"; msg += "content_css: " + this.settings['content_css'] + "\n"; msg += "popups_css: " + this.settings['popups_css'] + "\n"; msg += "editor_css: " + this.settings['editor_css'] + "\n"; alert(msg); } // Only do this once if (this.configs.length == 0) { // Is Safari enabled if (this.isSafari && this.getParam('safari_warning', false)) alert("Safari support is very limited and should be considered experimental.\nSo there is no need to even submit bugreports on this early version.\nYou can disable this message by setting: safari_warning option to false"); if (typeof(TinyMCECompressed) == "undefined") { tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad); if (tinyMCE.isMSIE && !tinyMCE.isOpera) { 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 var p = tinyMCE.getParam('plugins', '', true, ','); if (p.length > 0) { for (var 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; var 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.isMSIE ? 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) { // Find MCE instance linked to given form element and copy it's value var formElement = document.getElementById(form_element_name); for (var n in tinyMCE.instances) { var inst = tinyMCE.instances[n]; if (!tinyMCE.isInstance(inst)) continue; inst.switchSettings(); if (inst.formElement == formElement) { var doc = inst.getDoc(); tinyMCE._setHTML(doc, inst.formElement.value); if (!tinyMCE.isMSIE) 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); }, removeMCEControl : function(editor_id) { var inst = tinyMCE.getInstanceById(editor_id); if (inst) { inst.switchSettings(); editor_id = inst.editorId; var html = tinyMCE.getContent(editor_id); // Remove editor instance from instances array var tmpInstances = new Array(); for (var instanceName in tinyMCE.instances) { var instance = tinyMCE.instances[instanceName]; if (!tinyMCE.isInstance(instance)) continue; if (instanceName != editor_id) tmpInstances[instanceName] = instance; } tinyMCE.instances = tmpInstances; tinyMCE.selectedElement = null; tinyMCE.selectedInstance = null; // Remove element var replaceElement = document.getElementById(editor_id + "_parent"); var oldTargetElement = inst.oldTargetElement; var targetName = oldTargetElement.nodeName.toLowerCase(); if (targetName == "textarea" || targetName == "input") { // Just show the old text area replaceElement.parentNode.removeChild(replaceElement); oldTargetElement.style.display = "inline"; oldTargetElement.value = html; } else { oldTargetElement.innerHTML = html; oldTargetElement.style.display = 'block'; replaceElement.parentNode.insertBefore(oldTargetElement, replaceElement); replaceElement.parentNode.removeChild(replaceElement); } } }, triggerSave : function(skip_cleanup, skip_callback) { var inst, n; // Default to false if (typeof(skip_cleanup) == "undefined") skip_cleanup = false; // Default to false if (typeof(skip_callback) == "undefined") skip_callback = false; // Cleanup and set all form fields for (n in tinyMCE.instances) { inst = tinyMCE.instances[n]; if (!tinyMCE.isInstance(inst)) continue; inst.triggerSave(skip_cleanup, skip_callback); } }, resetForm : function(form_index) { var i, inst, n, formObj = document.forms[form_index]; for (n in tinyMCE.instances) { inst = tinyMCE.instances[n]; if (!tinyMCE.isInstance(inst)) continue; inst.switchSettings(); for (i=0; i'); content = content.replace(/"/g, '"'); content = content.replace(/&/g, '&'); } inst.switchSettings(); // Not loaded correctly hit it again, Mozilla bug #997860 if (!tinyMCE.isMSIE && 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; } if (!head) { 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'); } // 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.getDoc().body.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.isMSIE) 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.isMSIE) { // 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;"); var body = inst.getBody(); body.editorId = editor_id; } content = tinyMCE.cleanupHTMLCode(content); // Fix for bug #958637 if (!tinyMCE.isMSIE) { var contentElement = inst.getDoc().createElement("body"); var doc = inst.getDoc(); contentElement.innerHTML = content; // Remove weridness! if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt']) content = content.replace(new RegExp('<>', 'g'), ""); if (tinyMCE.settings['cleanup_on_startup']) tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement)); else { // Convert all strong/em to b/i content = tinyMCE.regexpReplace(content, "", "", "gi"); content = tinyMCE.regexpReplace(content, "", "", "gi"); content = tinyMCE.regexpReplace(content, "", "", "gi"); 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 eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}'); } else tinyMCE._setHTML(inst.getDoc(), content); } // Fix for bug #957681 //inst.getDoc().designMode = inst.getDoc().designMode; // Setup element references var parentElm = inst.targetDoc.getElementById(inst.editorId + '_parent'); inst.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling; tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst); tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); // Re-add design mode on mozilla if (!tinyMCE.isMSIE) tinyMCE.addEventHandlers(inst); // Add blur handler if (tinyMCE.isMSIE) { 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 tinyMCE.selectedInstance = inst; 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('\\smce_src=\"[^\"]*\"', 'gi'), ""); n.nodeValue = n.nodeValue.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), ""); } return false; }); } // Cleanup any mess left from storyAwayURLs tinyMCE._removeInternal(inst.getBody()); tinyMCE.selectedInstance = inst; 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('\\smce_src=\"[^\"]*\"', 'gi'), ""); n.nodeValue = n.nodeValue.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), ""); } return false; }); } }, removeTinyMCEFormElements : function(form_obj) { // 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 (var 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; break; case "keyup": case "keydown": tinyMCE.hideMenus(); tinyMCE.hasMouseMoved = false; if (inst && inst.handleShortcut(e)) return false; if (e.target.editorId) tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId]; else return; if (tinyMCE.selectedInstance) tinyMCE.selectedInstance.switchSettings(); var 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; var 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.isMSIE && e.type == "keydown" && e.keyCode == 13) tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement(); // Fix empty elements on return/enter if (tinyMCE.isMSIE && e.type == "keyup" && e.keyCode == 13) { var 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 var keys = tinyMCE.posKeyCodes; var posKey = false; for (var i=0; i'; h += ''; h += ''; } else { // Normal button h += ''; h += ''; h += ''; } return h; }, addButtonMap : function(m) { var i, a = m.replace(/\s+/, '').split(','); for (i=0; i 0); if (tinyMCE.settings['custom_undo_redo']) { undoIndex = inst.undoRedo.undoIndex; undoLevels = inst.undoRedo.undoLevels.length; } tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content); } if (this.selectedInstance && (typeof(focus) == "undefined" || focus)) this.selectedInstance.contentWindow.focus(); }, _customCleanup : function(inst, type, content) { var pl, po, i; // Call custom cleanup var customCleanup = tinyMCE.settings['cleanup_callback']; if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined") content = eval(customCleanup + "(type, content, inst);"); // Trigger plugin cleanups pl = inst.plugins; for (i=0; i 0) { for (i=ar.length-1; i>=0; i--) { s = ar[i].substring(2, ar[i].length-1); if (s.indexOf('lang_') == 0 && tinyMCELang[s]) h = tinyMCE.replaceVar(h, s, tinyMCELang[s]); else if (as && as[s]) h = tinyMCE.replaceVar(h, s, as[s]); else if (tinyMCE.settings[s]) h = tinyMCE.replaceVar(h, s, tinyMCE.settings[s]); } } h = tinyMCE.replaceVar(h, "themeurl", tinyMCE.themeURL); return h; }, replaceVar : function(h, r, v) { return h.replace(new RegExp('{\\\$' + r + '}', 'g'), v); }, openWindow : function(template, args) { var html, width, height, x, y, resizable, scrollbars, url; args['mce_template_file'] = template['file']; args['mce_width'] = template['width']; args['mce_height'] = template['height']; tinyMCE.windowArgs = args; html = template['html']; if (!(width = parseInt(template['width']))) width = 320; if (!(height = parseInt(template['height']))) height = 200; // Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!! if (tinyMCE.isMSIE) height += 40; else height += 20; x = parseInt(screen.width / 2.0) - (width / 2.0); y = parseInt(screen.height / 2.0) - (height / 2.0); resizable = (args && args['resizable']) ? args['resizable'] : "no"; scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no"; if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1) url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file']; else url = template['file']; // Replace all args as variables in URL for (var name in args) { if (typeof(args[name]) == 'function') continue; url = tinyMCE.replaceVar(url, name, escape(args[name])); } if (html) { html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']); html = tinyMCE.applyTemplate(html, args); var win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable); if (win == null) { alert(tinyMCELang['lang_popup_blocked']); return; } win.document.write(html); win.document.close(); win.resizeTo(width, height); win.focus(); } else { if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") { height += 10; var features = "resizable:" + resizable + ";scroll:" + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:" + width + "px;dialogHeight:" + height + "px;"; window.showModalDialog(url, window, features); } else { var modal = (resizable == "yes") ? "no" : "yes"; if (tinyMCE.isGecko && tinyMCE.isMac) modal = "no"; if (template['close_previous'] != "no") try {tinyMCE.lastWindow.close();} catch (ex) {} var win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable); if (win == null) { alert(tinyMCELang['lang_popup_blocked']); return; } if (template['close_previous'] != "no") tinyMCE.lastWindow = win; eval('try { win.resizeTo(width, height); } catch(e) { }'); // Make it bigger if statusbar is forced if (tinyMCE.isGecko) { if (win.document.defaultView.statusbar.visible) win.resizeBy(0, tinyMCE.isMac ? 10 : 24); } win.focus(); } } }, closeWindow : function(win) { win.close(); }, getVisualAidClass : function(class_name, state) { var aidClass = tinyMCE.settings['visual_table_class']; if (typeof(state) == "undefined") state = tinyMCE.settings['visual']; // Split var classNames = new Array(); var ar = class_name.split(' '); for (var i=0; i 0) className += " "; className += classNames[i]; } return className; }, handleVisualAid : function(el, deep, state, inst, skip_dispatch) { if (!el) return; if (!skip_dispatch) tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst); var tableElement = null; switch (el.nodeName) { case "TABLE": var oldW = el.style.width; var oldH = el.style.height; var 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 (var y=0; y<\/o:p>", "
"); html = tinyMCE.regexpReplace(html, " <\/o:p>", ""); html = tinyMCE.regexpReplace(html, "", ""); html = tinyMCE.regexpReplace(html, "

<\/p>", ""); html = tinyMCE.regexpReplace(html, "

<\/p>\r\n

<\/p>", ""); html = tinyMCE.regexpReplace(html, "

 <\/p>", "
"); html = tinyMCE.regexpReplace(html, "

\s*(

\s*)?", "

"); html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "

"); }*/ // Always set the htmlText output tinyMCE.setInnerHTML(doc.body, html); } tinyMCE.cleanupAnchors(doc); if (tinyMCE.getParam("convert_fonts_to_spans")) tinyMCE.convertSpansToFonts(doc); }, getEditorId : function(form_element) { var inst = this.getInstanceById(form_element); if (!inst) return null; return inst.editorId; }, getInstanceById : function(editor_id) { var inst = this.instances[editor_id]; if (!inst) { for (var n in tinyMCE.instances) { var instance = tinyMCE.instances[n]; if (!tinyMCE.isInstance(instance)) continue; if (instance.formTargetElementId == editor_id) { inst = instance; break; } } } return inst; }, queryInstanceCommandValue : function(editor_id, command) { var inst = tinyMCE.getInstanceById(editor_id); if (inst) return inst.queryCommandValue(command); return false; }, queryInstanceCommandState : function(editor_id, command) { var inst = tinyMCE.getInstanceById(editor_id); if (inst) return inst.queryCommandState(command); return null; }, setWindowArg : function(n, v) { this.windowArgs[n] = v; }, getWindowArg : function(n, d) { return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n]; }, getCSSClasses : function(editor_id, doc) { var output = new Array(); // Is cached, use that if (typeof(tinyMCE.cssClasses) != "undefined") return tinyMCE.cssClasses; if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") { var instance; for (var instanceName in tinyMCE.instances) { instance = tinyMCE.instances[instanceName]; if (!tinyMCE.isInstance(instance)) continue; break; } doc = instance.getDoc(); } if (typeof(doc) == "undefined") { var instance = tinyMCE.getInstanceById(editor_id); doc = instance.getDoc(); } if (doc) { var styles = doc.styleSheets; if (styles && styles.length > 0) { for (var x=0; x 0) tinyMCE.cssClasses = output; return output; }, regexpReplace : function(in_str, reg_exp, replace_str, opts) { if (in_str == null) return in_str; if (typeof(opts) == "undefined") opts = 'g'; var re = new RegExp(reg_exp, opts); return in_str.replace(re, replace_str); }, trim : function(s) { return s.replace(/^\s*|\s*$/g, ""); }, cleanupEventStr : function(s) { s = "" + s; s = s.replace('function anonymous()\n{\n', ''); s = s.replace('\n}', ''); s = s.replace(/^return true;/gi, ''); // Remove event blocker return s; }, getControlHTML : function(c) { var i, l, n, o, v; l = tinyMCE.plugins; for (n in l) { o = l[n]; if (o.getControlHTML && (v = o.getControlHTML(c)) != '') return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); } o = tinyMCE.themes[tinyMCE.settings['theme']]; if (o.getControlHTML && (v = o.getControlHTML(c)) != '') return v; return ''; }, evalFunc : function(f, idx, a) { var s = '(', i; for (i=idx; i 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(o[n], 3, a)) == s && m > 0) return true; } return false; }, xmlEncode : function(s) { s = "" + s; s = s.replace(/&/g, '&'); s = s.replace(new RegExp('"', 'g'), '"'); s = s.replace(/\'/g, '''); // ' is not working in MSIE s = s.replace(//g, '>'); return s; }, extend : function(p, np) { var o = {}; o.parent = p; for (n in p) o[n] = p[n]; for (n in np) 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; } }, explode : function(d, s) { var ar = s.split(d), oar = new Array(), i; for (i = 0; i 0) { for (i=0; i 1 && tinyMCE.currentConfig != this.settings['index']) { tinyMCE.settings = this.settings; tinyMCE.currentConfig = this.settings['index']; } }, getBody : function() { return this.getDoc().body; }, getDoc : function() { return this.contentWindow.document; }, getWin : function() { return this.contentWindow; }, addShortcut : function(m, k, d, cmd, ui, va) { var n = typeof(k) == "number", ie = tinyMCE.isMSIE, c, sc, i; var 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 0) rng.pasteHTML('
' + rng.htmlText + "
"); tinyMCE.triggerNodeChange(); return; } } } switch (command) { case "mceRepaint": this.repaint(); return true; case "InsertUnorderedList": case "InsertOrderedList": var tag = (command == "InsertUnorderedList") ? "ul" : "ol"; if (tinyMCE.isSafari) this.execCommand("mceInsertContent", false, "<" + tag + ">
  •  
  • <" + tag + ">"); else this.getDoc().execCommand(command, user_interface, value); tinyMCE.triggerNodeChange(); break; case "Strikethrough": if (tinyMCE.isSafari) this.execCommand("mceInsertContent", false, "" + this.selection.getSelectedHTML() + ""); else 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 (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) value = value.replace(/[^a-z]/gi, ''); if (tinyMCE.isMSIE && 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.isMSIE) { 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 (var 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 "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.isMSIE) { // 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', '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, new Array(), 1); for (var 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 (var i=nodes.length-1; i>=0; i--) { var elm = nodes[i]; var 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 (var x=0; x 0) { value = tinyMCE.replaceVar(value, "selection", selectedText); tinyMCE.execCommand('mceInsertContent', false, value); } 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("SetStyleInfo", 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.getDoc().body.scrollLeft + this.getDoc().documentElement.scrollLeft; var scrollY = this.getDoc().body.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; 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; } } // Ugly hack in Opera due to non working "inserthtml" if (tinyMCE.isOpera && insertHTMLFailed) { this.getDoc().execCommand("insertimage", false, tinyMCE.uniqueURL); var ar = tinyMCE.getElementsByAttributeValue(this.getBody(), "img", "src", tinyMCE.uniqueURL); ar[0].outerHTML = value; return; } if (!tinyMCE.isMSIE) { 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 var el = document.createElement("div"); el.innerHTML = value; value = el.firstChild.nodeValue; value = doc.createTextNode(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(); 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 && this.settings.url_converter.length != 0 && /^(src|href|longdesc)$/.test(an)) av = eval(this.settings.url_converter + '(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) return " " + an + "=" + '"' + this.xmlEncode(av) + '"'; return ""; }, formatHTML : function(h) { var s = this.settings, p = '', i = 0, li = 0, o = '', l; 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 i, l, e, o = '', c; this._setupEntities(); // Will intialize lookup table switch (this.settings.entity_encoding) { case "raw": return tinyMCE.xmlEncode(s); case "named": for (i=0, l=s.length; i 127 || c == 60 || c == 62 || c == 38 || c == 39 || c == 34) o += '&#' + c + ";"; else o += String.fromCharCode(c); } return o; } return s; }, split : function(re, s) { var c = s.split(re); var i, l, o = new Array(); for (i=0, l=c.length; i 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); } }; TinyMCE_Engine.prototype.getOuterHTML = function(e) { if (tinyMCE.isMSIE) return e.outerHTML; var d = e.ownerDocument.createElement("body"); d.appendChild(e); return d.innerHTML; }; TinyMCE_Engine.prototype.setOuterHTML = function(e, h) { if (tinyMCE.isMSIE) { e.outerHTML = h; return; } var d = e.ownerDocument.createElement("body"); d.innerHTML = h; e.parentNode.replaceChild(d.firstChild, e); }; TinyMCE_Engine.prototype._getElementById = function(id, d) { var e, i, j, f; if (typeof(d) == "undefined") d = document; e = d.getElementById(id); if (!e) { f = d.forms; for (i=0; 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 (var i=0; i= strTok2.length || strTok1[i] != strTok2[i]) { breakPoint = i + 1; break; } } } if (strTok1.length < strTok2.length) { for (var i=0; i= strTok1.length || strTok1[i] != strTok2[i]) { breakPoint = i + 1; break; } } } if (breakPoint == 1) return targetURL.path; for (var i=0; i<(strTok1.length-(breakPoint-1)); i++) outPath += "../"; for (var i=breakPoint-1; i=0; i--) { if (baseURLParts[i].length == 0) continue; newBaseURLParts[newBaseURLParts.length] = baseURLParts[i]; } baseURLParts = newBaseURLParts.reverse(); // Merge relURLParts chunks var newRelURLParts = new Array(); var numBack = 0; for (var 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 var len = baseURLParts.length-numBack; var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/'); var 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); }; TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) { var prot = document.location.protocol; var host = document.location.hostname; var port = document.location.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 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#") return url; // Fix relative/Mozilla if (!tinyMCE.isMSIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/') return tinyMCE.settings['base_href'] + url; // Handle relative URLs if (on_save && tinyMCE.getParam('relative_urls')) { var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url); if (curl.charAt(0) == '/') curl = tinyMCE.settings['document_base_prefix'] + curl; var urlParts = tinyMCE.parseURL(curl); var 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')) { var urlParts = tinyMCE.parseURL(url); var 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')) { var start = "", portPart = ""; if (port != "") portPart = ":" + port; start = prot + "//" + host + portPart + "/"; if (url.indexOf(start) == 0) url = url.substring(start.length-1); } return url; }; TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) { // Convert all image URL:s to absolute URL var elms = body.getElementsByTagName("img"); for (var i=0; i bookmark.index) { try { rng.addElement(nl[bookmark.index]); } catch (ex) { // Might be thrown if the node no longer exists } } } else { rng = inst.getSel().createRange(); rng.moveToElementText(inst.getBody()); rng.collapse(true); rng.moveStart('character', bookmark.start); rng.moveEnd('character', bookmark.length); } rng.select(); win.scrollTo(bookmark.scrollX, bookmark.scrollY); return true; } if (tinyMCE.isGecko && bookmark.rng) { sel.removeAllRanges(); sel.addRange(bookmark.rng); win.scrollTo(bookmark.scrollX, bookmark.scrollY); return true; } if (tinyMCE.isGecko) { // try { rng = doc.createRange(); nl = doc.getElementsByTagName(bookmark.startTag); if (nl.length > bookmark.start) rng.setStart(nl[bookmark.start].childNodes[bookmark.startIndex], bookmark.startOffset); nl = doc.getElementsByTagName(bookmark.endTag); if (nl.length > bookmark.end) rng.setEnd(nl[bookmark.end].childNodes[bookmark.endIndex], bookmark.endOffset); sel.removeAllRanges(); sel.addRange(rng); /* } catch { // Ignore }*/ win.scrollTo(bookmark.scrollX, bookmark.scrollY); return true; } return false; }, 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 (tinyMCE.isMSIE) { rng = inst.getBody().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, new Array(), 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; var pos, doc, scrollX, scrollY, height; // Scroll to node position pos = tinyMCE.getAbsPosition(node); doc = inst.getDoc(); scrollX = doc.body.scrollLeft + doc.documentElement.scrollLeft; scrollY = doc.body.scrollTop + doc.documentElement.scrollTop; height = tinyMCE.isMSIE ? document.getElementById(inst.editorId).style.pixelHeight : inst.targetElement.clientHeight; // Only scroll if out of visible area if (!tinyMCE.settings['auto_resize'] && !(pos.absTop > scrollY && pos.absTop < (scrollY - 25 + height))) inst.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25); }, getSel : function() { var inst = this.instance; if (tinyMCE.isMSIE && !tinyMCE.isOpera) return inst.getDoc().selection; return inst.contentWindow.getSelection(); }, getRng : function() { var inst = this.instance; var sel = this.getSel(); if (sel == null) return null; if (tinyMCE.isMSIE && !tinyMCE.isOpera) return sel.createRange(); if (tinyMCE.isSafari && !sel.getRangeAt) return '' + window.getSelection(); return sel.getRangeAt(0); }, getFocusElement : function() { var inst = this.instance; if (tinyMCE.isMSIE && !tinyMCE.isOpera) { var doc = inst.getDoc(); var rng = doc.selection.createRange(); // if (rng.collapse) // rng.collapse(true); var elm = rng.item ? rng.item(0) : rng.parentElement(); } else { if (inst.isHidden()) return inst.getBody(); var sel = this.getSel(); var rng = this.getRng(); if (!sel || !rng) return null; var elm = rng.commonAncestorContainer; //var 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 = new Array(); this.undoIndex = 0; this.typingUndoIndex = -1; this.undoRedo = true; }; TinyMCE_UndoRedo.prototype = { add : function(l) { var b; if (l) { this.undoLevels[this.undoLevels.length] = l; return true; } var inst = this.instance; if (this.typingUndoIndex != -1) { this.undoIndex = this.typingUndoIndex; // tinyMCE.debug("Override: " + this.undoIndex); } var newHTML = tinyMCE.trim(inst.getBody().innerHTML); if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) { //tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex]); tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst); // Time to compress var customUndoLevels = tinyMCE.settings['custom_undo_redo_levels']; if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) { for (var 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); } // tinyMCE.debug("Undo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex); }, 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 (this.undoIndex > 0) // inst.selection.moveToBookmark(this.undoLevels[this.undoIndex-1].bookmark); if (inst.settings.custom_undo_redo_restore_selection) inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark); // tinyMCE.debug("Redo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex); } tinyMCE.triggerNodeChange(); } }; /* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */ var TinyMCE_ForceParagraphs = { _insertPara : function(inst, e) { function isEmpty(para) { 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 var nodes = tinyMCE.getNodeTree(para, new Array(), 3); for (var i=0; i <" + blockName + "> "; paraAfter = body.childNodes[1]; } 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); var contents = rngAfter.cloneContents(); if (contents.firstChild && contents.firstChild.nodeName == blockName) { /* var nodes = contents.firstChild.childNodes; for (var 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); } 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); var w = parseInt(re.offsetWidth); var h = parseInt(re.offsetHeight); var e = this.getElement(); var ew = parseInt(e.offsetWidth); var eh = parseInt(e.offsetHeight); var x, y; 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() { this.getElement().style.display = 'block'; this.updateBlocker(); }, hide : function() { this.getElement().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.createElement("iframe"); 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) { var d = this.doc, e = d.createElement(n); e.setAttribute('id', this.id); if (c) e.className = c; if (!p) p = d.body; p.appendChild(e); return this.element = e; }, parseInt : function(s) { if (s == null || s == '') return 0; return parseInt(s); } }; /* 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 = new Array(); this.needsUpdate = true; }; // Extends the TinyMCE_Layer class 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 = new Array(); }, 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_Engine.prototype.debug = function() { var m = "", e, a, i; e = document.getElementById("tinymce_debug"); if (!e) { var d = document.createElement("div"); d.setAttribute("className", "debugger"); d.className = "debugger"; d.innerHTML = 'Debug output:'; document.body.appendChild(d); e = document.getElementById("tinymce_debug"); } a = this.debug.arguments; for (i=0; i