/* * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com * * http://extjs.com/license */ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, { enableFormat : true, enableFontSize : true, enableColors : true, enableAlignments : true, enableLists : true, enableSourceEdit : true, enableLinks : true, enableFont : true, createLinkText : "Please enter the URL for the link:", defaultLinkValue : "http:/" + "/", fontFamilies : ["Arial", "Courier New", "Tahoma", "Times New Roman", "Verdana"], defaultFont : "tahoma", validationEvent : false, deferHeight : true, initialized : false, activated : false, sourceEditMode : false, onFocus : Ext.emptyFn, iframePad : 3, hideMode : "offsets", defaultAutoCreate : { tag : "textarea", style : "width:500px;height:300px;", autocomplete : "off" }, initComponent : function() { this.addEvents("initialize", "activate", "beforesync", "beforepush", "sync", "push", "editmodechange") }, createFontOptions : function() { var D = [], B = this.fontFamilies, C, F; for (var E = 0, A = B.length; E < A; E++) { C = B[E]; F = C.toLowerCase(); D.push("") } return D.join("") }, createToolbar : function(C) { function B(F, D, E) { return { itemId : F, cls : "x-btn-icon x-edit-" + F, enableToggle : D !== false, scope : C, handler : E || C.relayBtnCmd, clickEvent : "mousedown", tooltip : C.buttonTips[F] || undefined, tabIndex : -1 } } var A = new Ext.Toolbar({ renderTo : this.wrap.dom.firstChild }); A.el.on("click", function(D) { D.preventDefault() }); if (this.enableFont && !Ext.isSafari) { this.fontSelect = A.el.createChild({ tag : "select", cls : "x-font-select", html : this.createFontOptions() }); this.fontSelect.on("change", function() { var D = this.fontSelect.dom.value; this.relayCmd("fontname", D); this.deferFocus() }, this); A.add(this.fontSelect.dom, "-") } if (this.enableFormat) { A.add(B("bold"), B("italic"), B("underline")) } if (this.enableFontSize) { A.add("-", B("increasefontsize", false, this.adjustFont), B( "decreasefontsize", false, this.adjustFont)) } if (this.enableColors) { A.add("-", { itemId : "forecolor", cls : "x-btn-icon x-edit-forecolor", clickEvent : "mousedown", tooltip : C.buttonTips["forecolor"] || undefined, tabIndex : -1, menu : new Ext.menu.ColorMenu({ allowReselect : true, focus : Ext.emptyFn, value : "000000", plain : true, selectHandler : function(E, D) { this.execCmd("forecolor", Ext.isSafari || Ext.isIE ? "#" + D : D); this.deferFocus() }, scope : this, clickEvent : "mousedown" }) }, { itemId : "backcolor", cls : "x-btn-icon x-edit-backcolor", clickEvent : "mousedown", tooltip : C.buttonTips["backcolor"] || undefined, tabIndex : -1, menu : new Ext.menu.ColorMenu({ focus : Ext.emptyFn, value : "FFFFFF", plain : true, allowReselect : true, selectHandler : function(E, D) { if (Ext.isGecko) { this.execCmd("useCSS", false); this.execCmd("hilitecolor", D); this.execCmd("useCSS", true); this.deferFocus() } else { this.execCmd(Ext.isOpera ? "hilitecolor" : "backcolor", Ext.isSafari || Ext.isIE ? "#" + D : D); this.deferFocus() } }, scope : this, clickEvent : "mousedown" }) }) } if (this.enableAlignments) { A.add("-", B("justifyleft"), B("justifycenter"), B("justifyright")) } if (!Ext.isSafari) { if (this.enableLinks) { A.add("-", B("createlink", false, this.createLink)) } if (this.enableLists) { A.add("-", B("insertorderedlist"), B("insertunorderedlist")) } if (this.enableSourceEdit) { A.add("-", B("sourceedit", true, function(D) { this.toggleSourceEdit(D.pressed) })) } } this.tb = A }, getDocMarkup : function() { return "" }, getEditorBody : function() { return this.doc.body || this.doc.documentElement }, onRender : function(C, A) { Ext.form.HtmlEditor.superclass.onRender.call(this, C, A); this.el.dom.style.border = "0 none"; this.el.dom.setAttribute("tabIndex", -1); this.el.addClass("x-hidden"); if (Ext.isIE) { this.el.applyStyles("margin-top:-1px;margin-bottom:-1px;") } this.wrap = this.el.wrap({ cls : "x-html-editor-wrap", cn : { cls : "x-html-editor-tb" } }); this.createToolbar(this); this.tb.items.each(function(E) { if (E.itemId != "sourceedit") { E.disable() } }); var D = document.createElement("iframe"); D.name = Ext.id(); D.frameBorder = "no"; D.src = (Ext.SSL_SECURE_URL || "javascript:false"); this.wrap.dom.appendChild(D); this.iframe = D; if (Ext.isIE) { D.contentWindow.document.designMode = "on"; this.doc = D.contentWindow.document; this.win = D.contentWindow } else { this.doc = (D.contentDocument || window.frames[D.name].document); this.win = window.frames[D.name]; this.doc.designMode = "on" } this.doc.open(); this.doc.write(this.getDocMarkup()); this.doc.close(); var B = { run : function() { if (this.doc.body || this.doc.readyState == "complete") { Ext.TaskMgr.stop(B); this.doc.designMode = "on"; this.initEditor.defer(10, this) } }, interval : 10, duration : 10000, scope : this }; Ext.TaskMgr.start(B); if (!this.width) { this.setSize(this.el.getSize()) } }, onResize : function(B, C) { Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments); if (this.el && this.iframe) { if (typeof B == "number") { var D = B - this.wrap.getFrameWidth("lr"); this.el.setWidth(this.adjustWidth("textarea", D)); this.iframe.style.width = D + "px" } if (typeof C == "number") { var A = C - this.wrap.getFrameWidth("tb") - this.tb.el.getHeight(); this.el.setHeight(this.adjustWidth("textarea", A)); this.iframe.style.height = A + "px"; if (this.doc) { this.getEditorBody().style.height = (A - (this.iframePad * 2)) + "px" } } } }, toggleSourceEdit : function(A) { if (A === undefined) { A = !this.sourceEditMode } this.sourceEditMode = A === true; var C = this.tb.items.get("sourceedit"); if (C.pressed !== this.sourceEditMode) { C.toggle(this.sourceEditMode); return } if (this.sourceEditMode) { this.tb.items.each(function(D) { if (D.itemId != "sourceedit") { D.disable() } }); this.syncValue(); this.iframe.className = "x-hidden"; this.el.removeClass("x-hidden"); this.el.dom.removeAttribute("tabIndex"); this.el.focus() } else { if (this.initialized) { this.tb.items.each(function(D) { D.enable() }) } this.pushValue(); this.iframe.className = ""; this.el.addClass("x-hidden"); this.el.dom.setAttribute("tabIndex", -1); this.deferFocus() } var B = this.lastSize; if (B) { delete this.lastSize; this.setSize(B) } this.fireEvent("editmodechange", this, this.sourceEditMode) }, createLink : function() { var A = prompt(this.createLinkText, this.defaultLinkValue); if (A && A != "http:/" + "/") { this.relayCmd("createlink", A) } }, adjustSize : Ext.BoxComponent.prototype.adjustSize, getResizeEl : function() { return this.wrap }, getPositionEl : function() { return this.wrap }, initEvents : function() { this.originalValue = this.getValue() }, markInvalid : Ext.emptyFn, clearInvalid : Ext.emptyFn, setValue : function(A) { Ext.form.HtmlEditor.superclass.setValue.call(this, A); this.pushValue() }, cleanHtml : function(A) { A = String(A); if (A.length > 5) { if (Ext.isSafari) { A = A .replace( /\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, "") } } if (A == " ") { A = "" } return A }, syncValue : function() { if (this.initialized) { var D = this.getEditorBody(); var C = D.innerHTML; if (Ext.isSafari) { var B = D.getAttribute("style"); var A = B.match(/text-align:(.*?);/i); if (A && A[1]) { C = "
" + C + "
" } } C = this.cleanHtml(C); if (this.fireEvent("beforesync", this, C) !== false) { this.el.dom.value = C; this.fireEvent("sync", this, C) } } }, pushValue : function() { if (this.initialized) { var A = this.el.dom.value; if (!this.activated && A.length < 1) { A = " " } if (this.fireEvent("beforepush", this, A) !== false) { this.getEditorBody().innerHTML = A; this.fireEvent("push", this, A) } } }, deferFocus : function() { this.focus.defer(10, this) }, focus : function() { if (this.win && !this.sourceEditMode) { this.win.focus() } else { this.el.focus() } }, initEditor : function() { var B = this.getEditorBody(); var A = this.el.getStyles("font-size", "font-family", "background-image", "background-repeat"); A["background-attachment"] = "fixed"; B.bgProperties = "fixed"; Ext.DomHelper.applyStyles(B, A); Ext.EventManager.on(this.doc, { "mousedown" : this.onEditorEvent, "dblclick" : this.onEditorEvent, "click" : this.onEditorEvent, "keyup" : this.onEditorEvent, buffer : 100, scope : this }); if (Ext.isGecko) { Ext.EventManager.on(this.doc, "keypress", this.applyCommand, this) } if (Ext.isIE || Ext.isSafari || Ext.isOpera) { Ext.EventManager.on(this.doc, "keydown", this.fixKeys, this) } this.initialized = true; this.fireEvent("initialize", this); this.pushValue() }, onDestroy : function() { if (this.rendered) { this.tb.items.each(function(A) { if (A.menu) { A.menu.removeAll(); if (A.menu.el) { A.menu.el.destroy() } } A.destroy() }); this.wrap.dom.innerHTML = ""; this.wrap.remove() } }, onFirstFocus : function() { this.activated = true; this.tb.items.each(function(D) { D.enable() }); if (Ext.isGecko) { this.win.focus(); var A = this.win.getSelection(); if (!A.focusNode || A.focusNode.nodeType != 3) { var B = A.getRangeAt(0); B.selectNodeContents(this.getEditorBody()); B.collapse(true); this.deferFocus() } try { this.execCmd("useCSS", true); this.execCmd("styleWithCSS", false) } catch (C) { } } this.fireEvent("activate", this) }, adjustFont : function(B) { var C = B.itemId == "increasefontsize" ? 1 : -1; if (Ext.isSafari) { C *= 2 } var A = parseInt(this.doc.queryCommandValue("FontSize") || 3, 10); A = Math.max(1, A + C); this.execCmd("FontSize", A + (Ext.isSafari ? "px" : 0)) }, onEditorEvent : function(A) { this.updateToolbar() }, updateToolbar : function() { if (!this.activated) { this.onFirstFocus(); return } var B = this.tb.items.map, C = this.doc; if (this.enableFont && !Ext.isSafari) { var A = (this.doc.queryCommandValue("FontName") || this.defaultFont) .toLowerCase(); if (A != this.fontSelect.dom.value) { this.fontSelect.dom.value = A } } if (this.enableFormat) { B.bold.toggle(C.queryCommandState("bold")); B.italic.toggle(C.queryCommandState("italic")); B.underline.toggle(C.queryCommandState("underline")) } if (this.enableAlignments) { B.justifyleft.toggle(C.queryCommandState("justifyleft")); B.justifycenter.toggle(C.queryCommandState("justifycenter")); B.justifyright.toggle(C.queryCommandState("justifyright")) } if (!Ext.isSafari && this.enableLists) { B.insertorderedlist .toggle(C.queryCommandState("insertorderedlist")); B.insertunorderedlist.toggle(C .queryCommandState("insertunorderedlist")) } Ext.menu.MenuMgr.hideAll(); this.syncValue() }, relayBtnCmd : function(A) { this.relayCmd(A.itemId) }, relayCmd : function(B, A) { this.win.focus(); this.execCmd(B, A); this.updateToolbar(); this.deferFocus() }, execCmd : function(B, A) { this.doc.execCommand(B, false, A === undefined ? null : A); this.syncValue() }, applyCommand : function(B) { if (B.ctrlKey) { var C = B.getCharCode(), A; if (C > 0) { C = String.fromCharCode(C); switch (C) { case "b" : A = "bold"; break; case "i" : A = "italic"; break; case "u" : A = "underline"; break } if (A) { this.win.focus(); this.execCmd(A); this.deferFocus(); B.preventDefault() } } } }, insertAtCursor : function(B) { if (!this.activated) { return } if (Ext.isIE) { this.win.focus(); var A = this.doc.selection.createRange(); if (A) { A.collapse(true); A.pasteHTML(B); this.syncValue(); this.deferFocus() } } else { if (Ext.isGecko || Ext.isOpera) { this.win.focus(); this.execCmd("InsertHTML", B); this.deferFocus() } else { if (Ext.isSafari) { this.execCmd("InsertText", B); this.deferFocus() } } } }, fixKeys : function() { if (Ext.isIE) { return function(D) { var A = D.getKey(), B; if (A == D.TAB) { D.stopEvent(); B = this.doc.selection.createRange(); if (B) { B.collapse(true); B.pasteHTML("    "); this.deferFocus() } } else { if (A == D.ENTER) { B = this.doc.selection.createRange(); if (B) { var C = B.parentElement(); if (!C || C.tagName.toLowerCase() != "li") { D.stopEvent(); B.pasteHTML("
"); B.collapse(false); B.select() } } } } } } else { if (Ext.isOpera) { return function(B) { var A = B.getKey(); if (A == B.TAB) { B.stopEvent(); this.win.focus(); this.execCmd("InsertHTML", "    "); this.deferFocus() } } } else { if (Ext.isSafari) { return function(B) { var A = B.getKey(); if (A == B.TAB) { B.stopEvent(); this.execCmd("InsertText", "\t"); this.deferFocus() } } } } } }(), getToolbar : function() { return this.tb }, buttonTips : { bold : { title : "Bold (Ctrl+B)", text : "Make the selected text bold.", cls : "x-html-editor-tip" }, italic : { title : "Italic (Ctrl+I)", text : "Make the selected text italic.", cls : "x-html-editor-tip" }, underline : { title : "Underline (Ctrl+U)", text : "Underline the selected text.", cls : "x-html-editor-tip" }, increasefontsize : { title : "Grow Text", text : "Increase the font size.", cls : "x-html-editor-tip" }, decreasefontsize : { title : "Shrink Text", text : "Decrease the font size.", cls : "x-html-editor-tip" }, backcolor : { title : "Text Highlight Color", text : "Change the background color of the selected text.", cls : "x-html-editor-tip" }, forecolor : { title : "Font Color", text : "Change the color of the selected text.", cls : "x-html-editor-tip" }, justifyleft : { title : "Align Text Left", text : "Align text to the left.", cls : "x-html-editor-tip" }, justifycenter : { title : "Center Text", text : "Center text in the editor.", cls : "x-html-editor-tip" }, justifyright : { title : "Align Text Right", text : "Align text to the right.", cls : "x-html-editor-tip" }, insertunorderedlist : { title : "Bullet List", text : "Start a bulleted list.", cls : "x-html-editor-tip" }, insertorderedlist : { title : "Numbered List", text : "Start a numbered list.", cls : "x-html-editor-tip" }, createlink : { title : "Hyperlink", text : "Make the selected text a hyperlink.", cls : "x-html-editor-tip" }, sourceedit : { title : "Source Edit", text : "Switch to source editing mode.", cls : "x-html-editor-tip" } } }); Ext.reg("htmleditor", Ext.form.HtmlEditor);