123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- /**
- * 源码编辑插件
- * @file
- * @since 1.2.6.1
- */
- (function() {
- var sourceEditors = {
- textarea: function(editor, holder) {
- var textarea = holder.ownerDocument.createElement("textarea");
- textarea.style.cssText =
- "position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;";
- // todo: IE下只有onresize属性可用... 很纠结
- if (browser.ie && browser.version < 8) {
- textarea.style.width = holder.offsetWidth + "px";
- textarea.style.height = holder.offsetHeight + "px";
- holder.onresize = function() {
- textarea.style.width = holder.offsetWidth + "px";
- textarea.style.height = holder.offsetHeight + "px";
- };
- }
- holder.appendChild(textarea);
- return {
- setContent: function(content) {
- textarea.value = content;
- },
- getContent: function() {
- return textarea.value;
- },
- select: function() {
- var range;
- if (browser.ie) {
- range = textarea.createTextRange();
- range.collapse(true);
- range.select();
- } else {
- //todo: chrome下无法设置焦点
- textarea.setSelectionRange(0, 0);
- textarea.focus();
- }
- },
- dispose: function() {
- holder.removeChild(textarea);
- // todo
- holder.onresize = null;
- textarea = null;
- holder = null;
- },
- focus: function (){
- textarea.focus();
- },
- blur: function (){
- textarea.blur();
- }
- };
- },
- codemirror: function(editor, holder) {
- var codeEditor = window.CodeMirror(holder, {
- mode: "text/html",
- tabMode: "indent",
- lineNumbers: true,
- lineWrapping: true
- });
- var dom = codeEditor.getWrapperElement();
- dom.style.cssText =
- 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;';
- codeEditor.getScrollerElement().style.cssText =
- "position:absolute;left:0;top:0;width:100%;height:100%;";
- codeEditor.refresh();
- return {
- getCodeMirror: function() {
- return codeEditor;
- },
- setContent: function(content) {
- codeEditor.setValue(content);
- },
- getContent: function() {
- return codeEditor.getValue();
- },
- select: function() {
- codeEditor.focus();
- },
- dispose: function() {
- holder.removeChild(dom);
- dom = null;
- codeEditor = null;
- },
- focus: function (){
- codeEditor.focus();
- },
- blur: function (){
- // codeEditor.blur();
- // since codemirror not support blur()
- codeEditor.setOption('readOnly', true);
- codeEditor.setOption('readOnly', false);
- }
- };
- }
- };
- UE.plugins["source"] = function() {
- var me = this;
- var opt = this.options;
- var sourceMode = false;
- var sourceEditor;
- var orgSetContent;
- var orgFocus;
- var orgBlur;
- opt.sourceEditor = browser.ie
- ? "textarea"
- : opt.sourceEditor || "codemirror";
- me.setOpt({
- sourceEditorFirst: false
- });
- function createSourceEditor(holder) {
- return sourceEditors[
- opt.sourceEditor == "codemirror" && window.CodeMirror
- ? "codemirror"
- : "textarea"
- ](me, holder);
- }
- var bakCssText;
- //解决在源码模式下getContent不能得到最新的内容问题
- var oldGetContent, bakAddress;
- /**
- * 切换源码模式和编辑模式
- * @command source
- * @method execCommand
- * @param { String } cmd 命令字符串
- * @example
- * ```javascript
- * editor.execCommand( 'source');
- * ```
- */
- /**
- * 查询当前编辑区域的状态是源码模式还是可视化模式
- * @command source
- * @method queryCommandState
- * @param { String } cmd 命令字符串
- * @return { int } 如果当前是源码编辑模式,返回1,否则返回0
- * @example
- * ```javascript
- * editor.queryCommandState( 'source' );
- * ```
- */
- me.commands["source"] = {
- execCommand: function() {
- sourceMode = !sourceMode;
- if (sourceMode) {
- bakAddress = me.selection.getRange().createAddress(false, true);
- me.undoManger && me.undoManger.save(true);
- if (browser.gecko) {
- me.body.contentEditable = false;
- }
- bakCssText = me.iframe.style.cssText;
- me.iframe.style.cssText +=
- "position:absolute;left:-32768px;top:-32768px;";
- me.fireEvent("beforegetcontent");
- var root = UE.htmlparser(me.body.innerHTML);
- me.filterOutputRule(root);
- root.traversal(function(node) {
- if (node.type == "element") {
- switch (node.tagName) {
- case "td":
- case "th":
- case "caption":
- if (node.children && node.children.length == 1) {
- if (node.firstChild().tagName == "br") {
- node.removeChild(node.firstChild());
- }
- }
- break;
- case "pre":
- node.innerText(node.innerText().replace(/ /g, " "));
- }
- }
- });
- me.fireEvent("aftergetcontent");
- var content = root.toHtml(true);
- sourceEditor = createSourceEditor(me.iframe.parentNode);
- sourceEditor.setContent(content);
- orgSetContent = me.setContent;
- me.setContent = function(html) {
- //这里暂时不触发事件,防止报错
- var root = UE.htmlparser(html);
- me.filterInputRule(root);
- html = root.toHtml();
- sourceEditor.setContent(html);
- };
- setTimeout(function() {
- sourceEditor.select();
- me.addListener("fullscreenchanged", function() {
- try {
- sourceEditor.getCodeMirror().refresh();
- } catch (e) {}
- });
- });
- //重置getContent,源码模式下取值也能是最新的数据
- oldGetContent = me.getContent;
- me.getContent = function() {
- return (
- sourceEditor.getContent() ||
- "<p>" + (browser.ie ? "" : "<br/>") + "</p>"
- );
- };
- orgFocus = me.focus;
- orgBlur = me.blur;
- me.focus = function(){
- sourceEditor.focus();
- };
- me.blur = function(){
- orgBlur.call(me);
- sourceEditor.blur();
- };
- } else {
- me.iframe.style.cssText = bakCssText;
- var cont =
- sourceEditor.getContent() ||
- "<p>" + (browser.ie ? "" : "<br/>") + "</p>";
- //处理掉block节点前后的空格,有可能会误命中,暂时不考虑
- cont = cont.replace(
- new RegExp("[\\r\\t\\n ]*</?(\\w+)\\s*(?:[^>]*)>", "g"),
- function(a, b) {
- if (b && !dtd.$inlineWithA[b.toLowerCase()]) {
- return a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g, "");
- }
- return a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g, "");
- }
- );
- me.setContent = orgSetContent;
- me.setContent(cont);
- sourceEditor.dispose();
- sourceEditor = null;
- //还原getContent方法
- me.getContent = oldGetContent;
- me.focus = orgFocus;
- me.blur = orgBlur;
- var first = me.body.firstChild;
- //trace:1106 都删除空了,下边会报错,所以补充一个p占位
- if (!first) {
- me.body.innerHTML = "<p>" + (browser.ie ? "" : "<br/>") + "</p>";
- first = me.body.firstChild;
- }
- //要在ifm为显示时ff才能取到selection,否则报错
- //这里不能比较位置了
- me.undoManger && me.undoManger.save(true);
- if (browser.gecko) {
- var input = document.createElement("input");
- input.style.cssText = "position:absolute;left:0;top:-32768px";
- document.body.appendChild(input);
- me.body.contentEditable = false;
- setTimeout(function() {
- domUtils.setViewportOffset(input, { left: -32768, top: 0 });
- input.focus();
- setTimeout(function() {
- me.body.contentEditable = true;
- me.selection.getRange().moveToAddress(bakAddress).select(true);
- domUtils.remove(input);
- });
- });
- } else {
- //ie下有可能报错,比如在代码顶头的情况
- try {
- me.selection.getRange().moveToAddress(bakAddress).select(true);
- } catch (e) {}
- }
- }
- this.fireEvent("sourcemodechanged", sourceMode);
- },
- queryCommandState: function() {
- return sourceMode | 0;
- },
- notNeedUndo: 1
- };
- var oldQueryCommandState = me.queryCommandState;
- me.queryCommandState = function(cmdName) {
- cmdName = cmdName.toLowerCase();
- if (sourceMode) {
- //源码模式下可以开启的命令
- return cmdName in
- {
- source: 1,
- fullscreen: 1
- }
- ? 1
- : -1;
- }
- return oldQueryCommandState.apply(this, arguments);
- };
- if (opt.sourceEditor == "codemirror") {
- me.addListener("ready", function() {
- utils.loadFile(
- document,
- {
- src:
- opt.codeMirrorJsUrl ||
- opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.js",
- tag: "script",
- type: "text/javascript",
- defer: "defer"
- },
- function() {
- if (opt.sourceEditorFirst) {
- setTimeout(function() {
- me.execCommand("source");
- }, 0);
- }
- }
- );
- utils.loadFile(document, {
- tag: "link",
- rel: "stylesheet",
- type: "text/css",
- href:
- opt.codeMirrorCssUrl ||
- opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.css"
- });
- });
- }
- };
- })();
|