📄 richtext.js
字号:
onKeyPress: function(e){ // summary: Fired on keypress if((!e)&&(this.object)){ e = dojo.event.browser.fixEvent(this.window.event); } // handle the various key events var modifiers = e.ctrlKey ? this.KEY_CTRL : 0; if (this._keyHandlers[e.key]) { // dojo.debug("char:", e.key); var handlers = this._keyHandlers[e.key], i = 0, handler; while (handler = handlers[i++]) { if (modifiers == handler.modifiers) { handler.handler.call(this); e.preventDefault(); break; } } } // function call after the character has been inserted dojo.lang.setTimeout(this, this.onKeyPressed, 1, e); }, addKeyHandler: function (/*String*/key, /*Int*/modifiers, /*Function*/handler) { // summary: add a handler for a keyboard shortcut if (!(this._keyHandlers[key] instanceof Array)) { this._keyHandlers[key] = []; } this._keyHandlers[key].push({ modifiers: modifiers || 0, handler: handler }); }, onKeyPressed: function (e) { // summary: // Fired after a keypress event has occured and it's action taken. This // is useful if action needs to be taken after text operations have finished // Mozilla adds a single <p> with an embedded <br> when you hit enter once: // <p><br>\n</p> // when you hit enter again it adds another <br> inside your enter // <p><br>\n<br>\n</p> // and if you hit enter again it splits the <br>s over 2 <p>s // <p><br>\n</p>\n<p><br>\n</p> // now this assumes that <p>s have double the line-height of <br>s to work // and so we need to remove the <p>s to ensure the position of the cursor // changes from the users perspective when they hit enter, as the second two // html snippets render the same when margins are set to 0. // TODO: doesn't really work; is this really needed? //if (dojo.render.html.moz) { // for (var i = 0; i < this.document.getElementsByTagName("p").length; i++) { // var p = this.document.getElementsByTagName("p")[i]; // if (p.innerHTML.match(/^<br>\s$/m)) { // while (p.hasChildNodes()) { p.parentNode.insertBefore(p.firstChild, p); } // p.parentNode.removeChild(p); // } // } //} this.onDisplayChanged(/*e*/); // can't pass in e }, onClick: function(e){ this.onDisplayChanged(e); }, onBlur: function(e){ }, _initialFocus: true, onFocus: function(e){ // summary: Fired on focus if( (dojo.render.html.mozilla)&&(this._initialFocus) ){ this._initialFocus = false; if(dojo.string.trim(this.editNode.innerHTML) == " "){ this.placeCursorAtStart();// this.execCommand("selectall");// this.window.getSelection().collapseToStart(); } } }, blur: function () { // summary: remove focus from this instance if(this.iframe) { this.window.blur(); } else if(this.object) { this.document.body.blur(); } else if(this.editNode) { this.editNode.blur(); } }, focus: function () { // summary: move focus to this instance if(this.iframe && !dojo.render.html.ie) { this.window.focus(); } else if(this.object) { this.document.focus(); } // editNode may be hidden in display:none div, lets just punt in this case else if(this.editNode && this.editNode.focus) { this.editNode.focus(); } else{ dojo.debug("Have no idea how to focus into the editor!"); } }, /** this event will be fired everytime the display context changes and the result needs to be reflected in the UI */ onDisplayChanged: function (e){ }, /* Formatting commands **********************/ // Object: IE's Active X codes: see http://www.computerbytesman.com/js/activex/dhtmledit.htm _activeX: { command: { bold: 5000, italic: 5023, underline: 5048, justifycenter: 5024, justifyleft: 5025, justifyright: 5026, cut: 5003, copy: 5002, paste: 5032, "delete": 5004, undo: 5049, redo: 5033, removeformat: 5034, selectall: 5035, unlink: 5050, indent: 5018, outdent: 5031, insertorderedlist: 5030, insertunorderedlist: 5051, // table commands inserttable: 5022, insertcell: 5019, insertcol: 5020, insertrow: 5021, deletecells: 5005, deletecols: 5006, deleterows: 5007, mergecells: 5029, splitcell: 5047, // the command need mapping, they don't translate directly // to the contentEditable commands setblockformat: 5043, getblockformat: 5011, getblockformatnames: 5012, setfontname: 5044, getfontname: 5013, setfontsize: 5045, getfontsize: 5014, setbackcolor: 5042, getbackcolor: 5010, setforecolor: 5046, getforecolor: 5015, findtext: 5008, font: 5009, hyperlink: 5016, image: 5017, lockelement: 5027, makeabsolute: 5028, sendbackward: 5036, bringforward: 5037, sendbelowtext: 5038, bringabovetext: 5039, sendtoback: 5040, bringtofront: 5041, properties: 5052 }, ui: { "default": 0, prompt: 1, noprompt: 2 }, status: { notsupported: 0, disabled: 1, enabled: 3, latched: 7, ninched: 11 }, appearance: { flat: 0, inset: 1 }, state: { unchecked: 0, checked: 1, gray: 2 } }, _normalizeCommand: function (/*String*/cmd){ // summary: // Used as the advice function by dojo.event.connect to map our // normalized set of commands to those supported by the target // browser var drh = dojo.render.html; var command = cmd.toLowerCase(); if(command == "formatblock"){ if(drh.safari){ command = "heading"; } }else if(this.object){ switch(command){ case "createlink": command = "hyperlink"; break; case "insertimage": command = "image"; break; } }else if(command == "hilitecolor" && !drh.mozilla){ command = "backcolor"; } return command; }, queryCommandAvailable: function (/*String*/command) { // summary: // Tests whether a command is supported by the host. Clients SHOULD check // whether a command is supported before attempting to use it, behaviour // for unsupported commands is undefined. // command: The command to test for var ie = 1; var mozilla = 1 << 1; var safari = 1 << 2; var opera = 1 << 3; var safari420 = 1 << 4; var gt420 = false; if(dojo.render.html.safari){ var tmp = dojo.render.html.UA.split("AppleWebKit/")[1]; var ver = parseFloat(tmp.split(" ")[0]); if(ver >= 420){ gt420 = true; } } function isSupportedBy (browsers) { return { ie: Boolean(browsers & ie), mozilla: Boolean(browsers & mozilla), safari: Boolean(browsers & safari), safari420: Boolean(browsers & safari420), opera: Boolean(browsers & opera) } } var supportedBy = null; switch (command.toLowerCase()) { case "bold": case "italic": case "underline": case "subscript": case "superscript": case "fontname": case "fontsize": case "forecolor": case "hilitecolor": case "justifycenter": case "justifyfull": case "justifyleft": case "justifyright": case "delete": case "selectall": supportedBy = isSupportedBy(mozilla | ie | safari | opera); break; case "createlink": case "unlink": case "removeformat": case "inserthorizontalrule": case "insertimage": case "insertorderedlist": case "insertunorderedlist": case "indent": case "outdent": case "formatblock": case "inserthtml": case "undo": case "redo": case "strikethrough": supportedBy = isSupportedBy(mozilla | ie | opera | safari420); break; case "blockdirltr": case "blockdirrtl": case "dirltr": case "dirrtl": case "inlinedirltr": case "inlinedirrtl": supportedBy = isSupportedBy(ie); break; case "cut": case "copy": case "paste": supportedBy = isSupportedBy( ie | mozilla | safari420); break; case "inserttable": supportedBy = isSupportedBy(mozilla | (this.object ? ie : 0)); break; case "insertcell": case "insertcol": case "insertrow": case "deletecells": case "deletecols": case "deleterows": case "mergecells": case "splitcell": supportedBy = isSupportedBy(this.object ? ie : 0); break; default: return false; } return (dojo.render.html.ie && supportedBy.ie) || (dojo.render.html.mozilla && supportedBy.mozilla) || (dojo.render.html.safari && supportedBy.safari) || (gt420 && supportedBy.safari420) || (dojo.render.html.opera && supportedBy.opera); // Boolean: return true if the command is supported, false otherwise }, execCommand: function (/*String*/command, argument){ // summary: Executes a command in the Rich Text area // command: The command to execute // argument: An optional argument to the command var returnValue; //focus() is required for IE (none-activeX mode) to work //In addition, focus() makes sure after the execution of //the command, the editor receives the focus as expected this.focus(); command = this._normalizeCommand(command); if (argument != undefined) { if(command == "heading") { throw new Error("unimplemented"); } else if(command == "formatblock"){ if(this.object){ //IE activeX mode argument = this._native2LocalFormatNames[argument]; } else if(drh.ie){ argument = '<'+argument+'>'; } } } 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"; } if(command == "strikethrough"){ command = "inserthtml"; var range = this.document.selection.createRange(); if(!range.htmlText){ return; } argument=range.htmlText.strike(); }else if(command == "inserthorizontalrule"){ command = "inserthtml"; argument="<hr>"; } if(command == "inserthtml"){ var range = this.document.selection.createRange(); if(this.document.selection.type.toUpperCase() == "CONTROL"){ //if selection is controlrange, no pasteHTML is available, //we replace the outerHTML directly for(var i=0;i<range.length;i++){ range.item(i).outerHTML = argument; } }else{ // on IE, we can use the pasteHTML method of the textRange object // to get an undo-able innerHTML modification range.pasteHTML(argument); range.select(); } returnValue = true; }else if(arguments.length == 1){ returnValue = this.object.ExecCommand(this._activeX.command[command], this._activeX.ui.noprompt); }else{ returnValue = this.object.ExecCommand(this._activeX.command[command], this._activeX.ui.noprompt, argument); } }else if(command == "inserthtml"){ if(dojo.render.html.ie){ //dojo.debug("inserthtml breaks the undo stack when not using the ActiveX version of the control!"); var insertRange = this.document.selection.createRange(); insertRange.pasteHTML(argument); insertRange.select(); //insertRange.collapse(true); return true; }else{ return this.document.execCommand(command, false, argument); } /* */ // fix up unlink in Mozilla to unlink the link and not just the selection }else if((command == "unlink")&& (this.queryCommandEnabled("unlink"))&& (dojo.render.html.mozilla)){ // grab selection // Mozilla gets upset if we just store the range so we have to // get the basic properties and recreate to save the selection var selection = this.window.getSelection(); var selectionRange = selection.getRangeAt(0); var selectionStartContainer = selectionRange.startContainer; var selectionStartOffset = selectionRange.startOffset; var selectionEndContainer = selectionRange.endContainer; var selectionEndOffset = selectionRange.endOffset; // select our link and unlink var a = dojo.withGlobal(this.window, "getAncestorElement", dojo.html.selection, ['a']); dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [a]); returnValue = this.document.execCommand("unlink", false, null); // restore original selection var selectionRange = this.document.createRange(); selectionRange.setStart(selectionStartContainer, selectionStartOffset); selectionRange.setEnd(selectionEndContainer, selectionEndOffset); selection.removeAllRanges(); selection.addRange(selectionRange); return returnValue; }else if((command == "hilitecolor")&&(dojo.render.html.mozilla)){ // mozilla doesn't support hilitecolor properly when useCSS is // set to false (bugzilla #279330) this.document.execCommand("useCSS", false, false); returnValue = this.document.execCommand(command, false, argument); this.document.execCommand("useCSS", false, true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -