/** * 插入代码插件 * @file * @since 1.2.6.1 */ UE.plugins["insertcode"] = function() { var me = this; me.ready(function() { utils.cssRule( "pre", "pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}", me.document ); }); me.setOpt("insertcode", { as3: "ActionScript3", bash: "Bash/Shell", cpp: "C/C++", css: "Css", cf: "CodeFunction", "c#": "C#", delphi: "Delphi", diff: "Diff", erlang: "Erlang", groovy: "Groovy", html: "Html", java: "Java", jfx: "JavaFx", js: "Javascript", pl: "Perl", php: "Php", plain: "Plain Text", ps: "PowerShell", python: "Python", ruby: "Ruby", scala: "Scala", sql: "Sql", vb: "Vb", xml: "Xml" }); /** * 插入代码 * @command insertcode * @method execCommand * @param { String } cmd 命令字符串 * @param { String } lang 插入代码的语言 * @example * ```javascript * editor.execCommand( 'insertcode', 'javascript' ); * ``` */ /** * 如果选区所在位置是插入插入代码区域,返回代码的语言 * @command insertcode * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回代码的语言 * @example * ```javascript * editor.queryCommandValue( 'insertcode' ); * ``` */ me.commands["insertcode"] = { execCommand: function(cmd, lang) { var me = this, rng = me.selection.getRange(), pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { pre.className = "brush:" + lang + ";toolbar:false;"; } else { var code = ""; if (rng.collapsed) { code = browser.ie && browser.ie11below ? browser.version <= 8 ? " " : "" : "
"; } else { var frag = rng.extractContents(); var div = me.document.createElement("div"); div.appendChild(frag); utils.each( UE.filterNode( UE.htmlparser(div.innerHTML.replace(/[\r\t]/g, "")), me.options.filterTxtRules ).children, function(node) { if (browser.ie && browser.ie11below && browser.version > 8) { if (node.type == "element") { if (node.tagName == "br") { code += "\n"; } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function(cn) { if (cn.type == "element") { if (cn.tagName == "br") { code += "\n"; } else if (!dtd.$empty[node.tagName]) { code += cn.innerText(); } } else { code += cn.data; } }); if (!/\n$/.test(code)) { code += "\n"; } } } else { code += node.data + "\n"; } if (!node.nextSibling() && /\n$/.test(code)) { code = code.replace(/\n$/, ""); } } else { if (browser.ie && browser.ie11below) { if (node.type == "element") { if (node.tagName == "br") { code += "
"; } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function(cn) { if (cn.type == "element") { if (cn.tagName == "br") { code += "
"; } else if (!dtd.$empty[node.tagName]) { code += cn.innerText(); } } else { code += cn.data; } }); if (!/br>$/.test(code)) { code += "
"; } } } else { code += node.data + "
"; } if (!node.nextSibling() && /
$/.test(code)) { code = code.replace(/
$/, ""); } } else { code += node.type == "element" ? dtd.$empty[node.tagName] ? "" : node.innerText() : node.data; if (!/br\/?\s*>$/.test(code)) { if (!node.nextSibling()) return; code += "
"; } } } } ); } me.execCommand( "inserthtml", '
' +
            code +
            "
", true ); pre = me.document.getElementById("coder"); domUtils.removeAttributes(pre, "id"); var tmpNode = pre.previousSibling; if ( tmpNode && ((tmpNode.nodeType == 3 && tmpNode.nodeValue.length == 1 && browser.ie && browser.version == 6) || domUtils.isEmptyBlock(tmpNode)) ) { domUtils.remove(tmpNode); } var rng = me.selection.getRange(); if (domUtils.isEmptyBlock(pre)) { rng.setStart(pre, 0).setCursor(false, true); } else { rng.selectNodeContents(pre).select(); } } }, queryCommandValue: function() { var path = this.selection.getStartElementPath(); var lang = ""; utils.each(path, function(node) { if (node.nodeName == "PRE") { var match = node.className.match(/brush:([^;]+)/); lang = match && match[1] ? match[1] : ""; return false; } }); return lang; } }; me.addInputRule(function(root) { utils.each(root.getNodesByTagName("pre"), function(pre) { var brs = pre.getNodesByTagName("br"); if (brs.length) { browser.ie && browser.ie11below && browser.version > 8 && utils.each(brs, function(br) { var txt = UE.uNode.createText("\n"); br.parentNode.insertBefore(txt, br); br.parentNode.removeChild(br); }); return; } if (browser.ie && browser.ie11below && browser.version > 8) return; var code = pre.innerText().split(/\n/); pre.innerHTML(""); utils.each(code, function(c) { if (c.length) { pre.appendChild(UE.uNode.createText(c)); } pre.appendChild(UE.uNode.createElement("br")); }); }); }); me.addOutputRule(function(root) { utils.each(root.getNodesByTagName("pre"), function(pre) { var code = ""; utils.each(pre.children, function(n) { if (n.type == "text") { //在ie下文本内容有可能末尾带有\n要去掉 //trace:3396 code += n.data.replace(/[ ]/g, " ").replace(/\n$/, ""); } else { if (n.tagName == "br") { code += "\n"; } else { code += !dtd.$empty[n.tagName] ? "" : n.innerText(); } } }); pre.innerText(code.replace(/( |\n)+$/, "")); }); }); //不需要判断highlight的command列表 me.notNeedCodeQuery = { help: 1, undo: 1, redo: 1, source: 1, print: 1, searchreplace: 1, fullscreen: 1, preview: 1, insertparagraph: 1, elementpath: 1, insertcode: 1, inserthtml: 1, selectall: 1 }; //将queyCommamndState重置 var orgQuery = me.queryCommandState; me.queryCommandState = function(cmd) { var me = this; if ( !me.notNeedCodeQuery[cmd.toLowerCase()] && me.selection && me.queryCommandValue("insertcode") ) { return -1; } return UE.Editor.prototype.queryCommandState.apply(this, arguments); }; me.addListener("beforeenterkeydown", function() { var rng = me.selection.getRange(); var pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { me.fireEvent("saveScene"); if (!rng.collapsed) { rng.deleteContents(); } if (!browser.ie || browser.ie9above) { var tmpNode = me.document.createElement("br"), pre; rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true); var next = tmpNode.nextSibling; if (!next && (!browser.ie || browser.version > 10)) { rng.insertNode(tmpNode.cloneNode(false)); } else { rng.setStartAfter(tmpNode); } pre = tmpNode.previousSibling; var tmp; while (pre) { tmp = pre; pre = pre.previousSibling; if (!pre || pre.nodeName == "BR") { pre = tmp; break; } } if (pre) { var str = ""; while ( pre && pre.nodeName != "BR" && new RegExp("^[\\s" + domUtils.fillChar + "]*$").test(pre.nodeValue) ) { str += pre.nodeValue; pre = pre.nextSibling; } if (pre.nodeName != "BR") { var match = pre.nodeValue.match( new RegExp("^([\\s" + domUtils.fillChar + "]+)") ); if (match && match[1]) { str += match[1]; } } if (str) { str = me.document.createTextNode(str); rng.insertNode(str).setStartAfter(str); } } rng.collapse(true).select(true); } else { if (browser.version > 8) { var txt = me.document.createTextNode("\n"); var start = rng.startContainer; if (rng.startOffset == 0) { var preNode = start.previousSibling; if (preNode) { rng.insertNode(txt); var fillchar = me.document.createTextNode(" "); rng .setStartAfter(txt) .insertNode(fillchar) .setStart(fillchar, 0) .collapse(true) .select(true); } } else { rng.insertNode(txt).setStartAfter(txt); var fillchar = me.document.createTextNode(" "); start = rng.startContainer.childNodes[rng.startOffset]; if (start && !/^\n/.test(start.nodeValue)) { rng.setStartBefore(txt); } rng .insertNode(fillchar) .setStart(fillchar, 0) .collapse(true) .select(true); } } else { var tmpNode = me.document.createElement("br"); rng.insertNode(tmpNode); rng.insertNode(me.document.createTextNode(domUtils.fillChar)); rng.setStartAfter(tmpNode); pre = tmpNode.previousSibling; var tmp; while (pre) { tmp = pre; pre = pre.previousSibling; if (!pre || pre.nodeName == "BR") { pre = tmp; break; } } if (pre) { var str = ""; while ( pre && pre.nodeName != "BR" && new RegExp("^[ " + domUtils.fillChar + "]*$").test(pre.nodeValue) ) { str += pre.nodeValue; pre = pre.nextSibling; } if (pre.nodeName != "BR") { var match = pre.nodeValue.match( new RegExp("^([ " + domUtils.fillChar + "]+)") ); if (match && match[1]) { str += match[1]; } } str = me.document.createTextNode(str); rng.insertNode(str).setStartAfter(str); } rng.collapse(true).select(); } } me.fireEvent("saveScene"); return true; } }); me.addListener("tabkeydown", function(cmd, evt) { var rng = me.selection.getRange(); var pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { me.fireEvent("saveScene"); if (evt.shiftKey) { } else { if (!rng.collapsed) { var bk = rng.createBookmark(); var start = bk.start.previousSibling; while (start) { if (pre.firstChild === start && !domUtils.isBr(start)) { pre.insertBefore(me.document.createTextNode(" "), start); break; } if (domUtils.isBr(start)) { pre.insertBefore( me.document.createTextNode(" "), start.nextSibling ); break; } start = start.previousSibling; } var end = bk.end; start = bk.start.nextSibling; if (pre.firstChild === bk.start) { pre.insertBefore( me.document.createTextNode(" "), start.nextSibling ); } while (start && start !== end) { if (domUtils.isBr(start) && start.nextSibling) { if (start.nextSibling === end) { break; } pre.insertBefore( me.document.createTextNode(" "), start.nextSibling ); } start = start.nextSibling; } rng.moveToBookmark(bk).select(); } else { var tmpNode = me.document.createTextNode(" "); rng .insertNode(tmpNode) .setStartAfter(tmpNode) .collapse(true) .select(true); } } me.fireEvent("saveScene"); return true; } }); me.addListener("beforeinserthtml", function(evtName, html) { var me = this, rng = me.selection.getRange(), pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { if (!rng.collapsed) { rng.deleteContents(); } var htmlstr = ""; if (browser.ie && browser.version > 8) { utils.each( UE.filterNode(UE.htmlparser(html), me.options.filterTxtRules) .children, function(node) { if (node.type == "element") { if (node.tagName == "br") { htmlstr += "\n"; } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function(cn) { if (cn.type == "element") { if (cn.tagName == "br") { htmlstr += "\n"; } else if (!dtd.$empty[node.tagName]) { htmlstr += cn.innerText(); } } else { htmlstr += cn.data; } }); if (!/\n$/.test(htmlstr)) { htmlstr += "\n"; } } } else { htmlstr += node.data + "\n"; } if (!node.nextSibling() && /\n$/.test(htmlstr)) { htmlstr = htmlstr.replace(/\n$/, ""); } } ); var tmpNode = me.document.createTextNode( utils.html(htmlstr.replace(/ /g, " ")) ); rng.insertNode(tmpNode).selectNode(tmpNode).select(); } else { var frag = me.document.createDocumentFragment(); utils.each( UE.filterNode(UE.htmlparser(html), me.options.filterTxtRules) .children, function(node) { if (node.type == "element") { if (node.tagName == "br") { frag.appendChild(me.document.createElement("br")); } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function(cn) { if (cn.type == "element") { if (cn.tagName == "br") { frag.appendChild(me.document.createElement("br")); } else if (!dtd.$empty[node.tagName]) { frag.appendChild( me.document.createTextNode( utils.html(cn.innerText().replace(/ /g, " ")) ) ); } } else { frag.appendChild( me.document.createTextNode( utils.html(cn.data.replace(/ /g, " ")) ) ); } }); if (frag.lastChild.nodeName != "BR") { frag.appendChild(me.document.createElement("br")); } } } else { frag.appendChild( me.document.createTextNode( utils.html(node.data.replace(/ /g, " ")) ) ); } if (!node.nextSibling() && frag.lastChild.nodeName == "BR") { frag.removeChild(frag.lastChild); } } ); rng.insertNode(frag).select(); } return true; } }); //方向键的处理 me.addListener("keydown", function(cmd, evt) { var me = this, keyCode = evt.keyCode || evt.which; if (keyCode == 40) { var rng = me.selection.getRange(), pre, start = rng.startContainer; if ( rng.collapsed && (pre = domUtils.findParentByTagName(rng.startContainer, "pre", true)) && !pre.nextSibling ) { var last = pre.lastChild; while (last && last.nodeName == "BR") { last = last.previousSibling; } if ( last === start || (rng.startContainer === pre && rng.startOffset == pre.childNodes.length) ) { me.execCommand("insertparagraph"); domUtils.preventDefault(evt); } } } }); //trace:3395 me.addListener("delkeydown", function(type, evt) { var rng = this.selection.getRange(); rng.txtToElmBoundary(true); var start = rng.startContainer; if ( domUtils.isTagNode(start, "pre") && rng.collapsed && domUtils.isStartInblock(rng) ) { var p = me.document.createElement("p"); domUtils.fillNode(me.document, p); start.parentNode.insertBefore(p, start); domUtils.remove(start); rng.setStart(p, 0).setCursor(false, true); domUtils.preventDefault(evt); return true; } }); };