// leanote 通用方法 //-------------- // 命名空间 //-------------- // 最上级变量 var LEA = {}; // 命名空间 var Notebook = { cache: {}, // notebookId => {Title, Seq} }; var Note = { cache: {}, // noteId => {Title, Tags, Content, Desc} }; var Import = {}; // 导入 // var UserInfo = {}; // 博客有问题, 会覆盖 var Tag = {}; var Notebook = {}; var Share = {}; var Mobile = {}; // 手机端处理 var LeaAce = {}; var Upgrade = { checkForUpdates: function () { Notify.show({title: 'Info', body: getMsg('Network error!')}); } }; // markdown var Converter; var MarkdownEditor; var ScrollLink; var MD; //--------------------- // 公用方法 function trimLeft(str, substr) { if(!substr || substr == " ") { return $.trim(str); } while(str.indexOf(substr) == 0) { str = str.substring(substr.length); } return str; } function json(str) { return eval("(" + str + ")") } // '
' function t() { var args = arguments; if(args.length <= 1) { return args[0]; } var text = args[0]; if(!text) { return text; } // 先把所有的?替换成, 很有可能替换的值有?会造成循环,没有替换想要的 var pattern = "LEAAEL" text = text.replace(/\?/g, pattern); // args[1] 替换第一个? for(var i = 1; i <= args.length; ++i) { text = text.replace(pattern, args[i]); } return text; } var tt = t; // 当slimscroll滑动时t被重新赋值了 // 判断数组是否相等 function arrayEqual(a, b) { a = a || []; b = b || []; // if (typeof a === 'string') { // a = [a]; // } // if (typeof b === 'string') { // b = [b]; // } return a.join(",") == b.join(","); } // 是否是数组 function isArray(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; } /** * 是否为空 * 可判断任意类型,string array */ function isEmpty(obj) { if(!obj) { return true; } if(isArray(obj)) { if(obj.length == 0) { return true; } } return false; } //------------ //得到form的数据 //返回json function getFormJsonData(formId) { var data = formArrDataToJson($('#' + formId).serializeArray()); return data; } //$('#form').serializeArray()的数据[{name: a, value: b}, {name: "c[]", value: d}] //转成{a:b} function formArrDataToJson(arrData) { var datas = {}; var arrObj= {}; // {a:[1, 2], b:[2, 3]}; for(var i in arrData) { var attr = arrData[i].name; var value = arrData[i].value; // 判断是否是a[]形式 if(attr.substring(attr.length-2, attr.length) == '[]') { attr = attr.substring(0, attr.length-2); if(arrObj[attr] == undefined) { arrObj[attr] = [value]; } else { arrObj[attr].push(value); } continue; } datas[attr] = value; } return $.extend(datas, arrObj); } //将serialize的的form值转成json function formSerializeDataToJson(formSerializeData) { var arr = formSerializeData.split("&"); var datas = {}; var arrObj= {}; // {a:[1, 2], b:[2, 3]}; for(var i = 0; i < arr.length; ++i) { var each = arr[i].split("="); var attr = decodeURI(each[0]); var value = decodeURI(each[1]); // 判断是否是a[]形式 if(attr.substring(attr.length-2, attr.length) == '[]') { attr = attr.substring(0, attr.length-2); if(arrObj[attr] == undefined) { arrObj[attr] = [value]; } else { arrObj[attr].push(value); } continue; } datas[attr] = value; } return $.extend(datas, arrObj); } // ajax请求返回结果后的操作 // 用于ajaxGet(), ajaxPost() function _ajaxCallback(ret, successFunc, failureFunc) { // 总会执行 if(ret === true || ret == "true" || typeof ret == "object") { // 是否是NOTELOGIN if(ret && typeof ret == "object") { if(ret.Msg == "NOTLOGIN") { alert("你还没有登录, 请先登录!"); return; } } if(typeof successFunc == "function") { successFunc(ret); } } else { if(typeof failureFunc == "function") { failureFunc(ret); } else { alert("error!") } } } function _ajax(type, url, param, successFunc, failureFunc, async) { Service.dispatch(url, param, successFunc); /* return $.ajax({ type: type, url: url, data: param, async: async, // 是否异步 success: function(ret) { _ajaxCallback(ret, successFunc, failureFunc); }, error: function(ret) { _ajaxCallback(ret, successFunc, failureFunc); } }); */ } /** * 发送ajax get请求 * @param url * @param param * @param successFunc * @param failureFunc * @param hasProgress * @param async 是否异步 * @returns */ function ajaxGet(url, param, successFunc, failureFunc, async) { return _ajax("GET", url, param, successFunc, failureFunc, async); } /** * 发送post请求 * @param url * @param param * @param successFunc * @param failureFunc * @param hasProgress * @param async 是否异步, 默认为true * @returns */ function ajaxPost(url, param, successFunc, failureFunc, async) { _ajax("POST", url, param, successFunc, failureFunc, async); } function ajaxPostJson(url, param, successFunc, failureFunc, async) { // log("-------------------ajaxPostJson:"); // log(url); // log(param); // 默认是异步的 if(typeof async == "undefined") { async = true; } else { async = false; } $.ajax({ url : url, type : "POST", contentType: "application/json; charset=utf-8", datatype: "json", async: async, data : JSON.stringify(param), success : function(ret, stats) { _ajaxCallback(ret, successFunc, failureFunc); }, error: function(ret) { _ajaxCallback(ret, successFunc, failureFunc); } }); } function findParents(target, selector) { if($(target).is(selector)) { return $(target); } var parents = $(target).parents(); for(var i = 0; i < parents.length; ++i) { log(parents.eq(i)) if(parents.eq(i).is(selector)) { return parents.seq(i); } } return null; } /* ajaxPostJson( "http://localhost:9000/notebook/index?i=100&name=life", {Title: "you can", UserId:"52a9e409f4ea49d6576fdbca", Subs:[{title: "xxxxx", Seq:11}, {title:"life..."}]}, function(e) { log(e); }); */ function getVendorPrefix() { // 使用body是为了避免在还需要传入元素 var body = document.body || document.documentElement, style = body.style, vendor = ['webkit', 'khtml', 'moz', 'ms', 'o'], i = 0; while (i < vendor.length) { // 此处进行判断是否有对应的内核前缀 if (typeof style[vendor[i] + 'Transition'] === 'string') { return vendor[i]; } i++; } } //----------------- // 切换编辑器时要修改tabIndex function editorIframeTabindex(index) { var $i = $("#editorContent"); // var $i = $("#editorContent_ifr"); // if($i.size() == 0) { $i.attr("tabindex", index); setTimeout(function() { $i.attr("tabindex", index); }, 500); setTimeout(function() { $i.attr("tabindex", index); }, 1000); // } else { // $i.attr("tabindex", index); // } } //切换编辑器 LEA.isM = false; LEA.isMarkdownEditor = function() { return LEA.isM; } function switchEditor(isMarkdown) { LEA.isM = isMarkdown; // 富文本永远是2 if(!isMarkdown) { $("#editor").show(); $("#mdEditor").css("z-index", 1).hide(); // 刚开始没有 editorIframeTabindex(2); $("#wmd-input-sub").attr("tabindex", 3); $("#leanoteNav").show(); } else { $("#mdEditor").css("z-index", 3).show(); editorIframeTabindex(3); $("#wmd-input-sub").attr("tabindex", 2); $("#leanoteNav").hide(); } } // 将http://127.0.0.1:8912转为leanote:// function fixContentUrl(content) { if (EvtService.canUseProtocol()) { return content.replace(/http:\/\/127.0.0.1:8912\/api\//g, 'leanote://'); } return content; } // editor 设置内容 // 可能是tinymce还没有渲染成功 var previewToken = "
FORTOKEN
" var clearIntervalForSetContent; function setEditorContent(content, isMarkdown, preview, callback) { // setTimeout(function() { _setEditorContent(content, isMarkdown, preview, callback); // }); } function _setEditorContent(content, isMarkdown, preview, callback) { if(!content) { content = ""; } content = fixContentUrl(content); if(clearIntervalForSetContent) { clearInterval(clearIntervalForSetContent); } if(!isMarkdown) { // 先destroy之前的ace /* if(typeof tinymce != "undefined" && tinymce.activeEditor) { var editor = tinymce.activeEditor; var everContent = $(editor.getBody()); if(everContent) { LeaAce.destroyAceFromContent(everContent); } } */ $("#editorContent").html(content); if(typeof tinymce != "undefined" && tinymce.activeEditor) { var editor = tinymce.activeEditor; editor.setContent(content); callback && callback(); // Note.toggleReadOnly(); /* if(LeaAce.canAce() && LeaAce.isAce) { try { LeaAce.initAceFromContent(editor); } catch(e) { log(e); } } else { // 为了在firefox下有正常的显示 $("#editorContent pre").removeClass("ace-tomorrow ace_editor"); } */ editor.undoManager.clear(); // 4-7修复BUG } else { // 等下再设置 clearIntervalForSetContent = setTimeout(function() { setEditorContent(content, false, false, callback); }, 100); } } else { /* $("#wmd-input").val(content); $("#wmd-preview").html(""); // 防止先点有的, 再点tinymce再点没内容的 if(!content || preview) { // 没有内容就不要解析了 $("#wmd-preview").html(preview).css("height", "auto"); if(ScrollLink) { ScrollLink.onPreviewFinished(); // 告诉scroll preview结束了 } } else { // 还要清空preview if(MarkdownEditor) { $("#wmd-preview").html(previewToken + "
正在转换...
"); MarkdownEditor.refreshPreview(); } else { // 等下再设置 clearIntervalForSetContent = setTimeout(function() { setEditorContent(content, true, preview); }, 200); } } */ if(MD) { MD.setContent(content); MD.clearUndo(); callback && callback(); } else { clearIntervalForSetContent = setTimeout(function() { setEditorContent(content, true, false, callback); }, 100); } } } // 复制图片 // 在web端得到图片 const {clipboard} = require('electron'); function pasteImage(e) { var image = clipboard.readImage(); if(image) { var dataUrl = image.toDataURL(); // 空图片 if(dataUrl == "data:image/png;base64,") { return; } FileService.pasteImage2(dataUrl, function(url) { insertImage(url); }); e && e.preventDefault(); } return; // 以下是node-webkit版 var items = (event.clipboardData || event.originalEvent.clipboardData).items; // 可能有多个file, 找到属于图片的file // find pasted image among pasted items var blob; for (var i = 0; i < items.length; i++) { // if (items[i].type.indexOf("image") === 0) { blob = items[i].getAsFile(); // console.log("paste images"); // console.log(blob); // load image if there is a pasted image if (blob) { // console.log("??"); var reader = new FileReader(); reader.onloadend = function() { // console.log('read end'); // console.log(reader); // console.log(reader.result); if(reader.result) { if(blob.type.indexOf('image/') === 0) { // image类型 FileService.pasteImage2(reader.result, function(url) { insertImage(url); }); } else { // 作为附件上传 // mac下还是图片 } } }; reader.readAsDataURL(blob); } } } // 插入本地图片 // tinymce image插件调用 function insertLocalImage() { gui.dialog.showOpenDialog(gui.getCurrentWindow(), { properties: ['openFile', 'multiSelections'], defaultPath: gui.app.getPath('userDesktop'), filters: [ { name: 'Images', extensions: ['jpg', 'jpeg', 'png', 'gif', 'bmp'] } ] }, function(paths) { if(!paths) { return; } for(var i = 0; i < paths.length; ++i) { (function(k) { var imagePath = paths[k]; // var imagePath = file.path; // 上传之 FileService.uploadImage(imagePath, function(newImage, msg) { if(newImage) { var note = Note.getCurNote(); var url = EvtService.getImageLocalUrl(newImage.FileId); if(!note.IsMarkdown) { tinymce.activeEditor.insertContent(''); } else { // TODO markdown insert Image MD.insertLink(url, '', true); } } else { alert(msg || "error"); } }); })(i); } } ); } // 插入图片(链接) // Markdown 插入图片 function insertImage(link) { if(LEA.isMarkdownEditor()) { MD.insertLink(link, '', true); } else { tinymce.activeEditor.insertContent(''); } } // preview是否为空 function previewIsEmpty(preview) { if(!preview || preview.substr(0, previewToken.length) == previewToken) { return true; } return false; } // ace的值有误? function isAceError(val) { if(!val) { return false; } return val.indexOf('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') != -1; } // 有tinymce得到的content有包围 // 总会出现

 

