feat: code optimisation

代码优化
This commit is contained in:
yanglbme 2019-11-10 15:52:46 +08:00
parent 30cf5b13d9
commit 98df1b6325
3 changed files with 85 additions and 97 deletions

View File

@ -6,9 +6,9 @@ let app = new Vue({
output: '', output: '',
source: '', source: '',
editorThemes: [ editorThemes: [
{ label: '淡雅', value: 'xq-light'}, { label: '淡雅', value: 'xq-light' },
{ label: '精美', value: 'eclipse'}, { label: '精美', value: 'eclipse' },
{ label: '暗绿', value: 'oceanic-next'} { label: '暗绿', value: 'oceanic-next' }
], ],
editor: null, editor: null,
builtinFonts: [ builtinFonts: [
@ -28,8 +28,8 @@ let app = new Vue({
], ],
colorOption: [ colorOption: [
{ label: '橘红', value: 'rgba(255, 95, 46, 0.9)', hex: '#FF5F2E' }, { label: '橘红', value: 'rgba(255, 95, 46, 0.9)', hex: '#FF5F2E' },
{ label: '淡绿', value: 'rgba(66, 185, 131, 0.9)', hex: '#42B983'}, { label: '淡绿', value: 'rgba(66, 185, 131, 0.9)', hex: '#42B983' },
{ label: '暗青', value: 'rgba(0, 139, 139, 0.9)', hex: '#008B8B'} { label: '暗青', value: 'rgba(0, 139, 139, 0.9)', hex: '#008B8B' }
], ],
aboutDialogVisible: false aboutDialogVisible: false
}; };
@ -40,7 +40,6 @@ let app = new Vue({
return d; return d;
}, },
mounted() { mounted() {
let self = this;
this.editor = CodeMirror.fromTextArea( this.editor = CodeMirror.fromTextArea(
document.getElementById('editor'), document.getElementById('editor'),
{ {
@ -51,9 +50,9 @@ let app = new Vue({
mode: 'text/x-markdown', mode: 'text/x-markdown',
} }
); );
this.editor.on("change", function (cm, change) { this.editor.on("change", (cm, change) => {
self.refresh(); this.refresh();
self.saveEditorContent(); this.saveEditorContent();
}); });
this.wxRenderer = new WxRenderer({ this.wxRenderer = new WxRenderer({
theme: setColor(this.currentColor), theme: setColor(this.currentColor),
@ -67,13 +66,13 @@ let app = new Vue({
axios({ axios({
method: 'get', method: 'get',
url: './assets/default-content.md', url: './assets/default-content.md',
}).then(function (resp) { }).then(resp => {
self.editor.setValue(resp.data) this.editor.setValue(resp.data)
}) })
} }
}, },
methods: { methods: {
renderWeChat: function (source) { renderWeChat(source) {
let output = marked(source, { renderer: this.wxRenderer.getRenderer() }); let output = marked(source, { renderer: this.wxRenderer.getRenderer() });
if (this.wxRenderer.hasFootnotes()) { if (this.wxRenderer.hasFootnotes()) {
// 去除第一行的 margin-top // 去除第一行的 margin-top
@ -85,22 +84,22 @@ let app = new Vue({
} }
return output return output
}, },
editorThemeChanged: function (editorTheme) { editorThemeChanged(editorTheme) {
this.editor.setOption('theme', editorTheme) this.editor.setOption('theme', editorTheme)
}, },
fontChanged: function (fonts) { fontChanged(fonts) {
this.wxRenderer.setOptions({ this.wxRenderer.setOptions({
fonts: fonts fonts: fonts
}); });
this.refresh() this.refresh()
}, },
sizeChanged: function (size) { sizeChanged(size) {
this.wxRenderer.setOptions({ this.wxRenderer.setOptions({
size: size size: size
}); });
this.refresh() this.refresh()
}, },
colorChanged: function (color) { colorChanged(color) {
let theme = setColor(color) let theme = setColor(color)
this.wxRenderer.setOptions({ this.wxRenderer.setOptions({
theme: theme theme: theme
@ -108,19 +107,19 @@ let app = new Vue({
this.refresh() this.refresh()
}, },
// 刷新右侧预览 // 刷新右侧预览
refresh: function () { refresh() {
this.output = this.renderWeChat(this.editor.getValue(0)) this.output = this.renderWeChat(this.editor.getValue(0))
}, },
// 将左侧编辑器内容保存到 LocalStorage // 将左侧编辑器内容保存到 LocalStorage
saveEditorContent: function () { saveEditorContent() {
let content = this.editor.getValue(0); let content = this.editor.getValue(0);
if (content){ if (content) {
localStorage.setItem("__editor_content", content); localStorage.setItem("__editor_content", content);
} else { } else {
localStorage.removeItem("__editor_content"); localStorage.removeItem("__editor_content");
} }
}, },
copy: function () { copy() {
let clipboardDiv = document.getElementById('output'); let clipboardDiv = document.getElementById('output');
clipboardDiv.focus(); clipboardDiv.focus();
window.getSelection().removeAllRanges(); window.getSelection().removeAllRanges();
@ -157,13 +156,13 @@ let app = new Vue({
}); });
} }
}, },
openWindow: function (url) { openWindow(url) {
window.open(url); window.open(url);
} }
}, },
updated: function () { updated() {
this.$nextTick(function () { this.$nextTick(() => {
prettyPrint() prettyPrint();
}) })
} }
}); });

View File

@ -9,11 +9,9 @@ let WxRenderer = function (opts) {
let CODE_FONT_FAMILY = "Menlo, Operator Mono, Consolas, Monaco, monospace"; let CODE_FONT_FAMILY = "Menlo, Operator Mono, Consolas, Monaco, monospace";
let merge = function (base, extend) { let merge = (base, extend) => Object.assign({}, base, extend);
return Object.assign({}, base, extend)
};
this.buildTheme = function (themeTpl) { this.buildTheme = themeTpl => {
let mapping = {}; let mapping = {};
let base = merge(themeTpl.BASE, { let base = merge(themeTpl.BASE, {
'font-family': this.opts.fonts, 'font-family': this.opts.fonts,
@ -30,6 +28,7 @@ let WxRenderer = function (opts) {
mapping[ele] = merge(base, style) mapping[ele] = merge(base, style)
} }
} }
for (let ele in themeTpl.block) { for (let ele in themeTpl.block) {
if (themeTpl.block.hasOwnProperty(ele)) { if (themeTpl.block.hasOwnProperty(ele)) {
let style = themeTpl.block[ele]; let style = themeTpl.block[ele];
@ -42,7 +41,7 @@ let WxRenderer = function (opts) {
return mapping return mapping
}; };
let getStyles = function (tokenName, addition) { let getStyles = (tokenName, addition) => {
let arr = []; let arr = [];
let dict = styleMapping[tokenName]; let dict = styleMapping[tokenName];
if (!dict) return ''; if (!dict) return '';
@ -52,14 +51,13 @@ let WxRenderer = function (opts) {
return `style="${arr.join(';') + (addition || '')}"` return `style="${arr.join(';') + (addition || '')}"`
}; };
let addFootnote = function (title, link) { let addFootnote = (title, link) => {
footnoteIndex += 1; footnotes.push([++footnoteIndex, title, link]);
footnotes.push([footnoteIndex, title, link]); return footnoteIndex;
return footnoteIndex
}; };
this.buildFootnotes = function () { this.buildFootnotes = () => {
let footnoteArray = footnotes.map(function (x) { let footnoteArray = footnotes.map(x => {
if (x[1] === x[2]) { if (x[1] === x[2]) {
return `<code style="font-size: 90%; opacity: 0.6;">[${x[0]}]</code>: <i>${x[1]}</i><br/>` return `<code style="font-size: 90%; opacity: 0.6;">[${x[0]}]</code>: <i>${x[1]}</i><br/>`
} }
@ -68,31 +66,33 @@ let WxRenderer = function (opts) {
return `<h4 ${getStyles('h4')}>引用链接</h4><p ${getStyles('footnotes')}>${footnoteArray.join('\n')}</p>` return `<h4 ${getStyles('h4')}>引用链接</h4><p ${getStyles('footnotes')}>${footnoteArray.join('\n')}</p>`
}; };
this.buildAddition = function () { this.buildAddition = () => {
return '<style>.preview-wrapper pre::before{' + return `
'font-family:"SourceSansPro","HelveticaNeue",Arial,sans-serif;' + <style>
'position:absolute;' + .preview-wrapper pre::before {
'top:0;' + font-family: "SourceSansPro", "HelveticaNeue", Arial, sans-serif;
'right:0;' + position: absolute;
'color:#ccc;' + top: 0;
'text-align:right;' + right: 0;
'font-size:0.8em;' + color: #ccc;
'padding:5px10px0;' + text-align: center;
'line-height:15px;' + font-size: 0.8em;
'height:15px;' + padding: 5px 10px 0;
'font-weight:600;' + line-height: 15px;
'}</style>' height: 15px;
}; font-weight: 600;
}
</style>
`;
}
this.setOptions = function (newOpts) { this.setOptions = newOpts => {
this.opts = merge(this.opts, newOpts) this.opts = merge(this.opts, newOpts)
}; };
this.hasFootnotes = function () { this.hasFootnotes = () => footnotes.length !== 0;
return footnotes.length !== 0
};
this.getRenderer = function () { this.getRenderer = () => {
footnotes = []; footnotes = [];
footnoteIndex = 0; footnoteIndex = 0;
@ -100,7 +100,7 @@ let WxRenderer = function (opts) {
let renderer = new marked.Renderer(); let renderer = new marked.Renderer();
FuriganaMD.register(renderer); FuriganaMD.register(renderer);
renderer.heading = function (text, level) { renderer.heading = (text, level) => {
switch (level) { switch (level) {
case 1: case 1:
return `<h1 ${getStyles('h1')}>${text}</h1>`; return `<h1 ${getStyles('h1')}>${text}</h1>`;
@ -112,39 +112,40 @@ let WxRenderer = function (opts) {
return `<h4 ${getStyles('h4')}>${text}</h4>`; return `<h4 ${getStyles('h4')}>${text}</h4>`;
} }
}; };
renderer.paragraph = function (text) { renderer.paragraph = text => `<p ${getStyles('p')}>${text}</p>`;
return `<p ${getStyles('p')}>${text}</p>`
}; renderer.blockquote = text => {
renderer.blockquote = function (text) {
text = text.replace(/<p.*?>/, `<p ${getStyles('blockquote_p')}>`); text = text.replace(/<p.*?>/, `<p ${getStyles('blockquote_p')}>`);
return `<blockquote ${getStyles('blockquote')}>${text}</blockquote>` return `<blockquote ${getStyles('blockquote')}>${text}</blockquote>`
}; };
renderer.code = function (text, infoString) { renderer.code = (text, infoString) => {
text = text.replace(/</g, "&lt;"); text = text.replace(/</g, "&lt;");
text = text.replace(/>/g, "&gt;"); text = text.replace(/>/g, "&gt;");
let lines = text.split('\n'); let lines = text.split('\n');
let codeLines = []; let codeLines = [];
let numbers = []; let numbers = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i]; const line = lines[i];
codeLines.push(`<code class="prettyprint"><span class="code-snippet_outer">${(line || '<br>')}</span></code>`); codeLines.push(`<code class="prettyprint"><span class="code-snippet_outer">${(line || '<br>')}</span></code>`);
numbers.push('<li></li>') numbers.push('<li></li>')
} }
let lang = infoString || ''; let lang = infoString || '';
return `<section class="code-snippet__fix code-snippet__js">`
+ `<ul class="code-snippet__line-index code-snippet__js">${numbers.join('')}</ul>` return `
+ `<pre class="code-snippet__js" data-lang="${lang}">` <section class="code-snippet__fix code-snippet__js">
+ codeLines.join('') <ul class="code-snippet__line-index code-snippet__js">${numbers.join('')}</ul>
+ `</pre></section>` <pre class="code-snippet__js" data-lang="${lang}">
${codeLines.join('')}
</pre>
</section>
`;
}; };
renderer.codespan = function (text, infoString) { renderer.codespan = (text, infoString) => `<code ${getStyles('codespan')}>${text}</code>`;
return `<code ${getStyles('codespan')}>${text}</code>` renderer.listitem = text => `<span ${getStyles('listitem')}><span style="margin-right: 10px;"><%s/></span>${text}</span>`;
};
renderer.listitem = function (text) { renderer.list = (text, ordered, start) => {
return `<span ${getStyles('listitem')}><span style="margin-right: 10px;"><%s/></span>${text}</span>`;
};
renderer.list = function (text, ordered, start) {
text = text.replace(/<\/*p.*?>/g, ''); text = text.replace(/<\/*p.*?>/g, '');
let segments = text.split(`<%s/>`); let segments = text.split(`<%s/>`);
if (!ordered) { if (!ordered) {
@ -157,7 +158,7 @@ let WxRenderer = function (opts) {
} }
return `<p ${getStyles('ol')}>${text}</p>`; return `<p ${getStyles('ol')}>${text}</p>`;
}; };
renderer.image = function (href, title, text) { renderer.image = (href, title, text) => {
let subText = ''; let subText = '';
if (text) { if (text) {
subText = `<figcaption ${getStyles('figcaption')}>${text}</figcaption>` subText = `<figcaption ${getStyles('figcaption')}>${text}</figcaption>`
@ -166,7 +167,7 @@ let WxRenderer = function (opts) {
let imgStyles = getStyles(ENV_STRETCH_IMAGE ? 'image' : 'image_org'); let imgStyles = getStyles(ENV_STRETCH_IMAGE ? 'image' : 'image_org');
return `<figure ${figureStyles}><img ${imgStyles} src="${href}" title="${title}" alt="${text}"/>${subText}</figure>` return `<figure ${figureStyles}><img ${imgStyles} src="${href}" title="${title}" alt="${text}"/>${subText}</figure>`
}; };
renderer.link = function (href, title, text) { renderer.link = (href, title, text) => {
if (href.indexOf('https://mp.weixin.qq.com') === 0) { if (href.indexOf('https://mp.weixin.qq.com') === 0) {
return `<a href="${href}" title="${(title || text)}" ${getStyles('wx_link')}>${text}</a>`; return `<a href="${href}" title="${(title || text)}" ${getStyles('wx_link')}>${text}</a>`;
} else if (href === text) { } else if (href === text) {
@ -180,21 +181,12 @@ let WxRenderer = function (opts) {
} }
} }
}; };
renderer.strong = function (text) { renderer.strong = text => `<strong ${getStyles('strong')}>${text}</strong>`;
return `<strong ${getStyles('strong')}>${text}</strong>`; renderer.em = text => `<p ${getStyles('p', ';font-style: italic;')}>${text}</p>`;
}; renderer.table = (header, body) => `<table class="preview-table"><thead ${getStyles('thead')}>${header}</thead><tbody>${body}</tbody></table>`;
renderer.em = function (text) { renderer.tablecell = (text, flags) => `<td ${getStyles('td')}>${text}</td>`;
return `<p ${getStyles('p', ';font-style: italic;')}>${text}</p>` renderer.hr = () => `<hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);">`;
};
renderer.table = function (header, body) {
return `<table class="preview-table"><thead ${getStyles('thead')}>${header}</thead><tbody>${body}</tbody></table>`;
};
renderer.tablecell = function (text, flags) {
return `<td ${getStyles('td')}>${text}</td>`;
};
renderer.hr = function () {
return `<hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);">`;
};
return renderer return renderer
} }
}; };

View File

@ -1,13 +1,11 @@
// 左右栏同步滚动 // 左右栏同步滚动
$(document).ready(function () { $(document).ready(() => {
let timeout; let timeout;
$('div.CodeMirror-scroll, #preview').on("scroll", function callback() { $('div.CodeMirror-scroll, #preview').on("scroll", function callback() {
clearTimeout(timeout); clearTimeout(timeout);
let source = $(this), let source = $(this),
target = $(source.is("#preview") ? 'div.CodeMirror-scroll' : '#preview'); target = $(source.is("#preview") ? 'div.CodeMirror-scroll' : '#preview');
target.off("scroll"); target.off("scroll");
@ -18,9 +16,8 @@ $(document).ready(function () {
let height = percentage * (target0.scrollHeight - target0.offsetHeight); let height = percentage * (target0.scrollHeight - target0.offsetHeight);
target0.scrollTo(0, height); target0.scrollTo(0, height);
timeout = setTimeout(function () { timeout = setTimeout(() => {
target.on("scroll", callback); target.on("scroll", callback);
}, 100); }, 100);
}); });
}); });