mirror of
https://github.com/mindoc-org/mindoc.git
synced 2025-10-25 19:17:05 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -3,6 +3,10 @@ $(function () {
|
||||
js : window.katex.js,
|
||||
css : window.katex.css
|
||||
};
|
||||
var htmlDecodeList = ["style","script","title","onmouseover","onmouseout","style"];
|
||||
if (!window.IS_ENABLE_IFRAME) {
|
||||
htmlDecodeList.unshift("iframe");
|
||||
}
|
||||
window.editor = editormd("docEditor", {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
@@ -18,8 +22,8 @@ $(function () {
|
||||
taskList: true,
|
||||
flowChart: true,
|
||||
mermaid: true,
|
||||
htmlDecode: "style,script,iframe,title,onmouseover,onmouseout,style",
|
||||
lineNumbers: false,
|
||||
htmlDecode: htmlDecodeList.join(','),
|
||||
lineNumbers: true,
|
||||
sequenceDiagram: true,
|
||||
highlightStyle: window.highlightStyle ? window.highlightStyle : "github",
|
||||
tocStartLevel: 1,
|
||||
|
||||
106
static/js/class2browser.js
Normal file
106
static/js/class2browser.js
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* 将es6的class语法转为浏览器可以直接使用的语法,
|
||||
* 取自 https://babeljs.io/repl
|
||||
* 需要添加 @babel/plugin-transform-classes
|
||||
* 是要到的方法添加了`c2b`前缀
|
||||
*/
|
||||
|
||||
function c2b_classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
}
|
||||
|
||||
function _defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
function c2b_createClass(Constructor, protoProps, staticProps) {
|
||||
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) _defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
}
|
||||
|
||||
function c2b_inherits(subClass, superClass) {
|
||||
if (typeof superClass !== "function" && superClass !== null) {
|
||||
throw new TypeError("Super expression must either be null or a function");
|
||||
}
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
||||
constructor: { value: subClass, writable: true, configurable: true }
|
||||
});
|
||||
if (superClass) _setPrototypeOf(subClass, superClass);
|
||||
}
|
||||
|
||||
function _setPrototypeOf(o, p) {
|
||||
_setPrototypeOf =
|
||||
Object.setPrototypeOf ||
|
||||
function _setPrototypeOf(o, p) {
|
||||
o.__proto__ = p;
|
||||
return o;
|
||||
};
|
||||
return _setPrototypeOf(o, p);
|
||||
}
|
||||
|
||||
function c2b_createSuper(Derived) {
|
||||
var hasNativeReflectConstruct = _isNativeReflectConstruct();
|
||||
return function _createSuperInternal() {
|
||||
var Super = _getPrototypeOf(Derived),
|
||||
result;
|
||||
if (hasNativeReflectConstruct) {
|
||||
var NewTarget = _getPrototypeOf(this).constructor;
|
||||
result = Reflect.construct(Super, arguments, NewTarget);
|
||||
} else {
|
||||
result = Super.apply(this, arguments);
|
||||
}
|
||||
return _possibleConstructorReturn(this, result);
|
||||
};
|
||||
}
|
||||
|
||||
function _possibleConstructorReturn(self, call) {
|
||||
if (call && (typeof call === "object" || typeof call === "function")) {
|
||||
return call;
|
||||
} else if (call !== void 0) {
|
||||
throw new TypeError(
|
||||
"Derived constructors may only return object or undefined"
|
||||
);
|
||||
}
|
||||
return _assertThisInitialized(self);
|
||||
}
|
||||
|
||||
function _assertThisInitialized(self) {
|
||||
if (self === void 0) {
|
||||
throw new ReferenceError(
|
||||
"this hasn't been initialised - super() hasn't been called"
|
||||
);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
function _isNativeReflectConstruct() {
|
||||
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
||||
if (Reflect.construct.sham) return false;
|
||||
if (typeof Proxy === "function") return true;
|
||||
try {
|
||||
Boolean.prototype.valueOf.call(
|
||||
Reflect.construct(Boolean, [], function () {})
|
||||
);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function _getPrototypeOf(o) {
|
||||
_getPrototypeOf = Object.setPrototypeOf
|
||||
? Object.getPrototypeOf
|
||||
: function _getPrototypeOf(o) {
|
||||
return o.__proto__ || Object.getPrototypeOf(o);
|
||||
};
|
||||
return _getPrototypeOf(o);
|
||||
}
|
||||
1
static/js/custom-elements-builtin-0.6.5.min.js
vendored
Normal file
1
static/js/custom-elements-builtin-0.6.5.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(P,H,k){"use strict";if(1==P.importNode.length&&!H.get("ungap-li")){var D="extends";try{var e={extends:"li"},t=HTMLLIElement,n=function(){return Reflect.construct(t,[],n)};if(n.prototype=k.create(t.prototype),H.define("ungap-li",n,e),!/is="ungap-li"/.test((new n).outerHTML))throw e}catch(e){!function(){var l="attributeChangedCallback",n="connectedCallback",r="disconnectedCallback",e=Element.prototype,i=k.assign,t=k.create,o=k.defineProperties,a=k.getOwnPropertyDescriptor,s=k.setPrototypeOf,u=H.define,c=H.get,f=H.upgrade,p=H.whenDefined,v=t(null),d=new WeakMap,g={childList:!0,subtree:!0};Reflect.ownKeys(self).filter(function(e){return"string"==typeof e&&/^HTML(?!Element)/.test(e)}).forEach(function(e){function t(){}var n=self[e];s(t,n),(t.prototype=n.prototype).constructor=t,(n={})[e]={value:t},o(self,n)}),new MutationObserver(m).observe(P,g),O(Document.prototype,"importNode"),O(Node.prototype,"cloneNode"),o(H,{define:{value:function(e,t,n){if(e=e.toLowerCase(),n&&D in n){v[e]=i({},n,{Class:t});for(var e=n[D]+'[is="'+e+'"]',r=P.querySelectorAll(e),o=0,a=r.length;o<a;o++)A(r[o])}else u.apply(H,arguments)}},get:{value:function(e){return e in v?v[e].Class:c.call(H,e)}},upgrade:{value:function(e){var t=L(e);!t||e instanceof t.Class?f.call(H,e):N(e,t)}},whenDefined:{value:function(e){return e in v?Promise.resolve():p.call(H,e)}}});var h=P.createElement;o(P,{createElement:{value:function(e,t){e=h.call(P,e);return t&&"is"in t&&(e.setAttribute("is",t.is),H.upgrade(e)),e}}});var b=a(e,"attachShadow").value,y=a(e,"innerHTML");function m(e){for(var t=0,n=e.length;t<n;t++){for(var r=e[t],o=r.addedNodes,a=r.removedNodes,i=0,l=o.length;i<l;i++)A(o[i]);for(i=0,l=a.length;i<l;i++)C(a[i])}}function w(e){for(var t=0,n=e.length;t<n;t++){var r=e[t],o=r.attributeName,a=r.oldValue,i=r.target,r=i.getAttribute(o);l in i&&(a!=r||null!=r)&&i[l](o,a,i.getAttribute(o),null)}}function C(e){var t;1===e.nodeType&&((t=L(e))&&e instanceof t.Class&&r in e&&d.get(e)!==r&&(d.set(e,r),Promise.resolve(e).then(T)),E(e,C))}function L(e){e=e.getAttribute("is");return e&&(e=e.toLowerCase())in v?v[e]:null}function M(e){e[n]()}function T(e){e[r]()}function N(e,t){var t=t.Class,n=t.observedAttributes||[];if(s(e,t.prototype),n.length){new MutationObserver(w).observe(e,{attributes:!0,attributeFilter:n,attributeOldValue:!0});for(var r=[],o=0,a=n.length;o<a;o++)r.push({attributeName:n[o],oldValue:null,target:e});w(r)}}function A(e){var t;1===e.nodeType&&((t=L(e))&&(e instanceof t.Class||N(e,t),n in e&&e.isConnected&&d.get(e)!==n&&(d.set(e,n),Promise.resolve(e).then(M))),E(e,A))}function E(e,t){for(var n=e.content,r=(n&&11==n.nodeType?n:e).querySelectorAll("[is]"),o=0,a=r.length;o<a;o++)t(r[o])}function O(e,t){var n=e[t],r={};r[t]={value:function(){var e=n.apply(this,arguments);switch(e.nodeType){case 1:case 11:E(e,A)}return e}},o(e,r)}o(e,{attachShadow:{value:function(){var e=b.apply(this,arguments);return new MutationObserver(m).observe(e,g),e}},innerHTML:{get:y.get,set:function(e){y.set.call(this,e),/\bis=("|')?[a-z0-9_-]+\1/i.test(e)&&E(this,A)}}})}()}}}(document,customElements,Object);
|
||||
@@ -5,7 +5,7 @@
|
||||
/**
|
||||
* 打开最后选中的节点
|
||||
*/
|
||||
function openLastSelectedNode() {
|
||||
function openLastSelectedNode() {
|
||||
//如果文档树或编辑器没有准备好则不加载文档
|
||||
if (window.treeCatalog == null || window.editor == null) {
|
||||
return false;
|
||||
@@ -81,7 +81,14 @@ function jstree_save(node, parent) {
|
||||
var index = layer.load(1, {
|
||||
shade: [0.1, '#fff'] //0.1透明度的白色背景
|
||||
});
|
||||
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
saveSortSucc: '保存排序成功',
|
||||
},
|
||||
'en': {
|
||||
saveSortSucc: 'Save sort success',
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
url: window.sortURL,
|
||||
type: "post",
|
||||
@@ -89,7 +96,7 @@ function jstree_save(node, parent) {
|
||||
success: function (res) {
|
||||
layer.close(index);
|
||||
if (res.errcode === 0) {
|
||||
layer.msg("保存排序成功");
|
||||
layer.msg(locales[lang].saveSortSucc);
|
||||
} else {
|
||||
layer.msg(res.message);
|
||||
}
|
||||
@@ -138,8 +145,27 @@ function getSiblingSort(node) {
|
||||
* @param $node
|
||||
*/
|
||||
function openDeleteDocumentDialog($node) {
|
||||
var index = layer.confirm('你确定要删除该文档吗?', {
|
||||
btn: ['确定', '取消'] //按钮
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
saveSortSucc: '保存排序成功',
|
||||
confirmDeleteDoc: '你确定要删除该文档吗?',
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
deleteFailed: '删除失败',
|
||||
confirmLeave: '您输入的内容尚未保存,确定离开此页面吗?'
|
||||
},
|
||||
'en': {
|
||||
saveSortSucc: 'Save sort success',
|
||||
confirmDeleteDoc: 'Are you sure you want to delete this document?',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
deleteFailed: 'Delete Failed',
|
||||
confirmLeave: 'The content you entered has not been saved. Are you sure you want to leave this page?'
|
||||
}
|
||||
}
|
||||
langs = locales[lang];
|
||||
var index = layer.confirm(langs.confirmDeleteDoc, {
|
||||
btn: [langs.confirm, langs.cancel] //按钮
|
||||
}, function () {
|
||||
|
||||
$.post(window.deleteURL, {"identify": window.book.identify, "doc_id": $node.id}).done(function (res) {
|
||||
@@ -154,11 +180,11 @@ function openDeleteDocumentDialog($node) {
|
||||
// console.log(window.documentCategory)
|
||||
setLastSelectNode();
|
||||
} else {
|
||||
layer.msg("删除失败", {icon: 2})
|
||||
layer.msg(lang.deleteFailed, {icon: 2})
|
||||
}
|
||||
}).fail(function () {
|
||||
layer.close(index);
|
||||
layer.msg("删除失败", {icon: 2})
|
||||
layer.msg(lang.deleteFailed, {icon: 2})
|
||||
});
|
||||
|
||||
});
|
||||
@@ -228,6 +254,14 @@ function pushVueLists($lists) {
|
||||
* 发布项目
|
||||
*/
|
||||
function releaseBook() {
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
publishToQueue: '发布任务已推送到任务队列,稍后将在后台执行。',
|
||||
},
|
||||
'en': {
|
||||
publishToQueue: 'The publish task has been pushed to the queue</br> and will be executed soon.',
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
url: window.releaseURL,
|
||||
data: {"identify": window.book.identify},
|
||||
@@ -235,7 +269,7 @@ function releaseBook() {
|
||||
dataType: "json",
|
||||
success: function (res) {
|
||||
if (res.errcode === 0) {
|
||||
layer.msg("发布任务已推送到任务队列,稍后将在后台执行。");
|
||||
layer.msg(locales[lang].publishToQueue);
|
||||
} else {
|
||||
layer.msg(res.message);
|
||||
}
|
||||
@@ -298,9 +332,17 @@ function showSuccess($msg, $id) {
|
||||
}
|
||||
|
||||
window.documentHistory = function () {
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
hisVer: '历史版本',
|
||||
},
|
||||
'en': {
|
||||
hisVer: 'Historic version',
|
||||
}
|
||||
}
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '历史版本',
|
||||
title: locales[lang].hisVer,
|
||||
shadeClose: true,
|
||||
shade: 0.8,
|
||||
area: ['700px', '80%'],
|
||||
@@ -320,6 +362,16 @@ window.documentHistory = function () {
|
||||
};
|
||||
|
||||
function uploadImage($id, $callback) {
|
||||
locales = {
|
||||
'zh-CN': {
|
||||
unsupportType: '不支持的图片格式',
|
||||
uploadFailed: '图片上传失败'
|
||||
},
|
||||
'en': {
|
||||
unsupportType: 'Unsupport image type',
|
||||
uploadFailed: 'Upload image failed'
|
||||
}
|
||||
}
|
||||
/** 粘贴上传图片 **/
|
||||
document.getElementById($id).addEventListener('paste', function (e) {
|
||||
if (e.clipboardData && e.clipboardData.items) {
|
||||
@@ -345,7 +397,7 @@ function uploadImage($id, $callback) {
|
||||
fileName += ".gif";
|
||||
break;
|
||||
default :
|
||||
layer.msg("不支持的图片格式");
|
||||
layer.msg(locales[lang].unsupportType);
|
||||
return;
|
||||
}
|
||||
var form = new FormData();
|
||||
@@ -367,7 +419,7 @@ function uploadImage($id, $callback) {
|
||||
error: function () {
|
||||
layer.close(layerIndex);
|
||||
$callback('error');
|
||||
layer.msg("图片上传失败");
|
||||
layer.msg(locales[lang].uploadFailed);
|
||||
},
|
||||
success: function (data) {
|
||||
layer.close(layerIndex);
|
||||
|
||||
@@ -1,21 +1,60 @@
|
||||
$(function () {
|
||||
wangEditor.config.mapAk = window.baiduMapKey;
|
||||
window.addDocumentModalFormHtml = $(this).find("form").html();
|
||||
wangEditor.config.printLog = false;
|
||||
window.editor = new wangEditor('htmlEditor');
|
||||
window.editor = new wangEditor('#htmlEditor');
|
||||
editor.config.mapAk = window.baiduMapKey;
|
||||
editor.config.printLog = false;
|
||||
editor.config.showMenuTooltips = true
|
||||
editor.config.menuTooltipPosition = 'down'
|
||||
editor.config.uploadImgUrl = window.imageUploadURL;
|
||||
editor.config.uploadImgFileName = "editormd-image-file";
|
||||
editor.config.uploadParams = {
|
||||
"editor" : "wangEditor"
|
||||
};
|
||||
wangEditor.config.menus.splice(0,0,"|");
|
||||
wangEditor.config.menus.splice(0,0,"history");
|
||||
wangEditor.config.menus.splice(0,0,"save");
|
||||
wangEditor.config.menus.splice(0,0,"release");
|
||||
wangEditor.config.menus.splice(29,0,"attach")
|
||||
editor.config.uploadImgServer = window.imageUploadURL;
|
||||
editor.config.customUploadImg = function (resultFiles, insertImgFn) {
|
||||
// resultFiles 是 input 中选中的文件列表
|
||||
// insertImgFn 是获取图片 url 后,插入到编辑器的方法
|
||||
var file = resultFiles[0];
|
||||
// file type is only image.
|
||||
if (/^image\//.test(file.type)) {
|
||||
var form = new FormData();
|
||||
form.append('editormd-image-file', file, file.name);
|
||||
|
||||
var layerIndex = 0;
|
||||
|
||||
$.ajax({
|
||||
url: window.imageUploadURL,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: form,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
error: function() {
|
||||
layer.close(layerIndex);
|
||||
layer.msg("图片上传失败");
|
||||
},
|
||||
success: function(data) {
|
||||
layer.close(layerIndex);
|
||||
if(data.errcode !== 0){
|
||||
layer.msg(data.message);
|
||||
}else{
|
||||
insertImgFn(data.url);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('You could only upload images.');
|
||||
}
|
||||
};
|
||||
/*
|
||||
editor.config.menus.splice(0,0,"|");
|
||||
editor.config.menus.splice(0,0,"history");
|
||||
editor.config.menus.splice(0,0,"save");
|
||||
editor.config.menus.splice(0,0,"release");
|
||||
editor.config.menus.splice(29,0,"attach")
|
||||
|
||||
//移除地图、背景色
|
||||
editor.config.menus = $.map(wangEditor.config.menus, function(item, key) {
|
||||
editor.config.menus = $.map(editor.config.menus, function(item, key) {
|
||||
|
||||
if (item === 'fullscreen') {
|
||||
return null;
|
||||
@@ -23,16 +62,8 @@ $(function () {
|
||||
|
||||
return item;
|
||||
});
|
||||
|
||||
window.editor.ready(function () {
|
||||
if(window.documentCategory.length > 0){
|
||||
var item = window.documentCategory[0];
|
||||
var $select_node = { node : {id : item.id}};
|
||||
loadDocument($select_node);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
*/
|
||||
/*
|
||||
window.editor.config.uploadImgFns.onload = function (resultText, xhr) {
|
||||
// resultText 服务器端返回的text
|
||||
// xhr 是 xmlHttpRequest 对象,IE8、9中不支持
|
||||
@@ -47,13 +78,15 @@ $(function () {
|
||||
layer.msg(res.message);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
window.editor.onchange = function () {
|
||||
window.editor.config.onchange = function (newHtml) {
|
||||
var saveMenu = window.editor.menus.menuList.find((item) => item.key == 'save');
|
||||
// 判断内容是否改变
|
||||
if (window.source !== this.$txt.html()) {
|
||||
window.editor.menus.save.$domNormal.addClass('selected');
|
||||
if (window.source !== window.editor.txt.html()) {
|
||||
saveMenu.$elem.addClass('selected');
|
||||
} else {
|
||||
window.editor.menus.save.$domNormal.removeClass('selected');
|
||||
saveMenu.$elem.removeClass('selected');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,7 +95,11 @@ $(function () {
|
||||
|
||||
$("#htmlEditor").css("height","100%");
|
||||
|
||||
|
||||
if(window.documentCategory.length > 0){
|
||||
var item = window.documentCategory[0];
|
||||
var $select_node = { node : {id : item.id}};
|
||||
loadDocument($select_node);
|
||||
}
|
||||
|
||||
/***
|
||||
* 加载指定的文档到编辑器中
|
||||
@@ -78,8 +115,8 @@ $(function () {
|
||||
|
||||
if(res.errcode === 0){
|
||||
window.isLoad = true;
|
||||
window.editor.clear();
|
||||
window.editor.$txt.html(res.data.content);
|
||||
window.editor.txt.clear();
|
||||
window.editor.txt.html(res.data.content);
|
||||
// 将原始内容备份
|
||||
window.source = res.data.content;
|
||||
var node = { "id" : res.data.doc_id,'parent' : res.data.parent_id === 0 ? '#' : res.data.parent_id ,"text" : res.data.doc_name,"identify" : res.data.identify,"version" : res.data.version};
|
||||
@@ -105,7 +142,7 @@ $(function () {
|
||||
var index = null;
|
||||
var node = window.selectNode;
|
||||
|
||||
var html = window.editor.$txt.html() ;
|
||||
var html = window.editor.txt.html() ;
|
||||
|
||||
var content = "";
|
||||
if($.trim(html) !== ""){
|
||||
@@ -149,7 +186,7 @@ $(function () {
|
||||
// 更新内容备份
|
||||
window.source = res.data.content;
|
||||
// 触发编辑器 onchange 回调函数
|
||||
window.editor.onchange();
|
||||
window.editor.config.onchange();
|
||||
if(typeof callback === "function"){
|
||||
callback();
|
||||
}
|
||||
@@ -267,7 +304,7 @@ $(function () {
|
||||
}).on('loaded.jstree', function () {
|
||||
window.treeCatalog = $(this).jstree();
|
||||
}).on('select_node.jstree', function (node, selected, event) {
|
||||
if(window.editor.menus.save.$domNormal.hasClass('selected')) {
|
||||
if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) {
|
||||
if(confirm("编辑内容未保存,需要保存吗?")){
|
||||
saveDocument(false,function () {
|
||||
loadDocument(selected);
|
||||
@@ -283,7 +320,7 @@ $(function () {
|
||||
|
||||
window.releaseBook = function () {
|
||||
if(Object.prototype.toString.call(window.documentCategory) === '[object Array]' && window.documentCategory.length > 0){
|
||||
if(window.editor.menus.save.$domNormal.hasClass('selected')) {
|
||||
if(window.editor.menus.menuList.find((item) => item.key == 'save').$elem.hasClass('selected')) {
|
||||
if(confirm("编辑内容未保存,需要保存吗?")) {
|
||||
saveDocument();
|
||||
}
|
||||
@@ -305,4 +342,16 @@ $(function () {
|
||||
layer.msg("没有需要发布的文档")
|
||||
}
|
||||
};
|
||||
|
||||
$(window).resize(function(e) {
|
||||
var $container = $(editor.$textContainerElem.elems[0]);
|
||||
var $manual = $container.closest('.manual-wangEditor');
|
||||
var maxHeight = $manual.closest('.manual-editor-container').innerHeight();
|
||||
var statusHeight = $manual.siblings('.manual-editor-status').outerHeight(true);
|
||||
var manualHeihgt = maxHeight - statusHeight;
|
||||
$manual.height(manualHeihgt);
|
||||
var toolbarHeight = $container.siblings('.w-e-toolbar').outerHeight(true);
|
||||
$container.height($container.parent().innerHeight() - toolbarHeight);
|
||||
});
|
||||
$(window).trigger('resize');
|
||||
});
|
||||
@@ -4,12 +4,66 @@ $(function () {
|
||||
css : window.katex.css
|
||||
};
|
||||
|
||||
window.editormdLocales = {
|
||||
'zh-CN': {
|
||||
placeholder: '本编辑器支持 Markdown 编辑,左边编写,右边预览。',
|
||||
contentUnsaved: '编辑内容未保存,需要保存吗?',
|
||||
noDocNeedPublish: '没有需要发布的文档',
|
||||
loadDocFailed: '文档加载失败',
|
||||
fetchDocFailed: '获取当前文档信息失败',
|
||||
cannotAddToEmptyNode: '空节点不能添加内容',
|
||||
overrideModified: '文档已被其他人修改确定覆盖已存在的文档吗?',
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
contentsNameEmpty: '目录名称不能为空',
|
||||
addDoc: '添加文档',
|
||||
edit: '编辑',
|
||||
delete: '删除',
|
||||
loadFailed: '加载失败请重试',
|
||||
tplNameEmpty: '模板名称不能为空',
|
||||
tplContentEmpty: '模板内容不能为空',
|
||||
saveSucc: '保存成功',
|
||||
serverExcept: '服务器异常',
|
||||
paramName: '参数名称',
|
||||
paramType: '参数类型',
|
||||
example: '示例值',
|
||||
remark: '备注',
|
||||
},
|
||||
'en': {
|
||||
placeholder: 'This editor supports Markdown editing, writing on the left and previewing on the right.',
|
||||
contentUnsaved: 'The edited content is not saved, need to save it?',
|
||||
noDocNeedPublish: 'No Document need to be publish',
|
||||
loadDocFailed: 'Load Document failed',
|
||||
fetchDocFailed: 'Fetch Document info failed',
|
||||
cannotAddToEmptyNode: 'Cannot add content to empty node',
|
||||
overrideModified: 'The document has been modified by someone else, are you sure to overwrite the document?',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
contentsNameEmpty: 'Document Name cannot be empty',
|
||||
addDoc: 'Add Document',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
loadFailed: 'Failed to load, please try again',
|
||||
tplNameEmpty: 'Template name cannot be empty',
|
||||
tplContentEmpty: 'Template content cannot be empty',
|
||||
saveSucc: 'Save success',
|
||||
serverExcept: 'Server Exception',
|
||||
paramName: 'Parameter',
|
||||
paramType: 'Type',
|
||||
example: 'Example',
|
||||
remark: 'Remark',
|
||||
}
|
||||
};
|
||||
var htmlDecodeList = ["style","script","title","onmouseover","onmouseout","style"];
|
||||
if (!window.IS_ENABLE_IFRAME) {
|
||||
htmlDecodeList.unshift("iframe");
|
||||
}
|
||||
window.editor = editormd("docEditor", {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
path: window.editormdLib,
|
||||
toolbar: true,
|
||||
placeholder: "本编辑器支持 Markdown 编辑,左边编写,右边预览。",
|
||||
placeholder: window.editormdLocales[window.lang].placeholder,
|
||||
imageUpload: true,
|
||||
imageFormats: ["jpg", "jpeg", "gif", "png","svg", "JPG", "JPEG", "GIF", "PNG","SVG"],
|
||||
imageUploadURL: window.imageUploadURL,
|
||||
@@ -18,8 +72,8 @@ $(function () {
|
||||
fileUploadURL: window.fileUploadURL,
|
||||
taskList: true,
|
||||
flowChart: true,
|
||||
htmlDecode: "style,script,iframe,title,onmouseover,onmouseout,style",
|
||||
lineNumbers: false,
|
||||
htmlDecode: htmlDecodeList.join(','),
|
||||
lineNumbers: true,
|
||||
sequenceDiagram: true,
|
||||
tocStartLevel: 1,
|
||||
tocm: true,
|
||||
@@ -57,6 +111,7 @@ $(function () {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.isLoad = true;
|
||||
},
|
||||
onchange: function () {
|
||||
@@ -110,7 +165,7 @@ $(function () {
|
||||
} else if (name === "release") {
|
||||
if (Object.prototype.toString.call(window.documentCategory) === '[object Array]' && window.documentCategory.length > 0) {
|
||||
if ($("#markdown-save").hasClass('change')) {
|
||||
var confirm_result = confirm("编辑内容未保存,需要保存吗?");
|
||||
var confirm_result = confirm(editormdLocales[lang].contentUnsaved);
|
||||
if (confirm_result) {
|
||||
saveDocument(false, releaseBook);
|
||||
return;
|
||||
@@ -119,7 +174,7 @@ $(function () {
|
||||
|
||||
releaseBook();
|
||||
} else {
|
||||
layer.msg("没有需要发布的文档")
|
||||
layer.msg(editormdLocales[lang].noDocNeedPublish)
|
||||
}
|
||||
} else if (name === "tasks") {
|
||||
// 插入 GFM 任务列表
|
||||
@@ -141,7 +196,7 @@ $(function () {
|
||||
} else {
|
||||
var action = window.editor.toolbarHandlers[name];
|
||||
|
||||
if (action !== "undefined") {
|
||||
if (!!action && action !== "undefined") {
|
||||
$.proxy(action, window.editor)();
|
||||
window.editor.focus();
|
||||
}
|
||||
@@ -175,11 +230,11 @@ $(function () {
|
||||
pushVueLists(res.data.attach);
|
||||
setLastSelectNode($node);
|
||||
} else {
|
||||
layer.msg("文档加载失败");
|
||||
layer.msg(editormdLocales[lang].loadDocFailed);
|
||||
}
|
||||
}).fail(function () {
|
||||
layer.close(index);
|
||||
layer.msg("文档加载失败");
|
||||
layer.msg(editormdLocales[lang].loadDocFailed);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -195,11 +250,11 @@ $(function () {
|
||||
var version = "";
|
||||
|
||||
if (!node) {
|
||||
layer.msg("获取当前文档信息失败");
|
||||
layer.msg(editormdLocales[lang].fetchDocFailed);
|
||||
return;
|
||||
}
|
||||
if (node.a_attr && node.a_attr.disabled) {
|
||||
layer.msg("空节点不能添加内容");
|
||||
layer.msg(editormdLocales[lang].cannotAddToEmptyNode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,8 +301,8 @@ $(function () {
|
||||
}
|
||||
|
||||
} else if(res.errcode === 6005) {
|
||||
var confirmIndex = layer.confirm('文档已被其他人修改确定覆盖已存在的文档吗?', {
|
||||
btn: ['确定', '取消'] // 按钮
|
||||
var confirmIndex = layer.confirm(editormdLocales[lang].overrideModified, {
|
||||
btn: [editormdLocales[lang].confirm, editormdLocales[lang].cancel] // 按钮
|
||||
}, function() {
|
||||
layer.close(confirmIndex);
|
||||
saveDocument(true, callback);
|
||||
@@ -257,7 +312,7 @@ $(function () {
|
||||
}
|
||||
},
|
||||
error : function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
layer.msg("服务器错误:" + errorThrown);
|
||||
layer.msg(window.editormdLocales[window.lang].serverExcept + errorThrown);
|
||||
},
|
||||
complete :function () {
|
||||
layer.close(index);
|
||||
@@ -287,7 +342,7 @@ $(function () {
|
||||
beforeSubmit: function () {
|
||||
var doc_name = $.trim($("#documentName").val());
|
||||
if (doc_name === "") {
|
||||
return showError("目录名称不能为空", "#add-error-message")
|
||||
return showError(editormdLocales[lang].contentsNameEmpty, "#add-error-message")
|
||||
}
|
||||
$("#btnSaveDocument").button("loading");
|
||||
return true;
|
||||
@@ -347,7 +402,7 @@ $(function () {
|
||||
"separator_before": false,
|
||||
"separator_after": true,
|
||||
"_disabled": false,
|
||||
"label": "添加文档",
|
||||
"label": window.editormdLocales[window.lang].addDoc,//"添加文档",
|
||||
"icon": "fa fa-plus",
|
||||
"action": function (data) {
|
||||
var inst = $.jstree.reference(data.reference),
|
||||
@@ -360,7 +415,7 @@ $(function () {
|
||||
"separator_before": false,
|
||||
"separator_after": true,
|
||||
"_disabled": false,
|
||||
"label": "编辑",
|
||||
"label": window.editormdLocales[window.lang].edit,
|
||||
"icon": "fa fa-edit",
|
||||
"action": function (data) {
|
||||
var inst = $.jstree.reference(data.reference);
|
||||
@@ -372,7 +427,7 @@ $(function () {
|
||||
"separator_before": false,
|
||||
"separator_after": true,
|
||||
"_disabled": false,
|
||||
"label": "删除",
|
||||
"label": window.editormdLocales[window.lang].delete,
|
||||
"icon": "fa fa-trash-o",
|
||||
"action": function (data) {
|
||||
var inst = $.jstree.reference(data.reference);
|
||||
@@ -390,7 +445,7 @@ $(function () {
|
||||
}).on('select_node.jstree', function (node, selected) {
|
||||
|
||||
if ($("#markdown-save").hasClass('change')) {
|
||||
if (confirm("编辑内容未保存,需要保存吗?")) {
|
||||
if (confirm(window.editormdLocales[window.lang].contentUnsaved)) {
|
||||
saveDocument(false, function () {
|
||||
loadDocument(selected);
|
||||
});
|
||||
@@ -446,7 +501,7 @@ $(function () {
|
||||
$("#displayCustomsTemplateList").html($res);
|
||||
},
|
||||
error : function () {
|
||||
layer.msg("加载失败请重试");
|
||||
layer.msg(window.editormdLocales[window.lang].loadFailed);
|
||||
},
|
||||
complete : function () {
|
||||
layer.close(index);
|
||||
@@ -464,11 +519,11 @@ $(function () {
|
||||
beforeSubmit: function () {
|
||||
var doc_name = $.trim($("#templateName").val());
|
||||
if (doc_name === "") {
|
||||
return showError("模板名称不能为空", "#saveTemplateForm .show-error-message");
|
||||
return showError(window.editormdLocales[window.lang].tplNameEmpty, "#saveTemplateForm .show-error-message");
|
||||
}
|
||||
var content = $("#saveTemplateForm").find("input[name='content']").val();
|
||||
if (content === ""){
|
||||
return showError("模板内容不能为空", "#saveTemplateForm .show-error-message");
|
||||
return showError(window.editormdLocales[window.lang].tplContentEmpty, "#saveTemplateForm .show-error-message");
|
||||
}
|
||||
|
||||
$("#btnSaveTemplate").button("loading");
|
||||
@@ -478,7 +533,7 @@ $(function () {
|
||||
success: function ($res) {
|
||||
if($res.errcode === 0){
|
||||
$("#saveTemplateModal").modal("hide");
|
||||
layer.msg("保存成功");
|
||||
layer.msg(window.editormdLocales[window.lang].saveSucc);
|
||||
}else{
|
||||
return showError($res.message, "#saveTemplateForm .show-error-message");
|
||||
}
|
||||
@@ -521,7 +576,7 @@ $(function () {
|
||||
resetEditorChanged(true);
|
||||
$("#displayCustomsTemplateModal").modal("hide");
|
||||
},error : function () {
|
||||
layer.msg("服务器异常");
|
||||
layer.msg(window.editormdLocales[window.lang].serverExcept);
|
||||
}
|
||||
});
|
||||
}).on("click",".btn-delete",function () {
|
||||
@@ -541,7 +596,7 @@ $(function () {
|
||||
$then.parents("tr").empty().remove();
|
||||
}
|
||||
},error : function () {
|
||||
layer.msg("服务器异常");
|
||||
layer.msg(window.editormdLocales[window.lang].serverExcept);
|
||||
},
|
||||
complete: function () {
|
||||
$then.button("reset");
|
||||
@@ -555,7 +610,11 @@ $(function () {
|
||||
try {
|
||||
var jsonObj = $.parseJSON(content);
|
||||
var data = foreachJson(jsonObj,"");
|
||||
var table = "| 参数名称 | 参数类型 | 示例值 | 备注 |\n| ------------ | ------------ | ------------ | ------------ |\n";
|
||||
var table = "| " + window.editormdLocales[window.lang].paramName
|
||||
+ " | " + window.editormdLocales[window.lang].paramType
|
||||
+ " | " + window.editormdLocales[window.lang].example
|
||||
+ " | " + window.editormdLocales[window.lang].remark
|
||||
+ " |\n| ------------ | ------------ | ------------ | ------------ |\n";
|
||||
$.each(data,function (i,item) {
|
||||
table += "|" + item.key + "|" + item.type + "|" + item.value +"| |\n";
|
||||
});
|
||||
|
||||
42
static/js/wangEditor-plugins/attach-menu.js
Normal file
42
static/js/wangEditor-plugins/attach-menu.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function () {
|
||||
|
||||
// 获取 wangEditor 构造函数和 jquery
|
||||
var E = window.wangEditor;
|
||||
var $ = window.jQuery;
|
||||
|
||||
let AttachMenu = (function (_BtnMenu) {
|
||||
c2b_inherits(AttachMenu, _BtnMenu);
|
||||
|
||||
var _super = c2b_createSuper(AttachMenu);
|
||||
|
||||
function AttachMenu(editor) {
|
||||
c2b_classCallCheck(this, AttachMenu);
|
||||
|
||||
const $elem = E.$(`<div class="w-e-menu" data-title="附件">
|
||||
<i class="fa fa-paperclip" aria-hidden="true"></i>
|
||||
</div>`);
|
||||
return _super.call(this, $elem, editor);
|
||||
}
|
||||
|
||||
c2b_createClass(AttachMenu, [
|
||||
{
|
||||
key: "clickHandler",
|
||||
value: function clickHandler() {
|
||||
$("#uploadAttachModal").modal("show");
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "tryChangeActive",
|
||||
value: function tryChangeActive() {
|
||||
// this.active();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
return AttachMenu;
|
||||
})(E.BtnMenu);
|
||||
|
||||
|
||||
var menuKey = 'attach';
|
||||
E.registerMenu(menuKey, AttachMenu);
|
||||
})();
|
||||
42
static/js/wangEditor-plugins/history-menu.js
Normal file
42
static/js/wangEditor-plugins/history-menu.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function () {
|
||||
|
||||
// 获取 wangEditor 构造函数和 jquery
|
||||
var E = window.wangEditor;
|
||||
var $ = window.jQuery;
|
||||
|
||||
let HistoryMenu = (function (_BtnMenu) {
|
||||
c2b_inherits(HistoryMenu, _BtnMenu);
|
||||
|
||||
var _super = c2b_createSuper(HistoryMenu);
|
||||
|
||||
function HistoryMenu(editor) {
|
||||
c2b_classCallCheck(this, HistoryMenu);
|
||||
|
||||
const $elem = E.$(`<div class="w-e-menu" data-title="history">
|
||||
<i class="fa fa-history" aria-hidden="true"></i>
|
||||
</div>`);
|
||||
return _super.call(this, $elem, editor);
|
||||
}
|
||||
|
||||
c2b_createClass(HistoryMenu, [
|
||||
{
|
||||
key: "clickHandler",
|
||||
value: function clickHandler() {
|
||||
window.documentHistory();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "tryChangeActive",
|
||||
value: function tryChangeActive() {
|
||||
// this.active();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
return HistoryMenu;
|
||||
})(E.BtnMenu);
|
||||
|
||||
|
||||
var menuKey = '历史';
|
||||
E.registerMenu(menuKey, HistoryMenu);
|
||||
})();
|
||||
42
static/js/wangEditor-plugins/release-menu.js
Normal file
42
static/js/wangEditor-plugins/release-menu.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function () {
|
||||
|
||||
// 获取 wangEditor 构造函数和 jquery
|
||||
var E = window.wangEditor;
|
||||
var $ = window.jQuery;
|
||||
|
||||
let ReleaseMenu = (function (_BtnMenu) {
|
||||
c2b_inherits(ReleaseMenu, _BtnMenu);
|
||||
|
||||
var _super = c2b_createSuper(ReleaseMenu);
|
||||
|
||||
function ReleaseMenu(editor) {
|
||||
c2b_classCallCheck(this, ReleaseMenu);
|
||||
|
||||
const $elem = E.$(`<div class="w-e-menu" data-title="发布">
|
||||
<i class="fa fa-cloud-upload" aria-hidden="true"></i>
|
||||
</div>`);
|
||||
return _super.call(this, $elem, editor);
|
||||
}
|
||||
|
||||
c2b_createClass(ReleaseMenu, [
|
||||
{
|
||||
key: "clickHandler",
|
||||
value: function clickHandler() {
|
||||
window.releaseBook();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "tryChangeActive",
|
||||
value: function tryChangeActive() {
|
||||
// this.active();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
return ReleaseMenu;
|
||||
})(E.BtnMenu);
|
||||
|
||||
|
||||
var menuKey = 'release';
|
||||
E.registerMenu(menuKey, ReleaseMenu);
|
||||
})();
|
||||
42
static/js/wangEditor-plugins/save-menu.js
Normal file
42
static/js/wangEditor-plugins/save-menu.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function () {
|
||||
|
||||
// 获取 wangEditor 构造函数和 jquery
|
||||
var E = window.wangEditor;
|
||||
var $ = window.jQuery;
|
||||
|
||||
let SaveMenu = (function (_BtnMenu) {
|
||||
c2b_inherits(SaveMenu, _BtnMenu);
|
||||
|
||||
var _super = c2b_createSuper(SaveMenu);
|
||||
|
||||
function SaveMenu(editor) {
|
||||
c2b_classCallCheck(this, SaveMenu);
|
||||
|
||||
const $elem = E.$(`<div class="w-e-menu" data-title="保存">
|
||||
<i class="fa fa-floppy-o" aria-hidden="true"></i>
|
||||
</div>`);
|
||||
return _super.call(this, $elem, editor);
|
||||
}
|
||||
|
||||
c2b_createClass(SaveMenu, [
|
||||
{
|
||||
key: "clickHandler",
|
||||
value: function clickHandler() {
|
||||
window.saveDocument();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "tryChangeActive",
|
||||
value: function tryChangeActive() {
|
||||
// this.active();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
return SaveMenu;
|
||||
})(E.BtnMenu);
|
||||
|
||||
|
||||
var menuKey = 'save';
|
||||
E.registerMenu(menuKey, SaveMenu);
|
||||
})();
|
||||
87
static/js/x-frame-bypass-1.0.2.js
Normal file
87
static/js/x-frame-bypass-1.0.2.js
Normal file
@@ -0,0 +1,87 @@
|
||||
customElements.define('x-frame-bypass', class extends HTMLIFrameElement {
|
||||
static get observedAttributes() {
|
||||
return ['src']
|
||||
}
|
||||
constructor () {
|
||||
super()
|
||||
}
|
||||
attributeChangedCallback () {
|
||||
this.load(this.src)
|
||||
}
|
||||
connectedCallback () {
|
||||
this.sandbox = '' + this.sandbox || 'allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation' // all except allow-top-navigation
|
||||
}
|
||||
load (url, options) {
|
||||
if (!url || !url.startsWith('http'))
|
||||
throw new Error(`X-Frame-Bypass src ${url} does not start with http(s)://`)
|
||||
console.log('X-Frame-Bypass loading:', url)
|
||||
this.srcdoc = `<html>
|
||||
<head>
|
||||
<style>
|
||||
.loader {
|
||||
position: absolute;
|
||||
top: calc(50% - 25px);
|
||||
left: calc(50% - 25px);
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background-color: #333;
|
||||
border-radius: 50%;
|
||||
animation: loader 1s infinite ease-in-out;
|
||||
}
|
||||
@keyframes loader {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="loader"></div>
|
||||
</body>
|
||||
</html>`
|
||||
this.fetchProxy(url, options, 0).then(res => res.text()).then(data => {
|
||||
if (data)
|
||||
this.srcdoc = data.replace(/<head([^>]*)>/i, `<head$1>
|
||||
<base href="${url}">
|
||||
<script>
|
||||
// X-Frame-Bypass navigation event handlers
|
||||
document.addEventListener('click', e => {
|
||||
if (frameElement && document.activeElement && document.activeElement.href) {
|
||||
e.preventDefault()
|
||||
frameElement.load(document.activeElement.href)
|
||||
}
|
||||
})
|
||||
document.addEventListener('submit', e => {
|
||||
if (frameElement && document.activeElement && document.activeElement.form && document.activeElement.form.action) {
|
||||
e.preventDefault()
|
||||
if (document.activeElement.form.method === 'post')
|
||||
frameElement.load(document.activeElement.form.action, {method: 'post', body: new FormData(document.activeElement.form)})
|
||||
else
|
||||
frameElement.load(document.activeElement.form.action + '?' + new URLSearchParams(new FormData(document.activeElement.form)))
|
||||
}
|
||||
})
|
||||
</script>`)
|
||||
}).catch(e => console.error('Cannot load X-Frame-Bypass:', e))
|
||||
}
|
||||
fetchProxy (url, options, i) {
|
||||
const proxies = (options || {}).proxies || [
|
||||
window.BASE_URL + 'cors-anywhere?url=',
|
||||
'https://cors-anywhere.herokuapp.com/',
|
||||
'https://yacdn.org/proxy/',
|
||||
'https://api.codetabs.com/v1/proxy/?quest='
|
||||
]
|
||||
return fetch(proxies[i] + url, options).then(res => {
|
||||
if (!res.ok)
|
||||
throw new Error(`${res.status} ${res.statusText}`);
|
||||
return res
|
||||
}).catch(error => {
|
||||
if (i === proxies.length - 1)
|
||||
throw error
|
||||
return this.fetchProxy(url, options, i + 1)
|
||||
})
|
||||
}
|
||||
}, {extends: 'iframe'})
|
||||
Reference in New Issue
Block a user