, 原因, setContent('


') 会设置成


// 所以, 要在getContent时, 当是


, 返回


function getEditorContent(isMarkdown) { var content = _getEditorContent(isMarkdown); if (content === '


') { return '


'; } return content; } function _getEditorContent(isMarkdown) { if(!isMarkdown) { var editor = tinymce.activeEditor; if(editor) { var content = $(editor.getBody()).clone(); // 删除toggle raw content.find('.toggle-raw').remove(); // 替换掉ace editor var pres = content.find('pre'); for(var i = 0 ; i < pres.length; ++i) { var pre = pres.eq(i); var id = pre.attr('id'); var aceEditor = LeaAce.getAce(id); if(aceEditor) { var val = aceEditor.getValue(); // 表示有错 if(isAceError(val)) { val = pre.html(); } val = val.replace(//g, '>'); pre.removeAttr('style', '').removeAttr('contenteditable').removeClass('ace_editor'); pre.html(val); } } // 去掉恶心的花瓣注入 // // 把最后的全去掉 // content.find("pinit").remove(); // content.find(".thunderpin").remove(); // content.find(".pin").parent().remove(); content = $(content).html(); if(content) { while(true) { var lastEndScriptPos = content.lastIndexOf(""); if (lastEndScriptPos == -1) { return content; } var length = content.length; // 证明在最后, 去除之 if(length - 9 == lastEndScriptPos) { var lastScriptPos = content.lastIndexOf("