diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6f3a291 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/assets/css/app.css b/assets/css/app.css index 673e783..5bb7522 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -101,6 +101,7 @@ section { width: 375px; padding: 20px; font-size: 14px; + box-sizing: border-box; outline: none; box-shadow: 0 0 60px rgba(0, 0, 0, 0.1); } @@ -123,11 +124,11 @@ section { } .CodeMirror { - height: 100%; + height: 100% !important; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); font-size: 14px; padding: 20px; - width: 100%; + width: 100% !important; font-family: 'PingFang SC', BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif; } diff --git a/assets/css/style-mirror.css b/assets/css/style-mirror.css new file mode 100644 index 0000000..bf98442 --- /dev/null +++ b/assets/css/style-mirror.css @@ -0,0 +1,104 @@ +/* + + Name: Base16 Default Light + Author: Chris Kempson (http://chriskempson.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-style-mirror.CodeMirror { + background: #f5f5f5; + color: #444; + font-size: 16px; + padding: 20px; + line-height: 25px; + } + .cm-s-style-mirror div.CodeMirror-selected { + background: #e0e0e0; + } + .cm-s-style-mirror .CodeMirror-line::selection, + .cm-s-style-mirror .CodeMirror-line > span::selection, + .cm-s-style-mirror .CodeMirror-line > span > span::selection { + background: #e0e0e0; + } + .cm-s-style-mirror .CodeMirror-line::-moz-selection, + .cm-s-style-mirror .CodeMirror-line > span::-moz-selection, + .cm-s-style-mirror .CodeMirror-line > span > span::-moz-selection { + background: #e0e0e0; + } + .cm-s-style-mirror .CodeMirror-gutters { + background: #f5f5f5; + border-right: 0px; + } + .cm-s-style-mirror .CodeMirror-guttermarker { + color: #ac4142; + } + .cm-s-style-mirror .CodeMirror-guttermarker-subtle { + color: #b0b0b0; + } + .cm-s-style-mirror .CodeMirror-linenumber { + color: #b0b0b0; + } + .cm-s-style-mirror .CodeMirror-cursor { + border-left: 1px solid #505050; + } + + .cm-s-style-mirror span.cm-comment { + color:green; + } + .cm-s-style-mirror span.cm-atom { + color: #aa759f; + } + .cm-s-style-mirror span.cm-number { + color: #aa759f; + } + + .cm-s-style-mirror span.cm-property, + .cm-s-style-mirror span.cm-attribute { + color: #90a959; + } + .cm-s-style-mirror span.cm-keyword { + color: #023a52; + } + .cm-s-style-mirror span.cm-string { + color: #e46918; + } + + .cm-s-style-mirror span.cm-variable { + color: #90a959; + } + .cm-s-style-mirror span.cm-variable-2 { + color: #00695f; + } + .cm-s-style-mirror span.cm-variable-3 { + color: #2e6e8a; + } + .cm-s-style-mirror span.cm-def { + color: #d28445; + } + .cm-s-style-mirror span.cm-bracket { + color: #202020; + } + .cm-s-style-mirror span.cm-tag { + color:#000; + } + .cm-s-style-mirror span.cm-link { + color: #b26a00; + } + .cm-s-style-mirror span.cm-error { + /* background: #ac4142; + color: #f5f5f5; */ + text-decoration: underline; + text-decoration-style: wavy; + text-decoration-color: #df8d8e; + } + .cm-s-style-mirror .CodeMirror-activeline-background { + background: #dddcdc; + } + .cm-s-style-mirror .CodeMirror-matchingbracket { + color: rgb(32,32,32) !important; + background-color: rgba(0,0,0,0.1) !important; + } + \ No newline at end of file diff --git a/assets/scripts/editor.js b/assets/scripts/editor.js index e812c56..c7dc777 100644 --- a/assets/scripts/editor.js +++ b/assets/scripts/editor.js @@ -32,6 +32,7 @@ let app = new Vue({ { label: '翡翠绿', value: 'rgba(0, 152, 116, 0.9)', hex: '清新且优雅' }, { label: '辣椒红', value: 'rgba(155, 35, 53, 0.9)', hex: '自信且迷人' } ], + showBox:true, aboutDialogVisible: false }; d.currentEditorTheme = d.editorThemes[0].value; @@ -39,10 +40,11 @@ let app = new Vue({ d.currentFont = d.builtinFonts[0].value; d.currentSize = d.sizeOption[1].value; d.currentColor = d.colorOption[1].value; - d.showBox = false; return d; }, mounted() { + this.showBox = false + this.editor = CodeMirror.fromTextArea( document.getElementById('editor'), { @@ -54,23 +56,34 @@ let app = new Vue({ } ); this.cssEditor = CodeMirror.fromTextArea( - document.getElementById('cssEditor'), - { - lineNumbers: false, - lineWrapping: true, - styleActiveLine: true, - matchBrackets: true, - theme: this.currentCssEditorTheme, - mode: 'application/json' - } + document.getElementById('cssEditor'), { + mode: 'css', + theme: 'style-mirror', + lineNumbers:false, + lineWrapping: true, + matchBrackets: true, + autofocus: true, + extraKeys: { + "Ctrl-F": function autoFormat(editor) { + var totalLines = editor.lineCount(); + editor.autoFormatRange({line:0, ch:0}, {line:totalLines}); + } + }, + } ); + // 自动提示 + this.cssEditor.on("keyup", (cm, e) => { + if ((e.keyCode >= 65 && e.keyCode <= 90) || e.keyCode === 189) { + cm.showHint(e); + } + }); this.editor.on("change", (cm, change) => { this.refresh(); this.saveEditorContent(this.editor, '__editor_content'); }); this.cssEditor.on('update', (instance) => { - this.cssChanged(); - this.saveEditorContent(this.cssEditor, '__css_content'); + this.cssChanged() + this.saveEditorContent(this.cssEditor, '__css_content'); }); this.wxRenderer = new WxRenderer({ theme: setColor(this.currentColor), @@ -84,20 +97,14 @@ let app = new Vue({ this.setDefaultContent(); } - if (localStorage.getItem('__css_content')) { - this.cssEditor.setValue(localStorage.getItem('__css_content')); - } else { - axios({ - method: 'get', - url: './assets/scripts/themes/default-theme.js' - }).then(resp => { - this.cssEditor.setValue(resp.data); - }).catch(err => { - console.log('无法通过网络请求加载default-theme.js文件'); - }) + if (localStorage.getItem("__css_content")) { + this.cssEditor.setValue(localStorage.getItem("__css_content")); + } else { + this.cssEditor.setValue(DEFAULT_CSS_CONTENT); } }, methods: { + renderWeChat(source) { let output = marked(source, { renderer: this.wxRenderer.getRenderer() }); if (this.wxRenderer.hasFootnotes()) { @@ -133,13 +140,12 @@ let app = new Vue({ this.refresh(); }, cssChanged() { - let theme = JSON.parse(this.cssEditor.getValue(0)); - this.wxRenderer.setOptions({ - theme: customCss(theme, this.currentColor), - font: this.currentFont, - size: this.currentSize - }); - this.refresh(); + let json = css2json(this.cssEditor.getValue(0)) + let theme = customCssWithTemplate(json,this.currentColor) + this.wxRenderer.setOptions({ + theme + }); + this.refresh(); }, // 图片上传结束 uploaded(response, file, fileList) { @@ -193,6 +199,7 @@ let app = new Vue({ localStorage.removeItem('__css_content'); this.setDefaultContent(); this.editor.focus(); + this.cssEditor.setValue(DEFAULT_CSS_CONTENT); this.refresh(); }).catch(() => { this.editor.focus(); @@ -208,7 +215,7 @@ let app = new Vue({ } }, customStyle() { - this.saveEditorContent(this.cssEditor, '__css_content'); + console.log(this.currentColor) this.showBox = !this.showBox; }, setDefaultContent() { diff --git a/assets/scripts/themes/default-theme-css.js b/assets/scripts/themes/default-theme-css.js new file mode 100644 index 0000000..3efce1e --- /dev/null +++ b/assets/scripts/themes/default-theme-css.js @@ -0,0 +1,55 @@ +const DEFAULT_CSS_CONTENT = +`/* + 按Ctrl+F可格式化 +*/ +/* 一级标题 */ +h1 { +} +/* 二级标题 */ +h2 { +} +/* 三级标题 */ +h3 { +} +h4{ +} +/* 段落 */ +p { +} +blockquote { +} +blockquote_p { +} +code { +} +image { +} +image_org{ +} +/* 无序列表 */ +ol { +} +ul { +} +/* 引用 */ +blockquote { +} +/* 行内样式 */ +table { +} +thead { +} +strong { +} +/* 脚注文字 */ +footnote { +} + + + + + +` + + + diff --git a/assets/scripts/themes/default-theme.js b/assets/scripts/themes/default-theme.js index b75e560..9e39fbd 100644 --- a/assets/scripts/themes/default-theme.js +++ b/assets/scripts/themes/default-theme.js @@ -16,7 +16,7 @@ let default_theme = { 'display': 'table', 'margin': '2em auto 1em', 'padding': '0 1em', - 'border-bottom': '2px solid rgba(15, 76, 129, 0.9)' + 'border-bottom': '2px solid rgba(0, 152, 116, 0.9)' }, // 二级标题样式 @@ -27,7 +27,7 @@ let default_theme = { 'display': 'table', 'margin': '4em auto 2em', 'padding': '0 0.2em', - 'background': 'rgba(15, 76, 129, 0.9)', + 'background': 'rgba(0, 152, 116, 0.9)', 'color': '#fff' }, @@ -38,7 +38,7 @@ let default_theme = { 'margin': '2em 8px 0.75em 0', 'line-height': '1.2', 'padding-left': '8px', - 'border-left': '3px solid rgba(15, 76, 129, 0.9)' + 'border-left': '3px solid rgba(0, 152, 116, 0.9)' }, // 四级标题样式 diff --git a/assets/scripts/util.js b/assets/scripts/util.js index e57f0fe..d962bf4 100644 --- a/assets/scripts/util.js +++ b/assets/scripts/util.js @@ -13,25 +13,37 @@ function setColorWithTemplate(template) { let setColor = setColorWithTemplate(default_theme); -function customCssWithTemplate(template, color) { - return function (jsonString) { - let custom_theme = JSON.parse(JSON.stringify(template)); - custom_theme.block.h1 = jsonString.h1; - custom_theme.block.h2 = jsonString.h2; - custom_theme.block.h3 = jsonString.h3; - custom_theme.block.h4 = jsonString.h4; - custom_theme.block.p = jsonString.p; - // color - custom_theme.block.h1['border-bottom'] = `2px solid ${color}`; +function customCssWithTemplate(jsonString,color) { + let custom_theme = JSON.parse(JSON.stringify(default_theme)); + // block + custom_theme.block.h1 = Object.assign(custom_theme.block.h1,jsonString.h1); + custom_theme.block.h2 = Object.assign(custom_theme.block.h2,jsonString.h2); + custom_theme.block.h3 = Object.assign(custom_theme.block.h3,jsonString.h3); + custom_theme.block.h4 = Object.assign(custom_theme.block.h4,jsonString.h4); + custom_theme.block.p = Object.assign(custom_theme.block.p,jsonString.p); + custom_theme.block.blockquote = Object.assign(custom_theme.block.blockquote,jsonString.blockquote); + custom_theme.block.blockquote_p = Object.assign(custom_theme.block.blockquote_p,jsonString.blockquote_p); + custom_theme.block.code = Object.assign(custom_theme.block.code,jsonString.code); + custom_theme.block.image = Object.assign(custom_theme.block.image,jsonString.image); + custom_theme.block.ol = Object.assign(custom_theme.block.ol,jsonString.ol); + custom_theme.block.ul = Object.assign(custom_theme.block.ul,jsonString.ul); + custom_theme.block.footnotes = Object.assign(custom_theme.block.footnotes,jsonString.footnotes); + custom_theme.block.figure = Object.assign(custom_theme.block.figure,jsonString.figure); + + // inline + custom_theme.inline.strong = Object.assign(custom_theme.inline.strong,jsonString.strong); + custom_theme.inline.table = Object.assign(custom_theme.inline.table,jsonString.table); + custom_theme.inline.thead = Object.assign(custom_theme.inline.thead,jsonString.thead); + custom_theme.inline.strong = Object.assign(custom_theme.inline.strong,jsonString.strong); + custom_theme.inline.link = Object.assign(custom_theme.inline.link,jsonString.link); + custom_theme.inline.wx_link = Object.assign(custom_theme.inline.wx_link,jsonString.wx_link); + custom_theme.block.h2['background'] = color; custom_theme.block.h3['border-left'] = `3px solid ${color}`; - custom_theme.block.h4['color'] = color; custom_theme.inline.strong['color'] = color; return custom_theme; - }; -} -let customCss = customCssWithTemplate(default_theme); +} /** @@ -109,4 +121,4 @@ function css2json(css) { // 返回JSON形式的结果串 return json; -} \ No newline at end of file +} diff --git a/index.html b/index.html index dc44d71..ebe980a 100644 --- a/index.html +++ b/index.html @@ -13,12 +13,22 @@ - + + + + + + + + + + +
@@ -103,10 +113,16 @@ -