📄 richtext.js
字号:
}else if((dojo.render.html.ie)&&( (command == "backcolor")||(command == "forecolor") )){ // Tested under IE 6 XP2, no problem here, comment out // IE weirdly collapses ranges when we exec these commands, so prevent it// var tr = this.document.selection.createRange(); argument = arguments.length > 1 ? argument : null; returnValue = this.document.execCommand(command, false, argument); // timeout is workaround for weird IE behavior were the text // selection gets correctly re-created, but subsequent input // apparently isn't bound to it// setTimeout(function(){tr.select();}, 1); }else{ // dojo.debug("command:", command, "arg:", argument); argument = arguments.length > 1 ? argument : null;// if(dojo.render.html.moz){// this.document = this.iframe.contentWindow.document// } if(argument || command!="createlink") { returnValue = this.document.execCommand(command, false, argument); } } this.onDisplayChanged(); return returnValue; }, queryCommandEnabled: function(/*String*/command){ // summary: check whether a command is enabled or not command = this._normalizeCommand(command); if(this.object){ switch (command) { case "hilitecolor": command = "setbackcolor"; break; case "forecolor": case "backcolor": case "fontsize": case "fontname": command = "set" + command; break; case "formatblock": command = "setblockformat"; break; //below are not natively supported commands, we fake them case "strikethrough": command = "bold"; //whenever bold is enabled, strikethrough should be so as well break; case "inserthorizontalrule": return true; } if(typeof this._activeX.command[command] == "undefined"){ return false; } var status = this.object.QueryStatus(this._activeX.command[command]); return ((status != this._activeX.status.notsupported)&& (status != this._activeX.status.disabled)); }else{ if(dojo.render.html.mozilla){ if(command == "unlink"){ // mozilla returns true always return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['a']); } else if (command == "inserttable") { return true; } } // return this.document.queryCommandEnabled(command); var elem = (dojo.render.html.ie) ? this.document.selection.createRange() : this.document; return elem.queryCommandEnabled(command); } }, queryCommandState: function(command){ // summary: check the state of a given command command = this._normalizeCommand(command); if(this.object){ if(command == "forecolor"){ command = "setforecolor"; }else if(command == "backcolor"){ command = "setbackcolor"; }else if(command == "strikethrough"){ //check whether we are under a <strike> return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['strike']); }else if(command == "inserthorizontalrule"){ return false; } if(typeof this._activeX.command[command] == "undefined"){ return null; } var status = this.object.QueryStatus(this._activeX.command[command]); return ((status == this._activeX.status.latched)|| (status == this._activeX.status.ninched)); }else{ return this.document.queryCommandState(command); } }, queryCommandValue: function (command) { // summary: check the value of a given command command = this._normalizeCommand(command); if (this.object) { switch (command) { case "forecolor": case "backcolor": case "fontsize": case "fontname": command = "get" + command; return this.object.execCommand( this._activeX.command[command], this._activeX.ui.noprompt); case "formatblock": var retvalue = this.object.execCommand( this._activeX.command["getblockformat"], this._activeX.ui.noprompt); if(retvalue){ return this._local2NativeFormatNames[retvalue]; } } } else { if(dojo.render.html.ie && command == "formatblock"){ return this._local2NativeFormatNames[this.document.queryCommandValue(command)] || this.document.queryCommandValue(command); } return this.document.queryCommandValue(command); } }, /* Misc. ********/ placeCursorAtStart: function(){ // summary: // place the cursor at the start of the editing area this.focus(); //see comments in placeCursorAtEnd if(dojo.render.html.moz && this.editNode.firstChild && this.editNode.firstChild.nodeType != dojo.dom.TEXT_NODE){ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.firstChild]); }else{ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]); } dojo.withGlobal(this.window, "collapse", dojo.html.selection, [true]); }, placeCursorAtEnd: function(){ // summary: // place the cursor at the end of the editing area this.focus(); //In mozilla, if last child is not a text node, we have to use selectElementChildren on this.editNode.lastChild //otherwise the cursor would be placed at the end of the closing tag of this.editNode.lastChild if(dojo.render.html.moz && this.editNode.lastChild && this.editNode.lastChild.nodeType != dojo.dom.TEXT_NODE){ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.lastChild]); }else{ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]); } dojo.withGlobal(this.window, "collapse", dojo.html.selection, [false]); }, replaceEditorContent: function(/*String*/html){ // summary: // this function set the content while trying to maintain the undo stack html = this._preFilterContent(html); if(this.isClosed){ this.domNode.innerHTML = html; }else if(this.window && this.window.getSelection && !dojo.render.html.moz){ // Safari // look ma! it's a totally f'd browser! this.editNode.innerHTML = html; }else if((this.window && this.window.getSelection) || (this.document && this.document.selection)){ // Moz/IE this.execCommand("selectall"); this.execCommand("inserthtml", html); } }, _preFilterContent: function(/*String*/html){ // summary: // filter the input before setting the content of the editing area var ec = html; dojo.lang.forEach(this.contentPreFilters, function(ef){ ec = ef(ec); }); if(this.contentDomPreFilters.length>0){ var dom = dojo.doc().createElement('div'); dom.style.display = "none"; dojo.body().appendChild(dom); dom.innerHTML = ec; dojo.lang.forEach(this.contentDomPreFilters, function(ef){ dom = ef(dom); }); ec = dom.innerHTML; dojo.body().removeChild(dom); } return ec; }, _postFilterContent: function(/*String*/html){ // summary: // filter the output after getting the content of the editing area var ec = html; if(this.contentDomPostFilters.length>0){ var dom = this.document.createElement('div'); dom.innerHTML = ec; dojo.lang.forEach(this.contentDomPostFilters, function(ef){ dom = ef(dom); }); ec = dom.innerHTML; } dojo.lang.forEach(this.contentPostFilters, function(ef){ ec = ef(ec); }); return ec; }, //Int: stored last time height _lastHeight: 0, _updateHeight: function(){ // summary: // Updates the height of the editor area to fit the contents. if(!this.isLoaded){ return; } if(this.height){ return; } var height = dojo.html.getBorderBox(this.editNode).height; //height maybe zero in some cases even though the content is not empty, //we try the height of body instead if(!height){ height = dojo.html.getBorderBox(this.document.body).height; } if(height == 0){ dojo.debug("Can not figure out the height of the editing area!"); return; //prevent setting height to 0 } this._lastHeight = height; this.editorObject.style.height = this._lastHeight + "px"; this.window.scrollTo(0, 0); }, _saveContent: function(e){ // summary: // Saves the content in an onunload event if the editor has not been closed var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent"); saveTextarea.value += this._SEPARATOR + this.saveName + ":" + this.getEditorContent(); }, getEditorContent: function(){ // summary: // return the current content of the editing area (post filters are applied) var ec = ""; try{ ec = (this._content.length > 0) ? this._content : this.editNode.innerHTML; if(dojo.string.trim(ec) == " "){ ec = ""; } }catch(e){ /* squelch */ } if(dojo.render.html.ie && !this.object){ //removing appended <P> </P> for IE in none-activeX mode var re = new RegExp("(?:<p> </p>[\n\r]*)+$", "i"); ec = ec.replace(re,""); } ec = this._postFilterContent(ec); if (this.relativeImageUrls) { // why use a regexp instead of dom? because IE is stupid // and won't let us set img.src to a relative URL // this comes after contentPostFilters because once content // gets innerHTML'd img urls will be fully qualified var siteBase = dojo.global().location.protocol + "//" + dojo.global().location.host; var pathBase = dojo.global().location.pathname; if (pathBase.match(/\/$/)) { // ends with slash, match full path } else { // match parent path to find siblings var pathParts = pathBase.split("/"); if (pathParts.length) { pathParts.pop(); } pathBase = pathParts.join("/") + "/"; } var sameSite = new RegExp("(<img[^>]*\ src=[\"'])("+siteBase+"("+pathBase+")?)", "ig"); ec = ec.replace(sameSite, "$1"); } return ec; }, close: function(/*Boolean*/save, /*Boolean*/force){ // summery: // Kills the editor and optionally writes back the modified contents to the // element from which it originated. // save: // Whether or not to save the changes. If false, the changes are discarded. // force: if(this.isClosed){return false; } if (arguments.length == 0) { save = true; } this._content = this._postFilterContent(this.editNode.innerHTML); var changed = (this.savedContent.innerHTML != this._content); // line height is squashed for iframes // FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; } if(this.interval){ clearInterval(this.interval); } if(dojo.render.html.ie && !this.object){ dojo.event.browser.clean(this.editNode); } if (this.iframe) { // FIXME: should keep iframe around for later re-use delete this.iframe; } if(this.textarea){ with(this.textarea.style){ position = ""; left = top = ""; if(dojo.render.html.ie){ overflow = this.__overflow; this.__overflow = null; } } this.domNode.parentNode.removeChild(this.domNode); this.domNode = this.textarea; }else{ this.domNode.innerHTML = ""; } if(save){ // kill listeners on the saved content dojo.event.browser.clean(this.savedContent); if(dojo.render.html.moz){ var nc = dojo.doc().createElement("span"); this.domNode.appendChild(nc); nc.innerHTML = this.editNode.innerHTML; }else{ this.domNode.innerHTML = this._content; } } else { while (this.savedContent.hasChildNodes()) { this.domNode.appendChild(this.savedContent.firstChild); } } delete this.savedContent; dojo.html.removeClass(this.domNode, "RichTextEditable"); this.isClosed = true; this.isLoaded = false; // FIXME: is this always the right thing to do? delete this.editNode; if(this.window._frameElement){ this.window._frameElement = null; } this.window = null; this.document = null; this.object = null; this.editingArea = null; this.editorObject = null; return changed; // Boolean: whether the content has been modified }, destroyRendering: function(){}, // stub! destroy: function (){ this.destroyRendering(); if(!this.isClosed){ this.close(false); } dojo.widget.RichText.superclass.destroy.call(this); }, connect: function (targetObj, targetFunc, thisFunc) { // summary: convenient method for dojo.event.connect dojo.event.connect(targetObj, targetFunc, this, thisFunc); }, disconnect: function (targetObj, targetFunc, thisFunc) { // summary: convenient method for dojo.event.disconnect dojo.event.disconnect(targetObj, targetFunc, this, thisFunc); }, disconnectAllWithRoot: function (targetObj) { dojo.deprecated("disconnectAllWithRoot", "is deprecated. No need to disconnect manually", "0.5"); }, _fixContentForMoz: function(html){ // summary: // Moz can not handle strong/em tags correctly, correct them here html = html.replace(/<strong([ \>])/gi, '<b$1' ); html = html.replace(/<\/strong>/gi, '<\/b>' ); html = html.replace(/<em([ \>])/gi, '<i$1' ); html = html.replace(/<\/em>/gi, '<\/i>' ); return html; } }, "html", function(){ // summary: // Constructor for this widget, initialize per-instance variables // Array: pre content filter function register array this.contentPreFilters = []; // Array: post content filter function register array this.contentPostFilters = []; // Array: pre content dom filter function register array this.contentDomPreFilters = []; // Array: post content dom filter function register array this.contentDomPostFilters = []; // String: semicolon (";") separated list of css files for the editing area this.styleSheets = ""; // Array: array to store all the stylesheets applied to the editing area this.editingAreaStyleSheets=[]; if(dojo.render.html.moz){ this.contentPreFilters.push(this._fixContentForMoz); } this._keyHandlers = {}; });
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -