mirror of
https://github.com/marktext/marktext.git
synced 2025-05-01 20:42:02 +08:00
[WIP] Support Diagram (#529)
* feat: basic use of mermaid * feat: add flowchart dep * feat: handle flowchart render error * feat: edit sequence diagram * feat: support vega-lite * fix: #534 * feat: basic use of mermaid * feat: add flowchart dep * feat: handle flowchart render error * feat: edit sequence diagram * feat: support vega-lite * feat: copy paste and import and export of diagram * finish * fix: #537 * update: dependence
This commit is contained in:
parent
f43504b2d0
commit
55092ff15d
@ -1,5 +1,5 @@
|
||||
test/unit/coverage/**
|
||||
test/unit/*.js
|
||||
test/e2e/*.js
|
||||
src/muya/lib/assets/symbolIcon/index.js
|
||||
src/renderer/assets/symbolIcon/index.js
|
||||
src/muya/lib/assets/libs/*.js
|
||||
|
1596
package-lock.json
generated
1596
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@ -136,18 +136,25 @@
|
||||
"dompurify": "^1.0.8",
|
||||
"element-ui": "^2.4.7",
|
||||
"file-icons-js": "^1.0.3",
|
||||
"flowchart.js": "^1.11.3",
|
||||
"fs-extra": "^7.0.0",
|
||||
"fuzzaldrin": "^2.1.0",
|
||||
"github-markdown-css": "^2.10.0",
|
||||
"html-tags": "^2.0.0",
|
||||
"katex": "^0.10.0-rc.1",
|
||||
"katex": "^0.10.0",
|
||||
"markdown-toc": "^1.2.0",
|
||||
"mermaid": "^8.0.0-rc.8",
|
||||
"popper.js": "^1.14.4",
|
||||
"prismjs2": "^1.15.0",
|
||||
"snabbdom": "^0.7.2",
|
||||
"snabbdom-to-html": "^5.1.1",
|
||||
"snapsvg": "^0.5.1",
|
||||
"turndown": "^5.0.1",
|
||||
"turndown-plugin-gfm": "^1.0.2",
|
||||
"underscore": "^1.9.1",
|
||||
"vega": "^4.3.0",
|
||||
"vega-embed": "^3.21.1",
|
||||
"vega-lite": "^3.0.0-rc8",
|
||||
"vue": "^2.5.17",
|
||||
"vue-electron": "^1.0.6",
|
||||
"vuex": "^3.0.1"
|
||||
@ -170,12 +177,12 @@
|
||||
"css-loader": "^1.0.0",
|
||||
"del": "^3.0.0",
|
||||
"devtron": "^1.4.0",
|
||||
"electron": "^3.0.5",
|
||||
"electron-builder": "^20.28.4",
|
||||
"electron": "^3.0.7",
|
||||
"electron-builder": "^20.29.0",
|
||||
"electron-debug": "^2.0.0",
|
||||
"electron-devtools-installer": "^2.2.4",
|
||||
"electron-updater": "^3.1.2",
|
||||
"electron-window-state": "^5.0.1",
|
||||
"electron-updater": "^3.1.6",
|
||||
"electron-window-state": "^5.0.2",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-config-standard": "^11.0.0",
|
||||
"eslint-friendly-formatter": "^4.0.1",
|
||||
|
@ -80,7 +80,7 @@ let viewMenu = {
|
||||
}]
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' || process.env.NODE_ENV === 'development') {
|
||||
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'development') {
|
||||
// add devtool when development
|
||||
viewMenu.submenu.push({
|
||||
label: 'Toggle Developer Tools',
|
||||
|
1
src/muya/lib/assets/icons/chart.svg
Normal file
1
src/muya/lib/assets/icons/chart.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1540911659576" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2485" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M597.333 85.333c-47.128 0-85.333 38.205-85.333 85.334 0 7.805 0.704 15.483 2.667 22.666L424 266.667C412.03 260.269 398.521 256 384 256c-28.074 0-52.448 13.742-68 34.667l-62.667-13.334c-9.47-36.808-42.902-64-82.666-64-47.129 0-85.334 38.205-85.334 85.334 0 47.128 38.205 85.333 85.334 85.333 30.093 0 56.807-15.136 72-38.667l57.333 12c7.457 39.52 42.312 69.334 84 69.334 47.128 0 85.333-38.205 85.333-85.334 0-7.805-0.703-15.483-2.666-22.666l90.666-72c11.837 6.213 25.704 9.333 40 9.333 13.884 0 27.081-3.451 38.667-9.333L772 360c-2.259 7.663-4 15.605-4 24 0 47.128 38.205 85.333 85.333 85.333 47.129 0 85.334-38.205 85.334-85.333s-38.205-85.333-85.334-85.333c-13.883 0-27.08 3.45-38.666 9.333l-136-113.333c2.259-7.663 4-15.606 4-24 0-47.129-38.205-85.334-85.334-85.334zM512 512v426.667h170.667V512H512z m213.333 128v298.667H896V640H725.333z m-640 42.667v256H256v-256H85.333z m213.334 42.666v213.334h170.666V725.333H298.667z" p-id="2486"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/muya/lib/assets/icons/flowchart.svg
Normal file
1
src/muya/lib/assets/icons/flowchart.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1540728996967" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2678" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M460.196316 192.395705l-97.49618 97.49618L162.792167 289.891885c-7.100597 0-13.245353 2.594376-18.434106 7.783293s-7.783293 11.333509-7.783293 18.434106l0 313.790167c-15.839729 16.385854-28.538794 38.506911-38.097195 66.36301s-14.337601 58.443145-14.337601 91.76114c0 50.79626 10.241261 94.082372 30.723619 129.858335s45.197792 53.663945 74.146302 53.663945c26.217398 0 49.021152-15.020461 68.411098-45.06122 19.389946-30.040759 30.996599-67.455258 34.820123-112.243498l106.508457 0 0 157.304718c0 14.201029 5.188916 26.490542 15.566585 36.868211 10.377669 10.377833 22.667182 15.566585 36.868375 15.566585l104.869757 0c14.747317 0 27.173238-5.188916 37.277927-15.566585 10.104689-10.377669 15.157033-22.667182 15.157033-36.868211l0-157.304718 106.508457 0c3.82336 44.788076 15.430013 82.202575 34.820123 112.243498 19.389946 30.040759 42.1937 45.06122 68.411098 45.06122 28.948347 0 53.663945-17.887982 74.146302-53.663945s30.723619-79.062075 30.723619-129.858335-10.241261-94.082536-30.723619-129.858335-45.197792-53.663781-74.146302-53.663781c-26.217398 0-49.021152 15.020461-68.411098 45.06122-19.39011 30.040759-30.996763 67.455258-34.820123 112.243498l-106.508457 0L608.489249 604.501321c0-14.747317-5.052344-27.173238-15.157033-37.277927-10.104689-10.104689-22.53061-15.157033-37.277927-15.157033L503.619 552.06636 503.619 432.449286l98.315449-98.315449c4.915772-4.915772 7.373577-10.787385 7.373577-17.614838s-2.457968-12.699065-7.373577-17.614838l-106.508457-106.508457c-4.915772-4.915772-10.787385-7.373577-17.614838-7.373577S465.112089 187.479933 460.196316 192.395705zM398.749243 604.501321l0 157.304718-106.508457 0c-3.82336-44.78824-15.430013-82.202739-34.820123-112.243498-19.389946-30.040759-42.1937-45.06122-68.411098-45.06122L189.009565 342.326846l172.871303 0 89.303172 89.303172 0 120.436506c-14.201193 0-26.490542 5.052344-36.868375 15.157033C403.938159 577.328082 398.749243 589.754003 398.749243 604.501321z" p-id="2679"></path></svg>
|
After Width: | Height: | Size: 2.3 KiB |
1
src/muya/lib/assets/icons/mermaid.svg
Normal file
1
src/muya/lib/assets/icons/mermaid.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1540728845770" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="677" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M85.333333 213.333333h341.333334V85.333333h85.333333v853.333334h-85.333333v-170.666667H256v-128h170.666667v-85.333333H170.666667v-128h256V341.333333H85.333333V213.333333m512 0h128v128h-128V213.333333m0 213.333334h213.333334v128h-213.333334v-128m0 213.333333h341.333334v128h-341.333334v-128z" fill="" p-id="678"></path></svg>
|
After Width: | Height: | Size: 709 B |
1
src/muya/lib/assets/icons/sequence.svg
Normal file
1
src/muya/lib/assets/icons/sequence.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1540728926061" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2165" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M211.91 606.15V409.82a111.23 111.23 0 0 0 0-210.65V99a36 36 0 0 0-72 0v100.33a111.23 111.23 0 0 0 0 210.32v197.18c-43.62 15.91-75 59.15-75 109.88s31.37 94 75 109.88V922a36 36 0 0 0 72 0v-94.73c44.62-15.33 76.91-59.09 76.91-110.56s-32.29-95.23-76.91-110.56z m-35.76-340.88a39.22 39.22 0 1 1-39.22 39.22 39.27 39.27 0 0 1 39.22-39.22z m0.73 495.84c-22 0-40-19.92-40-44.4s17.92-44.4 40-44.4 40 19.92 40 44.4-17.98 44.4-40.01 44.4z m242.95-477.32h401a36 36 0 0 0 0-72h-401a36 36 0 0 0 0 72z m0 139.01h246.92a36 36 0 0 0 0-72H419.83a36 36 0 0 0 0 72z m401.02 199.25h-401a36 36 0 0 0 0 72h401a36 36 0 0 0 0-72z m-154.1 139H419.83a36 36 0 1 0 0 72h246.92a36 36 0 0 0 0-72z" fill="" p-id="2166"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
142
src/muya/lib/assets/libs/raphael.js
Normal file
142
src/muya/lib/assets/libs/raphael.js
Normal file
File diff suppressed because one or more lines are too long
2698
src/muya/lib/assets/libs/sequence-diagram.js
Executable file
2698
src/muya/lib/assets/libs/sequence-diagram.js
Executable file
File diff suppressed because it is too large
Load Diff
17
src/muya/lib/assets/libs/webFontLoader.js
Normal file
17
src/muya/lib/assets/libs/webFontLoader.js
Normal file
@ -0,0 +1,17 @@
|
||||
/* Web Font Loader v1.6.28 - (c) Adobe Systems, Google. License: Apache 2.0 */(function(){function aa(a,b,c){return a.call.apply(a.bind,arguments)}function ba(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function p(a,b,c){p=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?aa:ba;return p.apply(null,arguments)}var q=Date.now||function(){return+new Date};function ca(a,b){this.a=a;this.o=b||a;this.c=this.o.document}var da=!!window.FontFace;function t(a,b,c,d){b=a.c.createElement(b);if(c)for(var e in c)c.hasOwnProperty(e)&&("style"==e?b.style.cssText=c[e]:b.setAttribute(e,c[e]));d&&b.appendChild(a.c.createTextNode(d));return b}function u(a,b,c){a=a.c.getElementsByTagName(b)[0];a||(a=document.documentElement);a.insertBefore(c,a.lastChild)}function v(a){a.parentNode&&a.parentNode.removeChild(a)}
|
||||
function w(a,b,c){b=b||[];c=c||[];for(var d=a.className.split(/\s+/),e=0;e<b.length;e+=1){for(var f=!1,g=0;g<d.length;g+=1)if(b[e]===d[g]){f=!0;break}f||d.push(b[e])}b=[];for(e=0;e<d.length;e+=1){f=!1;for(g=0;g<c.length;g+=1)if(d[e]===c[g]){f=!0;break}f||b.push(d[e])}a.className=b.join(" ").replace(/\s+/g," ").replace(/^\s+|\s+$/,"")}function y(a,b){for(var c=a.className.split(/\s+/),d=0,e=c.length;d<e;d++)if(c[d]==b)return!0;return!1}
|
||||
function ea(a){return a.o.location.hostname||a.a.location.hostname}function z(a,b,c){function d(){m&&e&&f&&(m(g),m=null)}b=t(a,"link",{rel:"stylesheet",href:b,media:"all"});var e=!1,f=!0,g=null,m=c||null;da?(b.onload=function(){e=!0;d()},b.onerror=function(){e=!0;g=Error("Stylesheet failed to load");d()}):setTimeout(function(){e=!0;d()},0);u(a,"head",b)}
|
||||
function A(a,b,c,d){var e=a.c.getElementsByTagName("head")[0];if(e){var f=t(a,"script",{src:b}),g=!1;f.onload=f.onreadystatechange=function(){g||this.readyState&&"loaded"!=this.readyState&&"complete"!=this.readyState||(g=!0,c&&c(null),f.onload=f.onreadystatechange=null,"HEAD"==f.parentNode.tagName&&e.removeChild(f))};e.appendChild(f);setTimeout(function(){g||(g=!0,c&&c(Error("Script load timeout")))},d||5E3);return f}return null};function B(){this.a=0;this.c=null}function C(a){a.a++;return function(){a.a--;D(a)}}function E(a,b){a.c=b;D(a)}function D(a){0==a.a&&a.c&&(a.c(),a.c=null)};function F(a){this.a=a||"-"}F.prototype.c=function(a){for(var b=[],c=0;c<arguments.length;c++)b.push(arguments[c].replace(/[\W_]+/g,"").toLowerCase());return b.join(this.a)};function G(a,b){this.c=a;this.f=4;this.a="n";var c=(b||"n4").match(/^([nio])([1-9])$/i);c&&(this.a=c[1],this.f=parseInt(c[2],10))}function fa(a){return H(a)+" "+(a.f+"00")+" 300px "+I(a.c)}function I(a){var b=[];a=a.split(/,\s*/);for(var c=0;c<a.length;c++){var d=a[c].replace(/['"]/g,"");-1!=d.indexOf(" ")||/^\d/.test(d)?b.push("'"+d+"'"):b.push(d)}return b.join(",")}function J(a){return a.a+a.f}function H(a){var b="normal";"o"===a.a?b="oblique":"i"===a.a&&(b="italic");return b}
|
||||
function ga(a){var b=4,c="n",d=null;a&&((d=a.match(/(normal|oblique|italic)/i))&&d[1]&&(c=d[1].substr(0,1).toLowerCase()),(d=a.match(/([1-9]00|normal|bold)/i))&&d[1]&&(/bold/i.test(d[1])?b=7:/[1-9]00/.test(d[1])&&(b=parseInt(d[1].substr(0,1),10))));return c+b};function ha(a,b){this.c=a;this.f=a.o.document.documentElement;this.h=b;this.a=new F("-");this.j=!1!==b.events;this.g=!1!==b.classes}function ia(a){a.g&&w(a.f,[a.a.c("wf","loading")]);K(a,"loading")}function L(a){if(a.g){var b=y(a.f,a.a.c("wf","active")),c=[],d=[a.a.c("wf","loading")];b||c.push(a.a.c("wf","inactive"));w(a.f,c,d)}K(a,"inactive")}function K(a,b,c){if(a.j&&a.h[b])if(c)a.h[b](c.c,J(c));else a.h[b]()};function ja(){this.c={}}function ka(a,b,c){var d=[],e;for(e in b)if(b.hasOwnProperty(e)){var f=a.c[e];f&&d.push(f(b[e],c))}return d};function M(a,b){this.c=a;this.f=b;this.a=t(this.c,"span",{"aria-hidden":"true"},this.f)}function N(a){u(a.c,"body",a.a)}function O(a){return"display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:"+I(a.c)+";"+("font-style:"+H(a)+";font-weight:"+(a.f+"00")+";")};function P(a,b,c,d,e,f){this.g=a;this.j=b;this.a=d;this.c=c;this.f=e||3E3;this.h=f||void 0}P.prototype.start=function(){var a=this.c.o.document,b=this,c=q(),d=new Promise(function(d,e){function f(){q()-c>=b.f?e():a.fonts.load(fa(b.a),b.h).then(function(a){1<=a.length?d():setTimeout(f,25)},function(){e()})}f()}),e=null,f=new Promise(function(a,d){e=setTimeout(d,b.f)});Promise.race([f,d]).then(function(){e&&(clearTimeout(e),e=null);b.g(b.a)},function(){b.j(b.a)})};function Q(a,b,c,d,e,f,g){this.v=a;this.B=b;this.c=c;this.a=d;this.s=g||"BESbswy";this.f={};this.w=e||3E3;this.u=f||null;this.m=this.j=this.h=this.g=null;this.g=new M(this.c,this.s);this.h=new M(this.c,this.s);this.j=new M(this.c,this.s);this.m=new M(this.c,this.s);a=new G(this.a.c+",serif",J(this.a));a=O(a);this.g.a.style.cssText=a;a=new G(this.a.c+",sans-serif",J(this.a));a=O(a);this.h.a.style.cssText=a;a=new G("serif",J(this.a));a=O(a);this.j.a.style.cssText=a;a=new G("sans-serif",J(this.a));a=
|
||||
O(a);this.m.a.style.cssText=a;N(this.g);N(this.h);N(this.j);N(this.m)}var R={D:"serif",C:"sans-serif"},S=null;function T(){if(null===S){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent);S=!!a&&(536>parseInt(a[1],10)||536===parseInt(a[1],10)&&11>=parseInt(a[2],10))}return S}Q.prototype.start=function(){this.f.serif=this.j.a.offsetWidth;this.f["sans-serif"]=this.m.a.offsetWidth;this.A=q();U(this)};
|
||||
function la(a,b,c){for(var d in R)if(R.hasOwnProperty(d)&&b===a.f[R[d]]&&c===a.f[R[d]])return!0;return!1}function U(a){var b=a.g.a.offsetWidth,c=a.h.a.offsetWidth,d;(d=b===a.f.serif&&c===a.f["sans-serif"])||(d=T()&&la(a,b,c));d?q()-a.A>=a.w?T()&&la(a,b,c)&&(null===a.u||a.u.hasOwnProperty(a.a.c))?V(a,a.v):V(a,a.B):ma(a):V(a,a.v)}function ma(a){setTimeout(p(function(){U(this)},a),50)}function V(a,b){setTimeout(p(function(){v(this.g.a);v(this.h.a);v(this.j.a);v(this.m.a);b(this.a)},a),0)};function W(a,b,c){this.c=a;this.a=b;this.f=0;this.m=this.j=!1;this.s=c}var X=null;W.prototype.g=function(a){var b=this.a;b.g&&w(b.f,[b.a.c("wf",a.c,J(a).toString(),"active")],[b.a.c("wf",a.c,J(a).toString(),"loading"),b.a.c("wf",a.c,J(a).toString(),"inactive")]);K(b,"fontactive",a);this.m=!0;na(this)};
|
||||
W.prototype.h=function(a){var b=this.a;if(b.g){var c=y(b.f,b.a.c("wf",a.c,J(a).toString(),"active")),d=[],e=[b.a.c("wf",a.c,J(a).toString(),"loading")];c||d.push(b.a.c("wf",a.c,J(a).toString(),"inactive"));w(b.f,d,e)}K(b,"fontinactive",a);na(this)};function na(a){0==--a.f&&a.j&&(a.m?(a=a.a,a.g&&w(a.f,[a.a.c("wf","active")],[a.a.c("wf","loading"),a.a.c("wf","inactive")]),K(a,"active")):L(a.a))};function oa(a){this.j=a;this.a=new ja;this.h=0;this.f=this.g=!0}oa.prototype.load=function(a){this.c=new ca(this.j,a.context||this.j);this.g=!1!==a.events;this.f=!1!==a.classes;pa(this,new ha(this.c,a),a)};
|
||||
function qa(a,b,c,d,e){var f=0==--a.h;(a.f||a.g)&&setTimeout(function(){var a=e||null,m=d||null||{};if(0===c.length&&f)L(b.a);else{b.f+=c.length;f&&(b.j=f);var h,l=[];for(h=0;h<c.length;h++){var k=c[h],n=m[k.c],r=b.a,x=k;r.g&&w(r.f,[r.a.c("wf",x.c,J(x).toString(),"loading")]);K(r,"fontloading",x);r=null;if(null===X)if(window.FontFace){var x=/Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent),xa=/OS X.*Version\/10\..*Safari/.exec(window.navigator.userAgent)&&/Apple/.exec(window.navigator.vendor);
|
||||
X=x?42<parseInt(x[1],10):xa?!1:!0}else X=!1;X?r=new P(p(b.g,b),p(b.h,b),b.c,k,b.s,n):r=new Q(p(b.g,b),p(b.h,b),b.c,k,b.s,a,n);l.push(r)}for(h=0;h<l.length;h++)l[h].start()}},0)}function pa(a,b,c){var d=[],e=c.timeout;ia(b);var d=ka(a.a,c,a.c),f=new W(a.c,b,e);a.h=d.length;b=0;for(c=d.length;b<c;b++)d[b].load(function(b,d,c){qa(a,f,b,d,c)})};function ra(a,b){this.c=a;this.a=b}
|
||||
ra.prototype.load=function(a){function b(){if(f["__mti_fntLst"+d]){var c=f["__mti_fntLst"+d](),e=[],h;if(c)for(var l=0;l<c.length;l++){var k=c[l].fontfamily;void 0!=c[l].fontStyle&&void 0!=c[l].fontWeight?(h=c[l].fontStyle+c[l].fontWeight,e.push(new G(k,h))):e.push(new G(k))}a(e)}else setTimeout(function(){b()},50)}var c=this,d=c.a.projectId,e=c.a.version;if(d){var f=c.c.o;A(this.c,(c.a.api||"https://fast.fonts.net/jsapi")+"/"+d+".js"+(e?"?v="+e:""),function(e){e?a([]):(f["__MonotypeConfiguration__"+
|
||||
d]=function(){return c.a},b())}).id="__MonotypeAPIScript__"+d}else a([])};function sa(a,b){this.c=a;this.a=b}sa.prototype.load=function(a){var b,c,d=this.a.urls||[],e=this.a.families||[],f=this.a.testStrings||{},g=new B;b=0;for(c=d.length;b<c;b++)z(this.c,d[b],C(g));var m=[];b=0;for(c=e.length;b<c;b++)if(d=e[b].split(":"),d[1])for(var h=d[1].split(","),l=0;l<h.length;l+=1)m.push(new G(d[0],h[l]));else m.push(new G(d[0]));E(g,function(){a(m,f)})};function ta(a,b){a?this.c=a:this.c=ua;this.a=[];this.f=[];this.g=b||""}var ua="https://fonts.googleapis.com/css";function va(a,b){for(var c=b.length,d=0;d<c;d++){var e=b[d].split(":");3==e.length&&a.f.push(e.pop());var f="";2==e.length&&""!=e[1]&&(f=":");a.a.push(e.join(f))}}
|
||||
function wa(a){if(0==a.a.length)throw Error("No fonts to load!");if(-1!=a.c.indexOf("kit="))return a.c;for(var b=a.a.length,c=[],d=0;d<b;d++)c.push(a.a[d].replace(/ /g,"+"));b=a.c+"?family="+c.join("%7C");0<a.f.length&&(b+="&subset="+a.f.join(","));0<a.g.length&&(b+="&text="+encodeURIComponent(a.g));return b};function ya(a){this.f=a;this.a=[];this.c={}}
|
||||
var za={latin:"BESbswy","latin-ext":"\u00e7\u00f6\u00fc\u011f\u015f",cyrillic:"\u0439\u044f\u0416",greek:"\u03b1\u03b2\u03a3",khmer:"\u1780\u1781\u1782",Hanuman:"\u1780\u1781\u1782"},Aa={thin:"1",extralight:"2","extra-light":"2",ultralight:"2","ultra-light":"2",light:"3",regular:"4",book:"4",medium:"5","semi-bold":"6",semibold:"6","demi-bold":"6",demibold:"6",bold:"7","extra-bold":"8",extrabold:"8","ultra-bold":"8",ultrabold:"8",black:"9",heavy:"9",l:"3",r:"4",b:"7"},Ba={i:"i",italic:"i",n:"n",normal:"n"},
|
||||
Ca=/^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i|normal|italic)?$/;
|
||||
function Da(a){for(var b=a.f.length,c=0;c<b;c++){var d=a.f[c].split(":"),e=d[0].replace(/\+/g," "),f=["n4"];if(2<=d.length){var g;var m=d[1];g=[];if(m)for(var m=m.split(","),h=m.length,l=0;l<h;l++){var k;k=m[l];if(k.match(/^[\w-]+$/)){var n=Ca.exec(k.toLowerCase());if(null==n)k="";else{k=n[2];k=null==k||""==k?"n":Ba[k];n=n[1];if(null==n||""==n)n="4";else var r=Aa[n],n=r?r:isNaN(n)?"4":n.substr(0,1);k=[k,n].join("")}}else k="";k&&g.push(k)}0<g.length&&(f=g);3==d.length&&(d=d[2],g=[],d=d?d.split(","):
|
||||
g,0<d.length&&(d=za[d[0]])&&(a.c[e]=d))}a.c[e]||(d=za[e])&&(a.c[e]=d);for(d=0;d<f.length;d+=1)a.a.push(new G(e,f[d]))}};function Ea(a,b){this.c=a;this.a=b}var Fa={Arimo:!0,Cousine:!0,Tinos:!0};Ea.prototype.load=function(a){var b=new B,c=this.c,d=new ta(this.a.api,this.a.text),e=this.a.families;va(d,e);var f=new ya(e);Da(f);z(c,wa(d),C(b));E(b,function(){a(f.a,f.c,Fa)})};function Ga(a,b){this.c=a;this.a=b}Ga.prototype.load=function(a){var b=this.a.id,c=this.c.o;b?A(this.c,(this.a.api||"https://use.typekit.net")+"/"+b+".js",function(b){if(b)a([]);else if(c.Typekit&&c.Typekit.config&&c.Typekit.config.fn){b=c.Typekit.config.fn;for(var e=[],f=0;f<b.length;f+=2)for(var g=b[f],m=b[f+1],h=0;h<m.length;h++)e.push(new G(g,m[h]));try{c.Typekit.load({events:!1,classes:!1,async:!0})}catch(l){}a(e)}},2E3):a([])};function Ha(a,b){this.c=a;this.f=b;this.a=[]}Ha.prototype.load=function(a){var b=this.f.id,c=this.c.o,d=this;b?(c.__webfontfontdeckmodule__||(c.__webfontfontdeckmodule__={}),c.__webfontfontdeckmodule__[b]=function(b,c){for(var g=0,m=c.fonts.length;g<m;++g){var h=c.fonts[g];d.a.push(new G(h.name,ga("font-weight:"+h.weight+";font-style:"+h.style)))}a(d.a)},A(this.c,(this.f.api||"https://f.fontdeck.com/s/css/js/")+ea(this.c)+"/"+b+".js",function(b){b&&a([])})):a([])};var Y=new oa(window);Y.a.c.custom=function(a,b){return new sa(b,a)};Y.a.c.fontdeck=function(a,b){return new Ha(b,a)};Y.a.c.monotype=function(a,b){return new ra(b,a)};Y.a.c.typekit=function(a,b){return new Ga(b,a)};Y.a.c.google=function(a,b){return new Ea(b,a)};var Z={load:p(Y.load,Y)};"function"===typeof define&&define.amd?define(function(){return Z}):"undefined"!==typeof module&&module.exports?module.exports=Z:(window.WebFont=Z,window.WebFontConfig&&Y.load(window.WebFontConfig));}());
|
BIN
src/muya/lib/assets/styles/danielbd.woff
Executable file
BIN
src/muya/lib/assets/styles/danielbd.woff
Executable file
Binary file not shown.
BIN
src/muya/lib/assets/styles/danielbd.woff2
Executable file
BIN
src/muya/lib/assets/styles/danielbd.woff2
Executable file
Binary file not shown.
@ -113,7 +113,7 @@ p.ag-paragraph.ag-active > span.ag-line:first-of-type:empty::after {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
figure pre.ag-multiple-math,
|
||||
figure.ag-container-block pre,
|
||||
div.ag-function-html pre.ag-html-block {
|
||||
width: 0;
|
||||
height: 0;
|
||||
@ -127,7 +127,7 @@ div.ag-function-html pre.ag-html-block {
|
||||
}
|
||||
|
||||
div.ag-function-html.ag-active pre.ag-html-block,
|
||||
figure.ag-active pre.ag-multiple-math {
|
||||
figure.ag-active.ag-container-block pre {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
@ -491,15 +491,43 @@ pre.ag-active.ag-multiple-math::after {
|
||||
content: '$$';
|
||||
}
|
||||
|
||||
pre.ag-active[data-role="mermaid"]::before {
|
||||
content: '``` mermaid';
|
||||
}
|
||||
|
||||
pre.ag-active[data-role="flowchart"]::before {
|
||||
content: '``` flowchart';
|
||||
}
|
||||
|
||||
pre.ag-active[data-role="sequence"]::before {
|
||||
content: '``` sequence';
|
||||
}
|
||||
|
||||
pre.ag-active[data-role="vega-lite"]::before {
|
||||
content: '``` vega-lite';
|
||||
}
|
||||
|
||||
pre.ag-active.ag-fence-code::before,
|
||||
pre.ag-active.ag-indent-code::after,
|
||||
pre.ag-active.ag-fence-code::after,
|
||||
pre.ag-active.ag-indent-code::before {
|
||||
pre.ag-active.ag-indent-code::before,
|
||||
pre.ag-active[data-role="mermaid"]::after,
|
||||
pre.ag-active[data-role="flowchart"]::after,
|
||||
pre.ag-active[data-role="sequence"]::after,
|
||||
pre.ag-active[data-role="vega-lite"]::after {
|
||||
content: '```';
|
||||
}
|
||||
|
||||
pre.ag-active.ag-front-matter::before,
|
||||
pre.ag-active.ag-front-matter::after,
|
||||
pre.ag-active[data-role="mermaid"]::before,
|
||||
pre.ag-active[data-role="mermaid"]::after,
|
||||
pre.ag-active[data-role="flowchart"]::before,
|
||||
pre.ag-active[data-role="flowchart"]::after,
|
||||
pre.ag-active[data-role="sequence"]::before,
|
||||
pre.ag-active[data-role="sequence"]::after,
|
||||
pre.ag-active[data-role="vega-lite"]::before,
|
||||
pre.ag-active[data-role="vega-lite"]::after,
|
||||
pre.ag-active.ag-fence-code::before,
|
||||
pre.ag-active.ag-fence-code::after,
|
||||
pre.ag-active.ag-indent-code::before,
|
||||
@ -514,6 +542,10 @@ pre.ag-active.ag-multiple-math::after {
|
||||
}
|
||||
|
||||
pre.ag-active.ag-front-matter::before,
|
||||
pre.ag-active[data-role="mermaid"]::before,
|
||||
pre.ag-active[data-role="flowchart"]::before,
|
||||
pre.ag-active[data-role="sequence"]::before,
|
||||
pre.ag-active[data-role="vega-lite"]::before,
|
||||
pre.ag-active.ag-multiple-math::before,
|
||||
pre.ag-active.ag-indent-code::before,
|
||||
pre.ag-active.ag-fence-code::before {
|
||||
@ -521,6 +553,10 @@ pre.ag-active.ag-fence-code::before {
|
||||
}
|
||||
|
||||
pre.ag-active.ag-front-matter::after,
|
||||
pre.ag-active[data-role="mermaid"]::after,
|
||||
pre.ag-active[data-role="flowchart"]::after,
|
||||
pre.ag-active[data-role="sequence"]::after,
|
||||
pre.ag-active[data-role="vega-lite"]::after,
|
||||
pre.ag-active.ag-multiple-math::after,
|
||||
pre.ag-active.ag-fence-code::after,
|
||||
pre.ag-active.ag-indent-code::after {
|
||||
@ -532,16 +568,17 @@ span.ag-multiple-math-line {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
figure div.ag-math-preview {
|
||||
figure.ag-container-block div.ag-container-preview {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
figure.ag-active div.ag-math-preview {
|
||||
figure.ag-active.ag-container-block > div.ag-container-preview {
|
||||
position: absolute;
|
||||
top: calc(100% + 8px);
|
||||
top: calc(100% + 20px);
|
||||
left: 50%;
|
||||
width: auto;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
z-index: 10000;
|
||||
transform: translateX(-50%);
|
||||
padding: .5rem;
|
||||
|
12
src/muya/lib/assets/styles/sequence-diagram.css
Executable file
12
src/muya/lib/assets/styles/sequence-diagram.css
Executable file
@ -0,0 +1,12 @@
|
||||
/** js sequence diagrams
|
||||
* https://bramp.github.io/js-sequence-diagrams/
|
||||
* (c) 2012-2017 Andrew Brampton (bramp.net)
|
||||
* Simplified BSD license.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'danielbd';
|
||||
src: url('danielbd.woff2') format('woff2'),
|
||||
url('danielbd.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
@ -112,8 +112,12 @@ export const CLASS_OR_ID = genUpper2LowerKeyHash([
|
||||
'AG_MATH_ERROR',
|
||||
'AG_EMPTY',
|
||||
'AG_MATH_MARKER',
|
||||
'AG_MATH_PREVIEW',
|
||||
'AG_MULTIPLE_MATH_BLOCK',
|
||||
'AG_CONTAINER_PREVIEW',
|
||||
'AG_FLOWCHART',
|
||||
'AG_SEQUENCE',
|
||||
'AG_MERMAID',
|
||||
'AG_VEGA_LITE',
|
||||
'AG_CONTAINER_BLOCK',
|
||||
'AG_MULTIPLE_MATH',
|
||||
'AG_LOOSE_LIST_ITEM',
|
||||
'AG_TIGHT_LIST_ITEM',
|
||||
@ -211,4 +215,22 @@ export const EXPORT_DOMPURIFY_CONFIG = {
|
||||
}
|
||||
}
|
||||
|
||||
export const MUYA_DEFAULT_OPTION = {
|
||||
focusMode: false,
|
||||
theme: 'light',
|
||||
markdown: '',
|
||||
preferLooseListItem: true,
|
||||
autoPairBracket: true,
|
||||
autoPairMarkdownSyntax: true,
|
||||
autoPairQuote: true,
|
||||
bulletListMarker: '-',
|
||||
tabSize: 4,
|
||||
sequenceTheme: 'hand', // hand or simple
|
||||
mermaidTheme: 'forest' // dark or forest
|
||||
}
|
||||
|
||||
// export const DIAGRAM_TEMPLATE = {
|
||||
// 'mermaid': `graph LR;\nYou-->|Mark Text|Me;`
|
||||
// }
|
||||
|
||||
export const isInElectron = window && window.process && window.process.type === 'renderer'
|
||||
|
@ -179,6 +179,10 @@ const backspaceCtrl = ContentState => {
|
||||
referenceBlock = preBlock
|
||||
break
|
||||
case 'multiplemath':
|
||||
case 'flowchart':
|
||||
case 'mermaid':
|
||||
case 'sequence':
|
||||
case 'vega-lite':
|
||||
referenceBlock = this.getParent(preBlock)
|
||||
break
|
||||
case 'html':
|
||||
|
85
src/muya/lib/contentState/containerCtrl.js
Normal file
85
src/muya/lib/contentState/containerCtrl.js
Normal file
@ -0,0 +1,85 @@
|
||||
const LINE_BREAKS_REG = /\n/
|
||||
const FUNCTION_TYPE_LANG = {
|
||||
'multiplemath': 'latex',
|
||||
'flowchart': 'yaml',
|
||||
'mermaid': 'yaml',
|
||||
'sequence': 'yaml',
|
||||
'vega-lite': 'yaml'
|
||||
}
|
||||
|
||||
const containerCtrl = ContentState => {
|
||||
ContentState.prototype.createContainerBlock = function (functionType, value = '') {
|
||||
const figureBlock = this.createBlock('figure')
|
||||
figureBlock.functionType = functionType
|
||||
const { preBlock, preview } = this.createPreAndPreview(functionType, value)
|
||||
this.appendChild(figureBlock, preBlock)
|
||||
this.appendChild(figureBlock, preview)
|
||||
this.codeBlocks.set(preBlock.key, value)
|
||||
return figureBlock
|
||||
}
|
||||
|
||||
ContentState.prototype.createPreAndPreview = function (functionType, value = '') {
|
||||
const preBlock = this.createBlock('pre')
|
||||
const codeBlock = this.createBlock('code')
|
||||
preBlock.functionType = functionType
|
||||
preBlock.lang = codeBlock.lang = FUNCTION_TYPE_LANG[functionType]
|
||||
this.appendChild(preBlock, codeBlock)
|
||||
|
||||
if (typeof value === 'string' && value) {
|
||||
value.replace(/^\s+/, '').split(LINE_BREAKS_REG).forEach(line => {
|
||||
const codeLine = this.createBlock('span', line)
|
||||
codeLine.functionType = 'codeLine'
|
||||
codeLine.lang = FUNCTION_TYPE_LANG[functionType]
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
})
|
||||
} else {
|
||||
const emptyLine = this.createBlock('span')
|
||||
emptyLine.functionType = 'codeLine'
|
||||
emptyLine.lang = FUNCTION_TYPE_LANG[functionType]
|
||||
this.appendChild(codeBlock, emptyLine)
|
||||
}
|
||||
|
||||
const preview = this.createBlock('div', '', false)
|
||||
this.codeBlocks.set(preBlock.key, '')
|
||||
preview.functionType = functionType
|
||||
|
||||
return { preBlock, preview }
|
||||
}
|
||||
|
||||
ContentState.prototype.initContainerBlock = function (functionType, block) { // p block
|
||||
block.type = 'figure'
|
||||
block.functionType = functionType
|
||||
block.children = []
|
||||
|
||||
const { preBlock, preview } = this.createPreAndPreview(functionType)
|
||||
|
||||
this.appendChild(block, preBlock)
|
||||
this.appendChild(block, preview)
|
||||
return preBlock.children[0].children[0]
|
||||
}
|
||||
|
||||
ContentState.prototype.handleContainerBlockClick = function (figure) {
|
||||
const { id } = figure
|
||||
const mathBlock = this.getBlock(id)
|
||||
const preBlock = mathBlock.children[0]
|
||||
const firstLine = preBlock.children[0].children[0]
|
||||
|
||||
const { key } = firstLine
|
||||
const offset = 0
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
end: { key, offset }
|
||||
}
|
||||
this.partialRender()
|
||||
}
|
||||
|
||||
ContentState.prototype.updateMathBlock = function (block) {
|
||||
const { type } = block
|
||||
if (type !== 'p') return false
|
||||
const { text } = block.children[0]
|
||||
const functionType = 'multiplemath'
|
||||
return text.trim() === '$$' ? this.initContainerBlock(functionType, block) : false
|
||||
}
|
||||
}
|
||||
|
||||
export default containerCtrl
|
@ -86,14 +86,29 @@ const copyCutCtrl = ContentState => {
|
||||
hb.replaceWith(pre)
|
||||
})
|
||||
|
||||
const mathBlock = wrapper.querySelectorAll(`figure.ag-multiple-math-block`)
|
||||
const mathBlock = wrapper.querySelectorAll(`figure.ag-container-block`)
|
||||
;[...mathBlock].forEach(mb => {
|
||||
const preElement = mb.querySelector('pre[data-role]')
|
||||
const functionType = preElement.getAttribute('data-role')
|
||||
const selectedCodeLines = mb.querySelectorAll('span.ag-code-line')
|
||||
const value = [...selectedCodeLines].map(codeLine => codeLine.textContent).join('\n')
|
||||
const pre = document.createElement('pre')
|
||||
let pre
|
||||
switch (functionType) {
|
||||
case 'multiplemath':
|
||||
pre = document.createElement('pre')
|
||||
pre.classList.add('multiple-math')
|
||||
pre.textContent = value
|
||||
mb.replaceWith(pre)
|
||||
break
|
||||
case 'mermaid':
|
||||
case 'flowchart':
|
||||
case 'sequence':
|
||||
case 'vega-lite':
|
||||
pre = document.createElement('pre')
|
||||
pre.innerHTML = `<code class="language-${functionType}">${value}</code>`
|
||||
mb.replaceWith(pre)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
const htmlData = wrapper.innerHTML
|
||||
|
@ -17,7 +17,7 @@ import paragraphCtrl from './paragraphCtrl'
|
||||
import tabCtrl from './tabCtrl'
|
||||
import formatCtrl from './formatCtrl'
|
||||
import searchCtrl from './searchCtrl'
|
||||
import mathCtrl from './mathCtrl'
|
||||
import containerCtrl from './containerCtrl'
|
||||
import imagePathCtrl from './imagePathCtrl'
|
||||
import htmlBlockCtrl from './htmlBlock'
|
||||
import clickCtrl from './clickCtrl'
|
||||
@ -39,7 +39,7 @@ const prototypes = [
|
||||
paragraphCtrl,
|
||||
formatCtrl,
|
||||
searchCtrl,
|
||||
mathCtrl,
|
||||
containerCtrl,
|
||||
imagePathCtrl,
|
||||
htmlBlockCtrl,
|
||||
clickCtrl,
|
||||
|
@ -1,81 +0,0 @@
|
||||
// import { CLASS_OR_ID } from '../config'
|
||||
const LINE_BREAKS_REG = /\n/
|
||||
|
||||
const mathCtrl = ContentState => {
|
||||
ContentState.prototype.createMathBlock = function (value = '') {
|
||||
const FUNCTION_TYPE = 'multiplemath'
|
||||
const mathBlock = this.createBlock('figure')
|
||||
mathBlock.functionType = FUNCTION_TYPE
|
||||
const { preBlock, mathPreview } = this.createMathAndPreview(value)
|
||||
this.appendChild(mathBlock, preBlock)
|
||||
this.appendChild(mathBlock, mathPreview)
|
||||
this.codeBlocks.set(preBlock.key, value)
|
||||
return mathBlock
|
||||
}
|
||||
|
||||
ContentState.prototype.createMathAndPreview = function (value = '') {
|
||||
const FUNCTION_TYPE = 'multiplemath'
|
||||
const preBlock = this.createBlock('pre')
|
||||
const codeBlock = this.createBlock('code')
|
||||
preBlock.functionType = FUNCTION_TYPE
|
||||
preBlock.lang = codeBlock.lang = 'latex'
|
||||
this.appendChild(preBlock, codeBlock)
|
||||
|
||||
if (typeof value === 'string' && value) {
|
||||
value.replace(/^\s+/, '').split(LINE_BREAKS_REG).forEach(line => {
|
||||
const codeLine = this.createBlock('span', line)
|
||||
codeLine.functionType = 'codeLine'
|
||||
codeLine.lang = 'latex'
|
||||
this.appendChild(codeBlock, codeLine)
|
||||
})
|
||||
} else {
|
||||
const emptyLine = this.createBlock('span')
|
||||
emptyLine.functionType = 'codeLine'
|
||||
emptyLine.lang = 'latex'
|
||||
this.appendChild(codeBlock, emptyLine)
|
||||
}
|
||||
|
||||
const mathPreview = this.createBlock('div', '', false)
|
||||
this.codeBlocks.set(preBlock.key, '')
|
||||
mathPreview.functionType = FUNCTION_TYPE
|
||||
|
||||
return { preBlock, mathPreview }
|
||||
}
|
||||
|
||||
ContentState.prototype.initMathBlock = function (block) { // p block
|
||||
const FUNCTION_TYPE = 'multiplemath'
|
||||
block.type = 'figure'
|
||||
block.functionType = FUNCTION_TYPE
|
||||
block.children = []
|
||||
|
||||
const { preBlock, mathPreview } = this.createMathAndPreview()
|
||||
|
||||
this.appendChild(block, preBlock)
|
||||
this.appendChild(block, mathPreview)
|
||||
return preBlock.children[0].children[0]
|
||||
}
|
||||
|
||||
ContentState.prototype.handleMathBlockClick = function (mathFigure) {
|
||||
const { id } = mathFigure
|
||||
const mathBlock = this.getBlock(id)
|
||||
const preBlock = mathBlock.children[0]
|
||||
const firstLine = preBlock.children[0].children[0]
|
||||
|
||||
const { key } = firstLine
|
||||
const offset = 0
|
||||
this.cursor = {
|
||||
start: { key, offset },
|
||||
end: { key, offset }
|
||||
}
|
||||
this.partialRender()
|
||||
}
|
||||
|
||||
ContentState.prototype.updateMathBlock = function (block) {
|
||||
const { type } = block
|
||||
if (type !== 'p') return false
|
||||
const { text } = block.children[0]
|
||||
return text.trim() === '$$' ? this.initMathBlock(block) : false
|
||||
}
|
||||
}
|
||||
|
||||
export default mathCtrl
|
@ -319,19 +319,19 @@ const paragraphCtrl = ContentState => {
|
||||
}
|
||||
}
|
||||
|
||||
ContentState.prototype.insertMathBlock = function () {
|
||||
ContentState.prototype.insertContainerBlock = function (functionType, value = '') {
|
||||
const { start, end } = selection.getCursorRange()
|
||||
if (start.key !== end.key) return
|
||||
let block = this.getBlock(start.key)
|
||||
if (block.type === 'span') {
|
||||
block = this.getParent(block)
|
||||
}
|
||||
const mathBlock = this.createMathBlock()
|
||||
const mathBlock = this.createContainerBlock(functionType, value)
|
||||
this.insertAfter(mathBlock, block)
|
||||
if (block.type === 'p' && block.children.length === 1 && !block.children[0].text) {
|
||||
this.removeBlock(block)
|
||||
}
|
||||
const cursorBlock = mathBlock.children[0].children[0]
|
||||
const cursorBlock = mathBlock.children[0].children[0].children[0]
|
||||
const { key } = cursorBlock
|
||||
const offset = 0
|
||||
this.cursor = {
|
||||
@ -391,7 +391,7 @@ const paragraphCtrl = ContentState => {
|
||||
break
|
||||
}
|
||||
case 'mathblock': {
|
||||
this.insertMathBlock()
|
||||
this.insertContainerBlock('multiplemath')
|
||||
break
|
||||
}
|
||||
case 'table': {
|
||||
@ -402,6 +402,12 @@ const paragraphCtrl = ContentState => {
|
||||
this.insertHtmlBlock(block)
|
||||
break
|
||||
}
|
||||
case 'flowchart':
|
||||
case 'sequence':
|
||||
case 'mermaid':
|
||||
case 'vega-lite':
|
||||
this.insertContainerBlock(paraType)
|
||||
break
|
||||
case 'heading 1':
|
||||
case 'heading 2':
|
||||
case 'heading 3':
|
||||
|
@ -127,7 +127,7 @@ const pasteCtrl = ContentState => {
|
||||
end: { key, offset }
|
||||
}
|
||||
}
|
||||
|
||||
this.updateCodeBlocks(startBlock)
|
||||
return this.partialRender()
|
||||
}
|
||||
|
||||
|
@ -41,12 +41,12 @@ class ClickEvent {
|
||||
event.stopPropagation()
|
||||
contentState.handleHtmlBlockClick(htmlPreview)
|
||||
}
|
||||
// handler math block preview click
|
||||
const mathFigure = target.closest('.ag-multiple-math-block')
|
||||
if (mathFigure && !mathFigure.classList.contains(CLASS_OR_ID['AG_ACTIVE'])) {
|
||||
// handler container block preview click
|
||||
const container = target.closest('.ag-container-block')
|
||||
if (container && !container.classList.contains(CLASS_OR_ID['AG_ACTIVE'])) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
contentState.handleMathBlockClick(mathFigure)
|
||||
contentState.handleContainerBlockClick(container)
|
||||
}
|
||||
// handler to-do checkbox click
|
||||
if (target.tagName === 'INPUT' && target.classList.contains(CLASS_OR_ID['AG_TASK_LIST_ITEM_CHECKBOX'])) {
|
||||
|
@ -3,7 +3,7 @@ import EventCenter from './eventHandler/event'
|
||||
import Clipboard from './eventHandler/clipboard'
|
||||
import Keyboard from './eventHandler/keyboard'
|
||||
import ClickEvent from './eventHandler/clickEvent'
|
||||
import { CLASS_OR_ID } from './config'
|
||||
import { CLASS_OR_ID, MUYA_DEFAULT_OPTION } from './config'
|
||||
import { wordCount } from './utils'
|
||||
import ExportMarkdown from './utils/exportMarkdown'
|
||||
import ExportHtml from './utils/exportHtml'
|
||||
@ -18,11 +18,8 @@ import './assets/styles/index.css'
|
||||
|
||||
class Muya {
|
||||
constructor (container, options) {
|
||||
const {
|
||||
focusMode = false, theme = 'light', markdown = '', preferLooseListItem = true,
|
||||
autoPairBracket = true, autoPairMarkdownSyntax = true, autoPairQuote = true,
|
||||
bulletListMarker = '-', tabSize = 4
|
||||
} = options
|
||||
this.options = Object.assign({}, MUYA_DEFAULT_OPTION, options)
|
||||
const { focusMode, theme, markdown } = this.options
|
||||
this.focusMode = focusMode
|
||||
this.theme = theme
|
||||
this.markdown = markdown
|
||||
@ -35,7 +32,7 @@ class Muya {
|
||||
this.emojiPicker = new EmojiPicker(this)
|
||||
this.imagePathPicker = new ImagePathPicker(this)
|
||||
this.formatPicker = new FormatPicker(this)
|
||||
this.contentState = new ContentState(this, { preferLooseListItem, autoPairBracket, autoPairMarkdownSyntax, autoPairQuote, bulletListMarker, tabSize })
|
||||
this.contentState = new ContentState(this, this.options)
|
||||
this.clipboard = new Clipboard(this)
|
||||
this.clickEvent = new ClickEvent(this)
|
||||
this.keyboard = new Keyboard(this)
|
||||
|
@ -1,8 +1,11 @@
|
||||
import mermaid from 'mermaid'
|
||||
import flowchart from 'flowchart.js'
|
||||
import Diagram from './sequence'
|
||||
import vegaEmbed from 'vega-embed'
|
||||
import { CLASS_OR_ID } from '../../config'
|
||||
import { conflict, mixins } from '../../utils'
|
||||
import { patch, toVNode, toHTML, h } from './snabbdom'
|
||||
import { beginRules } from '../rules'
|
||||
|
||||
import renderInlines from './renderInlines'
|
||||
import renderBlock from './renderBlock'
|
||||
|
||||
@ -12,6 +15,8 @@ class StateRender {
|
||||
this.eventCenter = muya.eventCenter
|
||||
this.loadImageMap = new Map()
|
||||
this.loadMathMap = new Map()
|
||||
this.mermaidCache = new Set()
|
||||
this.diagramCache = new Map()
|
||||
this.tokenCache = new Map()
|
||||
this.labels = new Map()
|
||||
this.container = null
|
||||
@ -84,6 +89,48 @@ class StateRender {
|
||||
return selector
|
||||
}
|
||||
|
||||
renderMermaid () {
|
||||
if (this.mermaidCache.size) {
|
||||
mermaid.init(undefined, document.querySelectorAll([...this.mermaidCache].join(', ')))
|
||||
this.mermaidCache.clear()
|
||||
}
|
||||
}
|
||||
|
||||
async renderDiagram () {
|
||||
const cache = this.diagramCache
|
||||
const RENDER_MAP = {
|
||||
'flowchart': flowchart,
|
||||
'sequence': Diagram,
|
||||
'vega-lite': vegaEmbed
|
||||
}
|
||||
if (cache.size) {
|
||||
for (const [key, value] of cache.entries()) {
|
||||
const target = document.querySelector(key)
|
||||
const { code, functionType } = value
|
||||
const render = RENDER_MAP[functionType]
|
||||
const options = {}
|
||||
if (functionType === 'sequence') {
|
||||
Object.assign(options, { theme: this.muya.options.sequenceTheme })
|
||||
} else if (functionType === 'vega-lite') {
|
||||
Object.assign(options, { actions: false, tooltip: false, renderer: 'svg' })
|
||||
}
|
||||
try {
|
||||
if (functionType === 'flowchart' || functionType === 'sequence') {
|
||||
const diagram = render.parse(code)
|
||||
target.innerHTML = ''
|
||||
diagram.drawSVG(target, options)
|
||||
} else if (functionType === 'vega-lite') {
|
||||
await vegaEmbed(key, JSON.parse(code), options)
|
||||
}
|
||||
} catch (err) {
|
||||
target.innerHTML = `< Invalid ${functionType === 'flowchart' ? 'Flow Chart' : 'Sequence'} Codes >`
|
||||
target.classList.add(CLASS_OR_ID['AG_MATH_ERROR'])
|
||||
}
|
||||
}
|
||||
this.diagramCache.clear()
|
||||
}
|
||||
}
|
||||
|
||||
render (blocks, cursor, activeBlocks, matches) {
|
||||
const selector = `div#${CLASS_OR_ID['AG_EDITOR_ID']}`
|
||||
|
||||
@ -96,6 +143,8 @@ class StateRender {
|
||||
const oldVdom = toVNode(rootDom)
|
||||
|
||||
patch(oldVdom, newVdom)
|
||||
this.renderMermaid()
|
||||
this.renderDiagram()
|
||||
}
|
||||
|
||||
// Only render the blocks which you updated
|
||||
@ -133,6 +182,8 @@ class StateRender {
|
||||
patch(oldCursorVnode, newCursorVnode)
|
||||
}
|
||||
}
|
||||
this.renderMermaid()
|
||||
this.renderDiagram()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,11 @@ const PRE_BLOCK_HASH = {
|
||||
'indentcode': `.${CLASS_OR_ID['AG_INDENT_CODE']}`,
|
||||
'html': `.${CLASS_OR_ID['AG_HTML_BLOCK']}`,
|
||||
'frontmatter': `.${CLASS_OR_ID['AG_FRONT_MATTER']}`,
|
||||
'multiplemath': `.${CLASS_OR_ID['AG_MULTIPLE_MATH']}`
|
||||
'multiplemath': `.${CLASS_OR_ID['AG_MULTIPLE_MATH']}`,
|
||||
'flowchart': `.${CLASS_OR_ID['AG_FLOWCHART']}`,
|
||||
'sequence': `.${CLASS_OR_ID['AG_SEQUENCE']}`,
|
||||
'mermaid': `.${CLASS_OR_ID['AG_MERMAID']}`,
|
||||
'vega-lite': `.${CLASS_OR_ID['AG_VEGA_LITE']}`
|
||||
}
|
||||
|
||||
export default function renderContainerBlock (block, cursor, activeBlocks, matches, useCache = false) {
|
||||
@ -29,11 +33,14 @@ export default function renderContainerBlock (block, cursor, activeBlocks, match
|
||||
}
|
||||
// handle `figure` block
|
||||
if (block.type === 'figure') {
|
||||
if (block.functionType === 'html') { // HTML Block
|
||||
if (block.functionType) {
|
||||
Object.assign(data.dataset, { role: block.functionType.toUpperCase() })
|
||||
}
|
||||
if (block.functionType === 'multiplemath') {
|
||||
selector += `.${CLASS_OR_ID['AG_MULTIPLE_MATH_BLOCK']}`
|
||||
|
||||
if (
|
||||
/multiplemath|flowchart|mermaid|sequence|vega-lite/.test(block.functionType)
|
||||
) {
|
||||
selector += `.${CLASS_OR_ID['AG_CONTAINER_BLOCK']}`
|
||||
}
|
||||
}
|
||||
// hanle list block
|
||||
|
@ -1,4 +1,5 @@
|
||||
import katex from 'katex'
|
||||
import mermaid from 'mermaid'
|
||||
import prism, { loadedCache } from '../../../prism/'
|
||||
import { CLASS_OR_ID, DEVICE_MEMORY, isInElectron, PREVIEW_DOMPURIFY_CONFIG } from '../../../config'
|
||||
import { tokenizer } from '../../parse'
|
||||
@ -90,27 +91,30 @@ export default function renderLeafBlock (block, cursor, activeBlocks, matches, u
|
||||
style: `text-align:${align}`
|
||||
})
|
||||
} else if (type === 'div') {
|
||||
if (functionType === 'preview') {
|
||||
const code = this.muya.contentState.codeBlocks.get(block.preSibling)
|
||||
switch (functionType) {
|
||||
case 'preview': {
|
||||
selector += `.${CLASS_OR_ID['AG_HTML_PREVIEW']}`
|
||||
const htmlContent = sanitize(this.muya.contentState.codeBlocks.get(block.preSibling), PREVIEW_DOMPURIFY_CONFIG)
|
||||
const htmlContent = sanitize(code, PREVIEW_DOMPURIFY_CONFIG)
|
||||
// handle empty html bock
|
||||
if (/<([a-z][a-z\d]*).*>\s*<\/\1>/.test(htmlContent)) {
|
||||
children = htmlToVNode('<div class="ag-empty"><Empty HTML Block></div>')
|
||||
} else {
|
||||
children = htmlToVNode(htmlContent)
|
||||
}
|
||||
} else if (functionType === 'multiplemath') {
|
||||
const math = this.muya.contentState.codeBlocks.get(block.preSibling)
|
||||
const key = `${math}_display_math`
|
||||
selector += `.${CLASS_OR_ID['AG_MATH_PREVIEW']}`
|
||||
if (math === '') {
|
||||
break
|
||||
}
|
||||
case 'multiplemath': {
|
||||
const key = `${code}_display_math`
|
||||
selector += `.${CLASS_OR_ID['AG_CONTAINER_PREVIEW']}`
|
||||
if (code === '') {
|
||||
children = '< Empty Mathematical Formula >'
|
||||
selector += `.${CLASS_OR_ID['AG_EMPTY']}`
|
||||
} else if (loadMathMap.has(key)) {
|
||||
children = loadMathMap.get(key)
|
||||
} else {
|
||||
try {
|
||||
const html = katex.renderToString(math, {
|
||||
const html = katex.renderToString(code, {
|
||||
displayMode: true
|
||||
})
|
||||
|
||||
@ -121,6 +125,42 @@ export default function renderLeafBlock (block, cursor, activeBlocks, matches, u
|
||||
selector += `.${CLASS_OR_ID['AG_MATH_ERROR']}`
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'mermaid': {
|
||||
selector += `.${CLASS_OR_ID['AG_CONTAINER_PREVIEW']}`
|
||||
if (code === '') {
|
||||
children = '< Empty Mermaid Block >'
|
||||
selector += `.${CLASS_OR_ID['AG_EMPTY']}`
|
||||
} else {
|
||||
try {
|
||||
mermaid.parse(code)
|
||||
children = code
|
||||
this.mermaidCache.add(`#${block.key}`)
|
||||
} catch (err) {
|
||||
children = '< Invalid Mermaid Codes >'
|
||||
selector += `.${CLASS_OR_ID['AG_MATH_ERROR']}`
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'flowchart':
|
||||
case 'sequence':
|
||||
case 'vega-lite': {
|
||||
const code = this.muya.contentState.codeBlocks.get(block.preSibling)
|
||||
selector += `.${CLASS_OR_ID['AG_CONTAINER_PREVIEW']}`
|
||||
if (code === '') {
|
||||
children = '< Empty Diagram Block >'
|
||||
selector += `.${CLASS_OR_ID['AG_EMPTY']}`
|
||||
} else {
|
||||
children = ''
|
||||
this.diagramCache.set(`#${block.key}`, {
|
||||
code,
|
||||
functionType
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (type === 'svg' && icon) {
|
||||
selector += '.icon'
|
||||
|
5
src/muya/lib/parser/render/sequence.js
Normal file
5
src/muya/lib/parser/render/sequence.js
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
import Diagram from '../../assets/libs/sequence-diagram'
|
||||
import '../../assets/styles/sequence-diagram.css'
|
||||
|
||||
export default Diagram
|
@ -843,7 +843,9 @@ class Selection {
|
||||
range.collapse(true)
|
||||
let rects = range.getClientRects()
|
||||
if (rects.length === 0) {
|
||||
rects = range.startContainer ? range.startContainer.getClientRects() : []
|
||||
rects = range.startContainer && range.startContainer.nodeType === Node.ELEMENT_NODE
|
||||
? range.startContainer.getClientRects()
|
||||
: []
|
||||
}
|
||||
if (rects.length) {
|
||||
const { left, top, x: rectX, y: rectY } = rects[0]
|
||||
|
@ -15,8 +15,37 @@ import quoteIcon from '../../assets/icons/quote.svg'
|
||||
import todoListIcon from '../../assets/icons/todolist.svg'
|
||||
import mathblockIcon from '../../assets/icons/math.svg'
|
||||
import orderListIcon from '../../assets/icons/order_list.svg'
|
||||
import flowchartIcon from '../../assets/icons/flowchart.svg'
|
||||
import sequenceIcon from '../../assets/icons/sequence.svg'
|
||||
import mermaidIcon from '../../assets/icons/mermaid.svg'
|
||||
import vegaIcon from '../../assets/icons/chart.svg'
|
||||
|
||||
export const quicInsertObj = {
|
||||
'diagram': [{
|
||||
title: 'Vega Chart',
|
||||
subTitle: 'Render flow chart by vega-lite.js.',
|
||||
label: 'vega-lite',
|
||||
icon: vegaIcon,
|
||||
color: 'rgb(224, 54, 54)'
|
||||
}, {
|
||||
title: 'Flow Chart',
|
||||
subTitle: 'Render flow chart by flowchart.js.',
|
||||
label: 'flowchart',
|
||||
icon: flowchartIcon,
|
||||
color: 'rgb(224, 54, 54)'
|
||||
}, {
|
||||
title: 'Sequence Diagram',
|
||||
subTitle: 'Render sequence diagram by js-sequence.',
|
||||
label: 'sequence',
|
||||
icon: sequenceIcon,
|
||||
color: 'rgb(224, 54, 54)'
|
||||
}, {
|
||||
title: 'Mermaid',
|
||||
subTitle: 'Render Diagram by mermaid.',
|
||||
label: 'mermaid',
|
||||
icon: mermaidIcon,
|
||||
color: 'rgb(224, 54, 54)'
|
||||
}],
|
||||
'basic block': [{
|
||||
title: 'Text',
|
||||
subTitle: 'Just start write plain text.',
|
||||
|
@ -52,13 +52,23 @@ class ExportMarkdown {
|
||||
|
||||
case 'figure':
|
||||
this.insertLineBreak(result, indent, true)
|
||||
if (block.functionType === 'table') {
|
||||
switch (block.functionType) {
|
||||
case 'table':
|
||||
const table = block.children[1]
|
||||
result.push(this.normalizeTable(table, indent))
|
||||
} else if (block.functionType === 'html') {
|
||||
break
|
||||
case 'html':
|
||||
result.push(this.normalizeHTML(block, indent))
|
||||
} else if (block.functionType === 'multiplemath') {
|
||||
break
|
||||
case 'multiplemath':
|
||||
result.push(this.normalizeMultipleMath(block, indent))
|
||||
break
|
||||
case 'mermaid':
|
||||
case 'flowchart':
|
||||
case 'sequence':
|
||||
case 'vega-lite':
|
||||
result.push(this.normalizeContainer(block, indent))
|
||||
break
|
||||
}
|
||||
break
|
||||
|
||||
@ -173,6 +183,18 @@ class ExportMarkdown {
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
// `mermaid` `flowchart` `sequence` `vega-lite`
|
||||
normalizeContainer (block, indent) {
|
||||
const result = []
|
||||
const diagramType = block.children[0].functionType
|
||||
result.push('```' + diagramType + '\n')
|
||||
for (const line of block.children[0].children[0].children) {
|
||||
result.push(`${line.text}\n`)
|
||||
}
|
||||
result.push('```\n')
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
normalizeCodeBlock (block, indent) {
|
||||
const result = []
|
||||
const textList = block.children[1].children.map(codeLine => codeLine.text)
|
||||
|
@ -73,7 +73,7 @@ const importRegister = ContentState => {
|
||||
}
|
||||
case 'multiplemath': {
|
||||
value = token.text
|
||||
block = this.createMathBlock(value)
|
||||
block = this.createContainerBlock(token.type, value)
|
||||
this.appendChild(parentList[0], block)
|
||||
break
|
||||
}
|
||||
@ -83,6 +83,10 @@ const importRegister = ContentState => {
|
||||
if (value.endsWith('\n')) {
|
||||
value = value.replace(/\n+$/, '')
|
||||
}
|
||||
if (/mermaid|flowchart|vega-lite|sequence/.test(lang)) {
|
||||
block = this.createContainerBlock(lang, value)
|
||||
this.appendChild(parentList[0], block)
|
||||
} else {
|
||||
block = this.createBlock('pre')
|
||||
const codeBlock = this.createBlock('code')
|
||||
value.split(LINE_BREAKS_REG).forEach(line => {
|
||||
@ -102,6 +106,7 @@ const importRegister = ContentState => {
|
||||
this.appendChild(block, inputBlock)
|
||||
this.appendChild(block, codeBlock)
|
||||
this.appendChild(parentList[0], block)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'table': {
|
||||
|
@ -321,15 +321,14 @@ table tr:nth-child(2n) {
|
||||
|
||||
table tr th {
|
||||
font-weight: bold;
|
||||
border-top: 2px solid #606266;
|
||||
border-bottom: 2px solid #606266;
|
||||
border: 2px solid #606266;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr td {
|
||||
border-bottom: 1px solid #606266;
|
||||
border: 1px solid #606266;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
|
Loading…
Reference in New Issue
Block a user