/* This class converts a textarea to a simple WYSIWYG editor */ Editor_class = function(textarea, id) { this.textarea = textarea; this.iframe = null; this.iframeId = "editor_" + id; this.enabled = true; this.isIE = document.all ? true : false; this.init(); } Editor_class.prototype.init = function() { if (!this.enabled) { return; } this.iframe = WSDOM.Element.create("iframe", { src: "../resources/js/editor/editorbody.htm", className: "editableContent", id: this.iframeId, 'WSDOM.Events': { type:"load", context:this, handler:this.setContent } }); WSDOM.Element.insertBefore(this.iframe, this.textarea); this.toggleTextarea(false); this.toolbar = WSDOM.Element.create("div",{className:"contentToolbar"},[ WSDOM.Element.create("a",{href:"javascript:void(0);",className:"toolbarBold",'WSDOM.Events':{type:"click",context:this,handler:this.toolbarAction,data:"B"}},"B") ,WSDOM.Element.create("a",{href:"javascript:void(0);",className:"toolbarItalic",'WSDOM.Events':{type:"click",context:this,handler:this.toolbarAction,data:"I"}},"I") ,WSDOM.Element.create("a",{href:"javascript:void(0);",className:"toolbarUnderline",'WSDOM.Events':{type:"click",context:this,handler:this.toolbarAction,data:"U"}},"U") ,WSDOM.Element.create("a",{href:"javascript:void(0);",className:"toolbarList",'WSDOM.Events':{type:"click",context:this,handler:this.toolbarAction,data:"L"}}," ") ,WSDOM.Element.create("a",{href:"javascript:void(0);",className:"toolbarLink",'WSDOM.Events':{type:"click",context:this,handler:this.toolbarAction,data:"SYMBOL"}},"L") ,WSDOM.Element.create("div",{className:"clear"}) ]); WSDOM.Element.insertBefore(this.toolbar,this.iframe); } Editor_class.prototype.setContent = function(e,el,data) { if(!this.enabled) { return; } var raw = WSDOM.Element.create('div'); raw.innerHTML = this.textarea.value; var normalized = normalizeNode(raw, null, (this.isIE ? 'IE' : 'FF')); this.editFrameDocument = this.iframe.contentWindow.document; this.editFrameDocument.body.innerHTML = normalized.innerHTML; try { if(!this.isIE) { this.editFrameDocument.designMode = "on"; } } catch(e) { console.log(e); } } function normalizeNode(node, container, type) { type = type || "IE"; // FF or IE var hadContainer = Boolean(container); var currentContainer = null; if(!hadContainer) container = WSDOM.Element.create('div'); var getAttributes = function(el) { var res = {}; for(var i = 0; i < el.attributes.length; i++) { if(el.attributes[i].specified && el.attributes[i].nodeName.substring(0, 1) != "_"){ res[el.attributes[i].nodeName] = el.attributes[i].nodeValue; } } return res; }; var append = function(el){ if(hadContainer) { container.appendChild(el); } else { if(!currentContainer) { currentContainer = WSDOM.Element.create('p'); container.appendChild(currentContainer); } currentContainer.appendChild(el); } }; var appendTextNode = function(text) { var el = document.createTextNode(text); append(el); }; var appendSpanNode = function(nd, style) { var el = WSDOM.Element.create('span', { 'style': (style.split ? style : '') }); append(el); normalizeNode(nd, el, type); }; var appendInlineElement = function(nd) { var el = WSDOM.Element.create(nd.tagName, getAttributes(nd)); append(el); normalizeNode(nd, el, type); }; var appendElement = function(nd) { var el = WSDOM.Element.create(nd.tagName, getAttributes(nd)); container.appendChild(el); normalizeNode(nd, el, type); }; var nd; for(var i = 0, len = node.childNodes.length; i < len; i++) { nd = node.childNodes[i]; if(nd.nodeType == 3) { //Text nodes appendTextNode(nd.nodeValue); } else { // Element nodes if(type== "FF") { // FF uses spans for bold, italic and underline switch(nd.tagName.toLowerCase()) { case 'em': appendSpanNode(nd, 'font-style:italic;'); break; case 'strong': appendSpanNode(nd, 'font-weight:bold;'); break; case 'u': appendSpanNode(nd, 'text-decoration:underline;'); break; case 'span': if(!nd.getAttribute('style')) { normalizeNode(nd, container, type); break; } appendInlineElement(nd); break; case 'p': if(!currentContainer) currentContainer = container; normalizeNode(nd, container, type); container.appendChild(WSDOM.Element.create('br')); break; default: // We don't want to alter any other elements currentContainer = null; appendElement(nd); } } else { // IE uses strong, em and u for bold, italic and underline switch(nd.tagName.toLowerCase()) { case 'a': case 'em': case 'strong': case 'u': appendInlineElement(nd); break; case 'span': var styles = nd.getAttribute('style'); if(typeof styles == 'object') styles = styles.cssText; if(!styles || !styles.replace) { normalizeNode(nd, container, type); break; } styles = styles.replace(/\s/g, '').toLowerCase().split(";"); var firstEl = null; var lastEl = null; var newEl = null; for(var j = 0; j < styles.length; j++) { switch(styles[j]) { case 'font-weight:bold': if(firstEl) { newEl = WSDOM.Element.create('strong'); lastEl.appendChild(newEl); lastEl = newEl; } else { firstEl = WSDOM.Element.create('strong'); lastEl = firstEl; } break; case 'font-style:italic': if(firstEl) { newEl = WSDOM.Element.create('em'); lastEl.appendChild(newEl); lastEl = newEl; } else { firstEl = WSDOM.Element.create('em'); lastEl = firstEl; } break; case 'text-decoration:underline': if(firstEl) { newEl = WSDOM.Element.create('u'); lastEl.appendChild(newEl); lastEl = newEl; } else { firstEl = WSDOM.Element.create('u'); lastEl = firstEl; } break; } } if(firstEl) { normalizeNode(nd, lastEl, type); appendInlineElement(firstEl); } break; case 'br': // Don't append
s currentContainer = null; break; default: // We don't want to alter any other elements currentContainer = null; appendElement(nd); } } } } return container; } Editor_class.prototype.getContent = function(e,el,data) { if (!this.enabled) { return; } var result = normalizeNode(this.editFrameDocument.body); var value = (result ? result.innerHTML : ''); this.textarea.value = value; return value; } Editor_class.prototype.toolbarAction = function(e,el,data) { var actionMap = { B:"Bold" ,I:"Italic" ,U:"Underline" ,L:"InsertUnorderedList" } var sText = this.isIE?this.editFrameDocument.selection.createRange():this.editFrameDocument.getSelection(); var selectedText = sText.text; if (!selectedText) { //return; } var parentElement = (this.isIE)?sText.parentElement():sText.parentNode; if (actionMap[data]) { this.editFrameDocument.execCommand(actionMap[data], false, false); } else if (data == "SYMBOL") { var href = "http://www.example.com"; if (parentElement && parentElement.tagName == "A") { href = parentElement.getAttribute("HREF") || ""; } href = prompt("Specify URL",href); if (href == "") { this.editFrameDocument.execCommand("unLink", false, false); } else if (href) { this.editFrameDocument.execCommand("createLink", false, href); } } this.iframe.contentWindow.focus(); } Editor_class.prototype.toggleTextarea = function(visible) { // hide or show the textarea WSDOM.Element.switchClass(this.textarea,"none",!visible); }