diff --git a/core/function.php b/core/function.php index 065a739..b154112 100644 --- a/core/function.php +++ b/core/function.php @@ -2,7 +2,7 @@ /* 获取主题当前版本号 */ function _getVersion() { - return "6.1.2"; + return "6.1.3"; }; /* 判断是否是手机 */ diff --git a/package.json b/package.json index 987c3dd..6cffa3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typecho-joe-next", - "version": "6.1.2", + "version": "6.1.3", "description": "A Theme Of Typecho", "main": "index.php", "keywords": [ diff --git a/typecho/write/js/joe.write.chunk.js b/typecho/write/js/joe.write.chunk.js index dc09a7f..d155fea 100644 --- a/typecho/write/js/joe.write.chunk.js +++ b/typecho/write/js/joe.write.chunk.js @@ -13472,148 +13472,148 @@ ]); class JoeAction { - constructor() { - $('body').append('
'); - $('.cm-modal__wrapper-footer--cancle').on('click', () => { - this.options.cancel(); - $('.cm-modal').removeClass('active'); - }); - $('.cm-modal__wrapper-footer--confirm').on('click', () => { - this.options.confirm(); - $('.cm-modal').removeClass('active'); - }); - } - _openModal(options = {}) { - const _options = { - title: '提示', - innerHtml: '内容', - cancel: () => {}, - confirm: () => {} - }; - this.options = Object.assign(_options, options); - $('.cm-modal__wrapper-header').html(this.options.title); - $('.cm-modal__wrapper-bodyer').html(this.options.innerHtml); - $('.cm-modal').addClass('active'); - } - _getLineCh(cm) { - const head = cm.state.selection.main.head; - const line = cm.state.doc.lineAt(head); - return head - line.from; - } - _replaceSelection(cm, str) { - cm.dispatch(cm.state.replaceSelection(str)); - } - _setCursor(cm, pos) { - cm.dispatch({ selection: { anchor: pos } }); - } - _getSelection(cm) { - return cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to); - } - _insetAmboText(cm, str) { - const cursor = cm.state.selection.main.head; - const selection = this._getSelection(cm); - this._replaceSelection(cm, ` ${str + selection + str} `); - if (selection === '') this._setCursor(cm, cursor + str.length + 1); - cm.focus(); - } - handleFullScreen(el) { - el.toggleClass('active'); - $('body').toggleClass('fullscreen'); - $('.cm-container').toggleClass('fullscreen'); - $('.cm-preview').width(0); - } - handlePublish() { - $('#btn-submit').click(); - } - handleUndo(cm) { - undo(cm); - cm.focus(); - } - handleRedo(cm) { - redo(cm); - cm.focus(); - } - handleIndent(cm) { - this._replaceSelection(cm, ' '); - cm.focus(); - } - handleTime(cm) { - const time = new Date(); - const _Year = time.getFullYear(); - const _Month = String(time.getMonth() + 1).padStart(2, 0); - const _Date = String(time.getDate()).padStart(2, 0); - const _Hours = String(time.getHours()).padStart(2, 0); - const _Minutes = String(time.getMinutes()).padStart(2, 0); - const _Seconds = String(time.getSeconds()).padStart(2, 0); - const _Day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][time.getDay()]; - const _time = `${this._getLineCh(cm) ? '\n' : ''}${_Year}-${_Month}-${_Date} ${_Hours}:${_Minutes}:${_Seconds} ${_Day}\n`; - this._replaceSelection(cm, _time); - cm.focus(); - } - handleHr(cm) { - const str = `${this._getLineCh(cm) ? '\n' : ''}\n------------\n\n`; - this._replaceSelection(cm, str); - cm.focus(); - } - handleClean(cm) { - cm.dispatch({ changes: { from: 0, to: cm.state.doc.length, insert: '' } }); - cm.focus(); - } - handleOrdered(cm) { - const selection = this._getSelection(cm); - if (selection === '') { - const str = (this._getLineCh(cm) ? '\n\n' : '') + '1. '; - this._replaceSelection(cm, str); - } else { - const selectionText = selection.split('\n'); - for (let i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = selectionText[i] === '' ? '' : i + 1 + '. ' + selectionText[i]; - } - const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); - this._replaceSelection(cm, str); - } - cm.focus(); - } - handleUnordered(cm) { - const selection = this._getSelection(cm); - if (selection === '') { - const str = (this._getLineCh(cm) ? '\n' : '') + '- '; - this._replaceSelection(cm, str); - } else { - const selectionText = selection.split('\n'); - for (let i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = selectionText[i] === '' ? '' : '- ' + selectionText[i]; - } - const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); - this._replaceSelection(cm, str); - } - cm.focus(); - } - handleQuote(cm) { - const selection = this._getSelection(cm); - if (selection === '') { - this._replaceSelection(cm, `${this._getLineCh(cm) ? '\n' : ''}> `); - } else { - const selectionText = selection.split('\n'); - for (let i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = selectionText[i] === '' ? '' : '> ' + selectionText[i]; - } - const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); - this._replaceSelection(cm, str); - } - cm.focus(); - } - handleDownload(cm) { - const title = $('#title').val() || '新文章'; - const aTag = document.createElement('a'); - let blob = new Blob([cm.state.doc.toString()]); - aTag.download = title + '.md'; - aTag.href = URL.createObjectURL(blob); - aTag.click(); - URL.revokeObjectURL(blob); - } - handleTitle(cm, tool) { - const item = $(` + constructor() { + $('body').append('
'); + $('.cm-modal__wrapper-footer--cancle').on('click', () => { + this.options.cancel(); + $('.cm-modal').removeClass('active'); + }); + $('.cm-modal__wrapper-footer--confirm').on('click', () => { + this.options.confirm(); + $('.cm-modal').removeClass('active'); + }); + } + _openModal(options = {}) { + const _options = { + title: '提示', + innerHtml: '内容', + cancel: () => {}, + confirm: () => {} + }; + this.options = Object.assign(_options, options); + $('.cm-modal__wrapper-header').html(this.options.title); + $('.cm-modal__wrapper-bodyer').html(this.options.innerHtml); + $('.cm-modal').addClass('active'); + } + _getLineCh(cm) { + const head = cm.state.selection.main.head; + const line = cm.state.doc.lineAt(head); + return head - line.from; + } + _replaceSelection(cm, str) { + cm.dispatch(cm.state.replaceSelection(str)); + } + _setCursor(cm, pos) { + cm.dispatch({ selection: { anchor: pos } }); + } + _getSelection(cm) { + return cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to); + } + _insetAmboText(cm, str) { + const cursor = cm.state.selection.main.head; + const selection = this._getSelection(cm); + this._replaceSelection(cm, ` ${str + selection + str} `); + if (selection === '') this._setCursor(cm, cursor + str.length + 1); + cm.focus(); + } + handleFullScreen(el) { + el.toggleClass('active'); + $('body').toggleClass('fullscreen'); + $('.cm-container').toggleClass('fullscreen'); + $('.cm-preview').width(0); + } + handlePublish() { + $('#btn-submit').click(); + } + handleUndo(cm) { + undo(cm); + cm.focus(); + } + handleRedo(cm) { + redo(cm); + cm.focus(); + } + handleIndent(cm) { + this._replaceSelection(cm, ' '); + cm.focus(); + } + handleTime(cm) { + const time = new Date(); + const _Year = time.getFullYear(); + const _Month = String(time.getMonth() + 1).padStart(2, 0); + const _Date = String(time.getDate()).padStart(2, 0); + const _Hours = String(time.getHours()).padStart(2, 0); + const _Minutes = String(time.getMinutes()).padStart(2, 0); + const _Seconds = String(time.getSeconds()).padStart(2, 0); + const _Day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][time.getDay()]; + const _time = `${this._getLineCh(cm) ? '\n' : ''}${_Year}-${_Month}-${_Date} ${_Hours}:${_Minutes}:${_Seconds} ${_Day}\n`; + this._replaceSelection(cm, _time); + cm.focus(); + } + handleHr(cm) { + const str = `${this._getLineCh(cm) ? '\n' : ''}\n------------\n\n`; + this._replaceSelection(cm, str); + cm.focus(); + } + handleClean(cm) { + cm.dispatch({ changes: { from: 0, to: cm.state.doc.length, insert: '' } }); + cm.focus(); + } + handleOrdered(cm) { + const selection = this._getSelection(cm); + if (selection === '') { + const str = (this._getLineCh(cm) ? '\n\n' : '') + '1. '; + this._replaceSelection(cm, str); + } else { + const selectionText = selection.split('\n'); + for (let i = 0, len = selectionText.length; i < len; i++) { + selectionText[i] = selectionText[i] === '' ? '' : i + 1 + '. ' + selectionText[i]; + } + const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); + this._replaceSelection(cm, str); + } + cm.focus(); + } + handleUnordered(cm) { + const selection = this._getSelection(cm); + if (selection === '') { + const str = (this._getLineCh(cm) ? '\n' : '') + '- '; + this._replaceSelection(cm, str); + } else { + const selectionText = selection.split('\n'); + for (let i = 0, len = selectionText.length; i < len; i++) { + selectionText[i] = selectionText[i] === '' ? '' : '- ' + selectionText[i]; + } + const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); + this._replaceSelection(cm, str); + } + cm.focus(); + } + handleQuote(cm) { + const selection = this._getSelection(cm); + if (selection === '') { + this._replaceSelection(cm, `${this._getLineCh(cm) ? '\n' : ''}> `); + } else { + const selectionText = selection.split('\n'); + for (let i = 0, len = selectionText.length; i < len; i++) { + selectionText[i] = selectionText[i] === '' ? '' : '> ' + selectionText[i]; + } + const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); + this._replaceSelection(cm, str); + } + cm.focus(); + } + handleDownload(cm) { + const title = $('#title').val() || '新文章'; + const aTag = document.createElement('a'); + let blob = new Blob([cm.state.doc.toString()]); + aTag.download = title + '.md'; + aTag.href = URL.createObjectURL(blob); + aTag.click(); + URL.revokeObjectURL(blob); + } + handleTitle(cm, tool) { + const item = $(`
${tool.innerHTML}
@@ -13626,26 +13626,26 @@
`); - item.on('click', function (e) { - e.stopPropagation(); - $(this).toggleClass('active'); - }); - const _this = this; - item.on('click', '.cm-tools__dropdown-item', function (e) { - e.stopPropagation(); - const text = $(this).attr('data-text'); - if (_this._getLineCh(cm)) _this._replaceSelection(cm, '\n\n' + text); - else _this._replaceSelection(cm, text); - item.removeClass('active'); - cm.focus(); - }); - $(document).on('click', () => item.removeClass('active')); - $('.cm-tools').append(item); - } - handleLink(cm) { - this._openModal({ - title: '插入链接', - innerHtml: ` + item.on('click', function (e) { + e.stopPropagation(); + $(this).toggleClass('active'); + }); + const _this = this; + item.on('click', '.cm-tools__dropdown-item', function (e) { + e.stopPropagation(); + const text = $(this).attr('data-text'); + if (_this._getLineCh(cm)) _this._replaceSelection(cm, '\n\n' + text); + else _this._replaceSelection(cm, text); + item.removeClass('active'); + cm.focus(); + }); + $(document).on('click', () => item.removeClass('active')); + $('.cm-tools').append(item); + } + handleLink(cm) { + this._openModal({ + title: '插入链接', + innerHtml: `
@@ -13655,18 +13655,18 @@
`, - confirm: () => { - const title = $(".cm-modal input[name='title']").val() || 'Test'; - const url = $(".cm-modal input[name='url']").val() || 'http://'; - this._replaceSelection(cm, ` [${title}](${url}) `); - cm.focus(); - } - }); - } - handleImage(cm) { - this._openModal({ - title: '插入图片', - innerHtml: ` + confirm: () => { + const title = $(".cm-modal input[name='title']").val() || 'Test'; + const url = $(".cm-modal input[name='url']").val() || 'http://'; + this._replaceSelection(cm, ` [${title}](${url}) `); + cm.focus(); + } + }); + } + handleImage(cm) { + this._openModal({ + title: '插入图片', + innerHtml: `
@@ -13676,18 +13676,18 @@
`, - confirm: () => { - const title = $(".cm-modal input[name='title']").val() || 'Test'; - const url = $(".cm-modal input[name='url']").val() || 'http://'; - this._replaceSelection(cm, ` ![${title}](${url}) `); - cm.focus(); - } - }); - } - handleTable(cm) { - this._openModal({ - title: '插入表格', - innerHtml: ` + confirm: () => { + const title = $(".cm-modal input[name='title']").val() || 'Test'; + const url = $(".cm-modal input[name='url']").val() || 'http://'; + this._replaceSelection(cm, ` ![${title}](${url}) `); + cm.focus(); + } + }); + } + handleTable(cm) { + this._openModal({ + title: '插入表格', + innerHtml: `
@@ -13695,201 +13695,201 @@
`, - confirm: () => { - let row = $(".cm-modal input[name='row']").val(); - let column = $(".cm-modal input[name='column']").val(); - if (isNaN(row)) row = 3; - if (isNaN(column)) column = 3; - let rowStr = ''; - let rangeStr = ''; - let columnlStr = ''; - for (let i = 0; i < column; i++) { - rowStr += '| 表头 '; - rangeStr += '| :--: '; - } - for (let i = 0; i < row; i++) { - for (let j = 0; j < column; j++) columnlStr += '| 表格 '; - columnlStr += '|\n'; - } - const htmlStr = `${rowStr}|\n${rangeStr}|\n${columnlStr}\n`; - if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); - else this._replaceSelection(cm, htmlStr); - cm.focus(); - } - }); - } - handleCodeBlock(cm) { - this._openModal({ - title: '插入代码块', - innerHtml: ` + confirm: () => { + let row = $(".cm-modal input[name='row']").val(); + let column = $(".cm-modal input[name='column']").val(); + if (isNaN(row)) row = 3; + if (isNaN(column)) column = 3; + let rowStr = ''; + let rangeStr = ''; + let columnlStr = ''; + for (let i = 0; i < column; i++) { + rowStr += '| 表头 '; + rangeStr += '| :--: '; + } + for (let i = 0; i < row; i++) { + for (let j = 0; j < column; j++) columnlStr += '| 表格 '; + columnlStr += '|\n'; + } + const htmlStr = `${rowStr}|\n${rangeStr}|\n${columnlStr}\n`; + if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); + else this._replaceSelection(cm, htmlStr); + cm.focus(); + } + }); + } + handleCodeBlock(cm) { + this._openModal({ + title: '插入代码块', + innerHtml: `
`, - confirm: () => { - const type = $(".cm-modal input[name='type']").val() || 'html'; - const htmlStr = `\`\`\`${type}\ncode here...\n\`\`\``; - if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); - else this._replaceSelection(cm, htmlStr); - cm.focus(); - } - }); - } - handleAbout() { - this._openModal({ - title: '关于', - innerHtml: ` + confirm: () => { + const type = $(".cm-modal input[name='type']").val() || 'html'; + const htmlStr = `\`\`\`${type}\ncode here...\n\`\`\``; + if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); + else this._replaceSelection(cm, htmlStr); + cm.focus(); + } + }); + } + handleAbout() { + this._openModal({ + title: '关于', + innerHtml: ` ` - }); - } + }); + } } class Joe extends JoeAction { - constructor() { - super(); - this.tools = [ - { - type: 'undo', - title: '撤销', - innerHTML: '' - }, - { - type: 'redo', - title: '重做', - innerHTML: '' - }, - { - type: 'bold', - title: '加粗', - innerHTML: '' - }, - { - type: 'italic', - title: '倾斜', - innerHTML: '' - }, - { - type: 'delete', - title: '删除', - innerHTML: '' - }, - { - type: 'code-inline', - title: '行内代码', - innerHTML: '' - }, - { - type: 'indent', - title: '缩进', - innerHTML: '' - }, - { - type: 'hr', - title: '横线', - innerHTML: '' - }, - { - type: 'quote', - title: '引用', - innerHTML: '' - }, - { - type: 'title', - title: '标题', - innerHTML: '' - }, - { - type: 'ordered-list', - title: '有序列表', - innerHTML: '' - }, - { - type: 'unordered-list', - title: '无序列表', - innerHTML: '' - }, - { - type: 'link', - title: '超链接', - innerHTML: '' - }, - { - type: 'image', - title: '插入图片', - innerHTML: '' - }, - { - type: 'table', - title: '表格', - innerHTML: '' - }, - { - type: 'code-block', - title: '代码块', - innerHTML: '' - }, - { - type: 'time', - title: '当前时间', - innerHTML: '' - }, - { - type: 'clean', - title: '清屏', - innerHTML: '' - }, - { - type: 'download', - title: '下载', - innerHTML: '' - }, - { - type: 'fullScreen', - title: '全屏/取消全屏', - innerHTML: '' - }, - { - type: 'publish', - title: '发布文章', - innerHTML: '' - }, - { - type: 'about', - title: '关于', - innerHTML: '' - } - ]; - this.plugins = [classHighlightStyle, history(), bracketMatching(), closeBrackets()]; - this.keymaps = [defaultTabBinding, ...defaultKeymap, ...historyKeymap, ...closeBracketsKeymap]; - this.parser = new HyperDown(); - this._isPasting = false; - this.init_ViewPort(); - this.init_Editor(); - this.init_Preview(); - this.init_Tools(); - this.init_Insert(); - } + constructor() { + super(); + this.tools = [ + { + type: 'undo', + title: '撤销', + innerHTML: '' + }, + { + type: 'redo', + title: '重做', + innerHTML: '' + }, + { + type: 'bold', + title: '加粗', + innerHTML: '' + }, + { + type: 'italic', + title: '倾斜', + innerHTML: '' + }, + { + type: 'delete', + title: '删除', + innerHTML: '' + }, + { + type: 'code-inline', + title: '行内代码', + innerHTML: '' + }, + { + type: 'indent', + title: '缩进', + innerHTML: '' + }, + { + type: 'hr', + title: '横线', + innerHTML: '' + }, + { + type: 'quote', + title: '引用', + innerHTML: '' + }, + { + type: 'title', + title: '标题', + innerHTML: '' + }, + { + type: 'ordered-list', + title: '有序列表', + innerHTML: '' + }, + { + type: 'unordered-list', + title: '无序列表', + innerHTML: '' + }, + { + type: 'link', + title: '超链接', + innerHTML: '' + }, + { + type: 'image', + title: '插入图片', + innerHTML: '' + }, + { + type: 'table', + title: '表格', + innerHTML: '' + }, + { + type: 'code-block', + title: '代码块', + innerHTML: '' + }, + { + type: 'time', + title: '当前时间', + innerHTML: '' + }, + { + type: 'clean', + title: '清屏', + innerHTML: '' + }, + { + type: 'download', + title: '下载', + innerHTML: '' + }, + { + type: 'fullScreen', + title: '全屏/取消全屏', + innerHTML: '' + }, + { + type: 'publish', + title: '发布文章', + innerHTML: '' + }, + { + type: 'about', + title: '关于', + innerHTML: '' + } + ]; + this.plugins = [classHighlightStyle, history(), bracketMatching(), closeBrackets()]; + this.keymaps = [defaultTabBinding, ...defaultKeymap, ...historyKeymap, ...closeBracketsKeymap]; + this.parser = new HyperDown(); + this._isPasting = false; + this.init_ViewPort(); + this.init_Editor(); + this.init_Preview(); + this.init_Tools(); + this.init_Insert(); + } - /* 已测 √ */ - init_ViewPort() { - try { - if ($('meta[name="viewport"]').length > 0) $('meta[name="viewport"]').attr('content', 'width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover'); - else $('head').append(''); - } catch (e) { - console.error('Init_ViewPort Error: ' + e); - } - } + /* 已测 √ */ + init_ViewPort() { + try { + if ($('meta[name="viewport"]').length > 0) $('meta[name="viewport"]').attr('content', 'width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover'); + else $('head').append(''); + } catch (e) { + console.error('Init_ViewPort Error: ' + e); + } + } - /* 已测 √ */ - init_Editor() { - try { - $('#text').before(` + /* 已测 √ */ + init_Editor() { + try { + $('#text').before(`
@@ -13902,224 +13902,224 @@
`); - const cm = new EditorView({ - state: EditorState.create({ - doc: $('#text').val(), - extensions: [ - ...this.plugins, - keymap.of([...this.keymaps]), - EditorView.updateListener.of(update => { - if (!update.docChanged) return; - $('.cm-preview-content').html(this.parser.makeHtml(update.state.doc.toString())); - }), - EditorView.domEventHandlers({ - paste: e => { - const clipboardData = e.clipboardData; - if (!clipboardData || !clipboardData.items) return; - const items = clipboardData.items; - if (!items.length) return; - let blob = null; - for (let i = 0; i < items.length; i++) { - if (items[i].type.indexOf('image') !== -1) { - e.preventDefault(); - blob = items[i].getAsFile(); - break; - } - } - if (!blob) return; - let api = $('script[api]').attr('api'); - if (!api) return; - const cid = $('input[name="cid"]').val(); - cid && (api = api + '&cid=' + cid); - if (this._isPasting) return; - this._isPasting = true; - const fileName = Date.now().toString(36) + '.png'; - let formData = new FormData(); - formData.append('name', fileName); - formData.append('file', blob, fileName); - $.ajax({ - url: api, - method: 'post', - data: formData, - contentType: false, - processData: false, - dataType: 'json', - xhr: () => { - const xhr = $.ajaxSettings.xhr(); - if (!xhr.upload) return; - xhr.upload.addEventListener( - 'progress', - e => { - let percent = (e.loaded / e.total) * 100; - $('.cm-progress-left').width(percent / 2 + '%'); - $('.cm-progress-right').width(percent / 2 + '%'); - }, - false - ); - return xhr; - }, - success: res => { - $('.cm-progress-left').width(0); - $('.cm-progress-right').width(0); - this._isPasting = false; - const str = `${super._getLineCh(cm) ? '\n' : ''}![${res[1].title}](${res[0]})\n`; - super._replaceSelection(cm, str); - cm.focus(); - }, - error: () => { - $('.cm-progress-left').width(0); - $('.cm-progress-right').width(0); - this._isPasting = false; - } - }); - } - }) - ] - }) - }); - $('.cm-mainer').prepend(cm.dom); - $('form[name="write_post"]').on('submit', () => $('#text').val(cm.state.doc.toString())); - this.cm = cm; - } catch (e) { - console.error('Init_Editor Error: ' + e); - } - } + const cm = new EditorView({ + state: EditorState.create({ + doc: $('#text').val(), + extensions: [ + ...this.plugins, + keymap.of([...this.keymaps]), + EditorView.updateListener.of(update => { + if (!update.docChanged) return; + $('.cm-preview-content').html(this.parser.makeHtml(update.state.doc.toString())); + }), + EditorView.domEventHandlers({ + paste: e => { + const clipboardData = e.clipboardData; + if (!clipboardData || !clipboardData.items) return; + const items = clipboardData.items; + if (!items.length) return; + let blob = null; + for (let i = 0; i < items.length; i++) { + if (items[i].type.indexOf('image') !== -1) { + e.preventDefault(); + blob = items[i].getAsFile(); + break; + } + } + if (!blob) return; + let api = $('script[api]').attr('api'); + if (!api) return; + const cid = $('input[name="cid"]').val(); + cid && (api = api + '&cid=' + cid); + if (this._isPasting) return; + this._isPasting = true; + const fileName = Date.now().toString(36) + '.png'; + let formData = new FormData(); + formData.append('name', fileName); + formData.append('file', blob, fileName); + $.ajax({ + url: api, + method: 'post', + data: formData, + contentType: false, + processData: false, + dataType: 'json', + xhr: () => { + const xhr = $.ajaxSettings.xhr(); + if (!xhr.upload) return; + xhr.upload.addEventListener( + 'progress', + e => { + let percent = (e.loaded / e.total) * 100; + $('.cm-progress-left').width(percent / 2 + '%'); + $('.cm-progress-right').width(percent / 2 + '%'); + }, + false + ); + return xhr; + }, + success: res => { + $('.cm-progress-left').width(0); + $('.cm-progress-right').width(0); + this._isPasting = false; + const str = `${super._getLineCh(cm) ? '\n' : ''}![${res[1].title}](${res[0]})\n`; + super._replaceSelection(cm, str); + cm.focus(); + }, + error: () => { + $('.cm-progress-left').width(0); + $('.cm-progress-right').width(0); + this._isPasting = false; + } + }); + } + }) + ] + }) + }); + $('.cm-mainer').prepend(cm.dom); + $('#text')[0].form && $('#text')[0].form.addEventListener('submit', () => $('#text').val(cm.state.doc.toString())); + this.cm = cm; + } catch (e) { + console.error('Init_Editor Error: ' + e); + } + } - /* 已测 √ */ - init_Preview() { - const move = (nowClientX, nowWidth, clientX) => { - let moveX = nowClientX - clientX; - let moveWidth = nowWidth + moveX; - if (moveWidth <= 0) moveWidth = 0; - if (moveWidth >= $('.cm-mainer').outerWidth() - 16) moveWidth = $('.cm-mainer').outerWidth() - 16; - $('.cm-preview').width(moveWidth); - }; - $('.cm-resize').on({ - mousedown: e => { - e.preventDefault(); - e.stopPropagation(); - const nowWidth = $('.cm-preview').outerWidth(); - const nowClientX = e.clientX; - document.onmousemove = _e => { - if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.clientX)); - else move(nowClientX, nowWidth, _e.clientX); - }; - document.onmouseup = () => { - document.onmousemove = null; - document.onmouseup = null; - }; - return false; - }, - touchstart: e => { - e.preventDefault(); - e.stopPropagation(); - const nowWidth = $('.cm-preview').outerWidth(); - const nowClientX = e.originalEvent.targetTouches[0].clientX; - document.ontouchmove = _e => { - if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.targetTouches[0].clientX)); - else move(nowClientX, nowWidth, _e.targetTouches[0].clientX); - }; - document.ontouchend = () => { - document.ontouchmove = null; - document.ontouchend = null; - }; - return false; - } - }); - } + /* 已测 √ */ + init_Preview() { + const move = (nowClientX, nowWidth, clientX) => { + let moveX = nowClientX - clientX; + let moveWidth = nowWidth + moveX; + if (moveWidth <= 0) moveWidth = 0; + if (moveWidth >= $('.cm-mainer').outerWidth() - 16) moveWidth = $('.cm-mainer').outerWidth() - 16; + $('.cm-preview').width(moveWidth); + }; + $('.cm-resize').on({ + mousedown: e => { + e.preventDefault(); + e.stopPropagation(); + const nowWidth = $('.cm-preview').outerWidth(); + const nowClientX = e.clientX; + document.onmousemove = _e => { + if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.clientX)); + else move(nowClientX, nowWidth, _e.clientX); + }; + document.onmouseup = () => { + document.onmousemove = null; + document.onmouseup = null; + }; + return false; + }, + touchstart: e => { + e.preventDefault(); + e.stopPropagation(); + const nowWidth = $('.cm-preview').outerWidth(); + const nowClientX = e.originalEvent.targetTouches[0].clientX; + document.ontouchmove = _e => { + if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.targetTouches[0].clientX)); + else move(nowClientX, nowWidth, _e.targetTouches[0].clientX); + }; + document.ontouchend = () => { + document.ontouchmove = null; + document.ontouchend = null; + }; + return false; + } + }); + } - /* 已测 √ */ - init_Tools() { - this.tools.forEach(item => { - if (item.type === 'title') { - super.handleTitle(this.cm, item); - } else { - const el = $(`
${item.innerHTML}
`); - el.on('click', e => { - e.preventDefault(); - switch (item.type) { - case 'fullScreen': - super.handleFullScreen(el); - break; - case 'publish': - super.handlePublish(); - break; - case 'undo': - super.handleUndo(this.cm); - break; - case 'redo': - super.handleRedo(this.cm); - break; - case 'time': - super.handleTime(this.cm); - break; - case 'bold': - super._insetAmboText(this.cm, '**'); - break; - case 'italic': - super._insetAmboText(this.cm, '*'); - break; - case 'delete': - super._insetAmboText(this.cm, '~~'); - break; - case 'code-inline': - super._insetAmboText(this.cm, '`'); - break; - case 'indent': - super.handleIndent(this.cm); - break; - case 'hr': - super.handleHr(this.cm); - break; - case 'clean': - super.handleClean(this.cm); - break; - case 'ordered-list': - super.handleOrdered(this.cm); - break; - case 'unordered-list': - super.handleUnordered(this.cm); - break; - case 'quote': - super.handleQuote(this.cm); - break; - case 'download': - super.handleDownload(this.cm); - break; - case 'link': - super.handleLink(this.cm); - break; - case 'image': - super.handleImage(this.cm); - break; - case 'table': - super.handleTable(this.cm); - break; - case 'code-block': - super.handleCodeBlock(this.cm); - break; - case 'about': - super.handleAbout(); - break; - } - }); - $('.cm-tools').append(el); - } - }); - } + /* 已测 √ */ + init_Tools() { + this.tools.forEach(item => { + if (item.type === 'title') { + super.handleTitle(this.cm, item); + } else { + const el = $(`
${item.innerHTML}
`); + el.on('click', e => { + e.preventDefault(); + switch (item.type) { + case 'fullScreen': + super.handleFullScreen(el); + break; + case 'publish': + super.handlePublish(); + break; + case 'undo': + super.handleUndo(this.cm); + break; + case 'redo': + super.handleRedo(this.cm); + break; + case 'time': + super.handleTime(this.cm); + break; + case 'bold': + super._insetAmboText(this.cm, '**'); + break; + case 'italic': + super._insetAmboText(this.cm, '*'); + break; + case 'delete': + super._insetAmboText(this.cm, '~~'); + break; + case 'code-inline': + super._insetAmboText(this.cm, '`'); + break; + case 'indent': + super.handleIndent(this.cm); + break; + case 'hr': + super.handleHr(this.cm); + break; + case 'clean': + super.handleClean(this.cm); + break; + case 'ordered-list': + super.handleOrdered(this.cm); + break; + case 'unordered-list': + super.handleUnordered(this.cm); + break; + case 'quote': + super.handleQuote(this.cm); + break; + case 'download': + super.handleDownload(this.cm); + break; + case 'link': + super.handleLink(this.cm); + break; + case 'image': + super.handleImage(this.cm); + break; + case 'table': + super.handleTable(this.cm); + break; + case 'code-block': + super.handleCodeBlock(this.cm); + break; + case 'about': + super.handleAbout(); + break; + } + }); + $('.cm-tools').append(el); + } + }); + } - /* 已测 √ */ - init_Insert() { - try { - Typecho.insertFileToEditor = (file, url, isImage) => { - const str = `${super._getLineCh(this.cm) ? '\n' : ''}${isImage ? '!' : ''}[${file}](${url})\n`; - super._replaceSelection(this.cm, str); - this.cm.focus(); - }; - } catch (e) { - console.error('Init_Insert Error: ' + e); - } - } + /* 已测 √ */ + init_Insert() { + try { + Typecho.insertFileToEditor = (file, url, isImage) => { + const str = `${super._getLineCh(this.cm) ? '\n' : ''}${isImage ? '!' : ''}[${file}](${url})\n`; + super._replaceSelection(this.cm, str); + this.cm.focus(); + }; + } catch (e) { + console.error('Init_Insert Error: ' + e); + } + } } document.addEventListener('DOMContentLoaded', () => new Joe()); diff --git a/typecho/write/js/joe.write.js b/typecho/write/js/joe.write.js index 6849b90..b67de4b 100644 --- a/typecho/write/js/joe.write.js +++ b/typecho/write/js/joe.write.js @@ -7,148 +7,148 @@ import { history, historyKeymap, undo, redo } from '@codemirror/history'; import { classHighlightStyle } from '@codemirror/highlight'; class JoeAction { - constructor() { - $('body').append('
'); - $('.cm-modal__wrapper-footer--cancle').on('click', () => { - this.options.cancel(); - $('.cm-modal').removeClass('active'); - }); - $('.cm-modal__wrapper-footer--confirm').on('click', () => { - this.options.confirm(); - $('.cm-modal').removeClass('active'); - }); - } - _openModal(options = {}) { - const _options = { - title: '提示', - innerHtml: '内容', - cancel: () => {}, - confirm: () => {} - }; - this.options = Object.assign(_options, options); - $('.cm-modal__wrapper-header').html(this.options.title); - $('.cm-modal__wrapper-bodyer').html(this.options.innerHtml); - $('.cm-modal').addClass('active'); - } - _getLineCh(cm) { - const head = cm.state.selection.main.head; - const line = cm.state.doc.lineAt(head); - return head - line.from; - } - _replaceSelection(cm, str) { - cm.dispatch(cm.state.replaceSelection(str)); - } - _setCursor(cm, pos) { - cm.dispatch({ selection: { anchor: pos } }); - } - _getSelection(cm) { - return cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to); - } - _insetAmboText(cm, str) { - const cursor = cm.state.selection.main.head; - const selection = this._getSelection(cm); - this._replaceSelection(cm, ` ${str + selection + str} `); - if (selection === '') this._setCursor(cm, cursor + str.length + 1); - cm.focus(); - } - handleFullScreen(el) { - el.toggleClass('active'); - $('body').toggleClass('fullscreen'); - $('.cm-container').toggleClass('fullscreen'); - $('.cm-preview').width(0); - } - handlePublish() { - $('#btn-submit').click(); - } - handleUndo(cm) { - undo(cm); - cm.focus(); - } - handleRedo(cm) { - redo(cm); - cm.focus(); - } - handleIndent(cm) { - this._replaceSelection(cm, ' '); - cm.focus(); - } - handleTime(cm) { - const time = new Date(); - const _Year = time.getFullYear(); - const _Month = String(time.getMonth() + 1).padStart(2, 0); - const _Date = String(time.getDate()).padStart(2, 0); - const _Hours = String(time.getHours()).padStart(2, 0); - const _Minutes = String(time.getMinutes()).padStart(2, 0); - const _Seconds = String(time.getSeconds()).padStart(2, 0); - const _Day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][time.getDay()]; - const _time = `${this._getLineCh(cm) ? '\n' : ''}${_Year}-${_Month}-${_Date} ${_Hours}:${_Minutes}:${_Seconds} ${_Day}\n`; - this._replaceSelection(cm, _time); - cm.focus(); - } - handleHr(cm) { - const str = `${this._getLineCh(cm) ? '\n' : ''}\n------------\n\n`; - this._replaceSelection(cm, str); - cm.focus(); - } - handleClean(cm) { - cm.dispatch({ changes: { from: 0, to: cm.state.doc.length, insert: '' } }); - cm.focus(); - } - handleOrdered(cm) { - const selection = this._getSelection(cm); - if (selection === '') { - const str = (this._getLineCh(cm) ? '\n\n' : '') + '1. '; - this._replaceSelection(cm, str); - } else { - const selectionText = selection.split('\n'); - for (let i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = selectionText[i] === '' ? '' : i + 1 + '. ' + selectionText[i]; - } - const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); - this._replaceSelection(cm, str); - } - cm.focus(); - } - handleUnordered(cm) { - const selection = this._getSelection(cm); - if (selection === '') { - const str = (this._getLineCh(cm) ? '\n' : '') + '- '; - this._replaceSelection(cm, str); - } else { - const selectionText = selection.split('\n'); - for (let i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = selectionText[i] === '' ? '' : '- ' + selectionText[i]; - } - const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); - this._replaceSelection(cm, str); - } - cm.focus(); - } - handleQuote(cm) { - const selection = this._getSelection(cm); - if (selection === '') { - this._replaceSelection(cm, `${this._getLineCh(cm) ? '\n' : ''}> `); - } else { - const selectionText = selection.split('\n'); - for (let i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = selectionText[i] === '' ? '' : '> ' + selectionText[i]; - } - const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); - this._replaceSelection(cm, str); - } - cm.focus(); - } - handleDownload(cm) { - const title = $('#title').val() || '新文章'; - const aTag = document.createElement('a'); - let blob = new Blob([cm.state.doc.toString()]); - aTag.download = title + '.md'; - aTag.href = URL.createObjectURL(blob); - aTag.click(); - URL.revokeObjectURL(blob); - } - handleTitle(cm, tool) { - const item = $(` + constructor() { + $('body').append('
'); + $('.cm-modal__wrapper-footer--cancle').on('click', () => { + this.options.cancel(); + $('.cm-modal').removeClass('active'); + }); + $('.cm-modal__wrapper-footer--confirm').on('click', () => { + this.options.confirm(); + $('.cm-modal').removeClass('active'); + }); + } + _openModal(options = {}) { + const _options = { + title: '提示', + innerHtml: '内容', + cancel: () => {}, + confirm: () => {} + }; + this.options = Object.assign(_options, options); + $('.cm-modal__wrapper-header').html(this.options.title); + $('.cm-modal__wrapper-bodyer').html(this.options.innerHtml); + $('.cm-modal').addClass('active'); + } + _getLineCh(cm) { + const head = cm.state.selection.main.head; + const line = cm.state.doc.lineAt(head); + return head - line.from; + } + _replaceSelection(cm, str) { + cm.dispatch(cm.state.replaceSelection(str)); + } + _setCursor(cm, pos) { + cm.dispatch({ selection: { anchor: pos } }); + } + _getSelection(cm) { + return cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to); + } + _insetAmboText(cm, str) { + const cursor = cm.state.selection.main.head; + const selection = this._getSelection(cm); + this._replaceSelection(cm, ` ${str + selection + str} `); + if (selection === '') this._setCursor(cm, cursor + str.length + 1); + cm.focus(); + } + handleFullScreen(el) { + el.toggleClass('active'); + $('body').toggleClass('fullscreen'); + $('.cm-container').toggleClass('fullscreen'); + $('.cm-preview').width(0); + } + handlePublish() { + $('#btn-submit').click(); + } + handleUndo(cm) { + undo(cm); + cm.focus(); + } + handleRedo(cm) { + redo(cm); + cm.focus(); + } + handleIndent(cm) { + this._replaceSelection(cm, ' '); + cm.focus(); + } + handleTime(cm) { + const time = new Date(); + const _Year = time.getFullYear(); + const _Month = String(time.getMonth() + 1).padStart(2, 0); + const _Date = String(time.getDate()).padStart(2, 0); + const _Hours = String(time.getHours()).padStart(2, 0); + const _Minutes = String(time.getMinutes()).padStart(2, 0); + const _Seconds = String(time.getSeconds()).padStart(2, 0); + const _Day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][time.getDay()]; + const _time = `${this._getLineCh(cm) ? '\n' : ''}${_Year}-${_Month}-${_Date} ${_Hours}:${_Minutes}:${_Seconds} ${_Day}\n`; + this._replaceSelection(cm, _time); + cm.focus(); + } + handleHr(cm) { + const str = `${this._getLineCh(cm) ? '\n' : ''}\n------------\n\n`; + this._replaceSelection(cm, str); + cm.focus(); + } + handleClean(cm) { + cm.dispatch({ changes: { from: 0, to: cm.state.doc.length, insert: '' } }); + cm.focus(); + } + handleOrdered(cm) { + const selection = this._getSelection(cm); + if (selection === '') { + const str = (this._getLineCh(cm) ? '\n\n' : '') + '1. '; + this._replaceSelection(cm, str); + } else { + const selectionText = selection.split('\n'); + for (let i = 0, len = selectionText.length; i < len; i++) { + selectionText[i] = selectionText[i] === '' ? '' : i + 1 + '. ' + selectionText[i]; + } + const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); + this._replaceSelection(cm, str); + } + cm.focus(); + } + handleUnordered(cm) { + const selection = this._getSelection(cm); + if (selection === '') { + const str = (this._getLineCh(cm) ? '\n' : '') + '- '; + this._replaceSelection(cm, str); + } else { + const selectionText = selection.split('\n'); + for (let i = 0, len = selectionText.length; i < len; i++) { + selectionText[i] = selectionText[i] === '' ? '' : '- ' + selectionText[i]; + } + const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); + this._replaceSelection(cm, str); + } + cm.focus(); + } + handleQuote(cm) { + const selection = this._getSelection(cm); + if (selection === '') { + this._replaceSelection(cm, `${this._getLineCh(cm) ? '\n' : ''}> `); + } else { + const selectionText = selection.split('\n'); + for (let i = 0, len = selectionText.length; i < len; i++) { + selectionText[i] = selectionText[i] === '' ? '' : '> ' + selectionText[i]; + } + const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n'); + this._replaceSelection(cm, str); + } + cm.focus(); + } + handleDownload(cm) { + const title = $('#title').val() || '新文章'; + const aTag = document.createElement('a'); + let blob = new Blob([cm.state.doc.toString()]); + aTag.download = title + '.md'; + aTag.href = URL.createObjectURL(blob); + aTag.click(); + URL.revokeObjectURL(blob); + } + handleTitle(cm, tool) { + const item = $(`
${tool.innerHTML}
@@ -161,26 +161,26 @@ class JoeAction {
`); - item.on('click', function (e) { - e.stopPropagation(); - $(this).toggleClass('active'); - }); - const _this = this; - item.on('click', '.cm-tools__dropdown-item', function (e) { - e.stopPropagation(); - const text = $(this).attr('data-text'); - if (_this._getLineCh(cm)) _this._replaceSelection(cm, '\n\n' + text); - else _this._replaceSelection(cm, text); - item.removeClass('active'); - cm.focus(); - }); - $(document).on('click', () => item.removeClass('active')); - $('.cm-tools').append(item); - } - handleLink(cm) { - this._openModal({ - title: '插入链接', - innerHtml: ` + item.on('click', function (e) { + e.stopPropagation(); + $(this).toggleClass('active'); + }); + const _this = this; + item.on('click', '.cm-tools__dropdown-item', function (e) { + e.stopPropagation(); + const text = $(this).attr('data-text'); + if (_this._getLineCh(cm)) _this._replaceSelection(cm, '\n\n' + text); + else _this._replaceSelection(cm, text); + item.removeClass('active'); + cm.focus(); + }); + $(document).on('click', () => item.removeClass('active')); + $('.cm-tools').append(item); + } + handleLink(cm) { + this._openModal({ + title: '插入链接', + innerHtml: `
@@ -190,18 +190,18 @@ class JoeAction {
`, - confirm: () => { - const title = $(".cm-modal input[name='title']").val() || 'Test'; - const url = $(".cm-modal input[name='url']").val() || 'http://'; - this._replaceSelection(cm, ` [${title}](${url}) `); - cm.focus(); - } - }); - } - handleImage(cm) { - this._openModal({ - title: '插入图片', - innerHtml: ` + confirm: () => { + const title = $(".cm-modal input[name='title']").val() || 'Test'; + const url = $(".cm-modal input[name='url']").val() || 'http://'; + this._replaceSelection(cm, ` [${title}](${url}) `); + cm.focus(); + } + }); + } + handleImage(cm) { + this._openModal({ + title: '插入图片', + innerHtml: `
@@ -211,18 +211,18 @@ class JoeAction {
`, - confirm: () => { - const title = $(".cm-modal input[name='title']").val() || 'Test'; - const url = $(".cm-modal input[name='url']").val() || 'http://'; - this._replaceSelection(cm, ` ![${title}](${url}) `); - cm.focus(); - } - }); - } - handleTable(cm) { - this._openModal({ - title: '插入表格', - innerHtml: ` + confirm: () => { + const title = $(".cm-modal input[name='title']").val() || 'Test'; + const url = $(".cm-modal input[name='url']").val() || 'http://'; + this._replaceSelection(cm, ` ![${title}](${url}) `); + cm.focus(); + } + }); + } + handleTable(cm) { + this._openModal({ + title: '插入表格', + innerHtml: `
@@ -230,201 +230,201 @@ class JoeAction {
`, - confirm: () => { - let row = $(".cm-modal input[name='row']").val(); - let column = $(".cm-modal input[name='column']").val(); - if (isNaN(row)) row = 3; - if (isNaN(column)) column = 3; - let rowStr = ''; - let rangeStr = ''; - let columnlStr = ''; - for (let i = 0; i < column; i++) { - rowStr += '| 表头 '; - rangeStr += '| :--: '; - } - for (let i = 0; i < row; i++) { - for (let j = 0; j < column; j++) columnlStr += '| 表格 '; - columnlStr += '|\n'; - } - const htmlStr = `${rowStr}|\n${rangeStr}|\n${columnlStr}\n`; - if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); - else this._replaceSelection(cm, htmlStr); - cm.focus(); - } - }); - } - handleCodeBlock(cm) { - this._openModal({ - title: '插入代码块', - innerHtml: ` + confirm: () => { + let row = $(".cm-modal input[name='row']").val(); + let column = $(".cm-modal input[name='column']").val(); + if (isNaN(row)) row = 3; + if (isNaN(column)) column = 3; + let rowStr = ''; + let rangeStr = ''; + let columnlStr = ''; + for (let i = 0; i < column; i++) { + rowStr += '| 表头 '; + rangeStr += '| :--: '; + } + for (let i = 0; i < row; i++) { + for (let j = 0; j < column; j++) columnlStr += '| 表格 '; + columnlStr += '|\n'; + } + const htmlStr = `${rowStr}|\n${rangeStr}|\n${columnlStr}\n`; + if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); + else this._replaceSelection(cm, htmlStr); + cm.focus(); + } + }); + } + handleCodeBlock(cm) { + this._openModal({ + title: '插入代码块', + innerHtml: `
`, - confirm: () => { - const type = $(".cm-modal input[name='type']").val() || 'html'; - const htmlStr = `\`\`\`${type}\ncode here...\n\`\`\``; - if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); - else this._replaceSelection(cm, htmlStr); - cm.focus(); - } - }); - } - handleAbout() { - this._openModal({ - title: '关于', - innerHtml: ` + confirm: () => { + const type = $(".cm-modal input[name='type']").val() || 'html'; + const htmlStr = `\`\`\`${type}\ncode here...\n\`\`\``; + if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr); + else this._replaceSelection(cm, htmlStr); + cm.focus(); + } + }); + } + handleAbout() { + this._openModal({ + title: '关于', + innerHtml: ` ` - }); - } + }); + } } class Joe extends JoeAction { - constructor() { - super(); - this.tools = [ - { - type: 'undo', - title: '撤销', - innerHTML: '' - }, - { - type: 'redo', - title: '重做', - innerHTML: '' - }, - { - type: 'bold', - title: '加粗', - innerHTML: '' - }, - { - type: 'italic', - title: '倾斜', - innerHTML: '' - }, - { - type: 'delete', - title: '删除', - innerHTML: '' - }, - { - type: 'code-inline', - title: '行内代码', - innerHTML: '' - }, - { - type: 'indent', - title: '缩进', - innerHTML: '' - }, - { - type: 'hr', - title: '横线', - innerHTML: '' - }, - { - type: 'quote', - title: '引用', - innerHTML: '' - }, - { - type: 'title', - title: '标题', - innerHTML: '' - }, - { - type: 'ordered-list', - title: '有序列表', - innerHTML: '' - }, - { - type: 'unordered-list', - title: '无序列表', - innerHTML: '' - }, - { - type: 'link', - title: '超链接', - innerHTML: '' - }, - { - type: 'image', - title: '插入图片', - innerHTML: '' - }, - { - type: 'table', - title: '表格', - innerHTML: '' - }, - { - type: 'code-block', - title: '代码块', - innerHTML: '' - }, - { - type: 'time', - title: '当前时间', - innerHTML: '' - }, - { - type: 'clean', - title: '清屏', - innerHTML: '' - }, - { - type: 'download', - title: '下载', - innerHTML: '' - }, - { - type: 'fullScreen', - title: '全屏/取消全屏', - innerHTML: '' - }, - { - type: 'publish', - title: '发布文章', - innerHTML: '' - }, - { - type: 'about', - title: '关于', - innerHTML: '' - } - ]; - this.plugins = [classHighlightStyle, history(), bracketMatching(), closeBrackets()]; - this.keymaps = [defaultTabBinding, ...defaultKeymap, ...historyKeymap, ...closeBracketsKeymap]; - this.parser = new HyperDown(); - this._isPasting = false; - this.init_ViewPort(); - this.init_Editor(); - this.init_Preview(); - this.init_Tools(); - this.init_Insert(); - } + constructor() { + super(); + this.tools = [ + { + type: 'undo', + title: '撤销', + innerHTML: '' + }, + { + type: 'redo', + title: '重做', + innerHTML: '' + }, + { + type: 'bold', + title: '加粗', + innerHTML: '' + }, + { + type: 'italic', + title: '倾斜', + innerHTML: '' + }, + { + type: 'delete', + title: '删除', + innerHTML: '' + }, + { + type: 'code-inline', + title: '行内代码', + innerHTML: '' + }, + { + type: 'indent', + title: '缩进', + innerHTML: '' + }, + { + type: 'hr', + title: '横线', + innerHTML: '' + }, + { + type: 'quote', + title: '引用', + innerHTML: '' + }, + { + type: 'title', + title: '标题', + innerHTML: '' + }, + { + type: 'ordered-list', + title: '有序列表', + innerHTML: '' + }, + { + type: 'unordered-list', + title: '无序列表', + innerHTML: '' + }, + { + type: 'link', + title: '超链接', + innerHTML: '' + }, + { + type: 'image', + title: '插入图片', + innerHTML: '' + }, + { + type: 'table', + title: '表格', + innerHTML: '' + }, + { + type: 'code-block', + title: '代码块', + innerHTML: '' + }, + { + type: 'time', + title: '当前时间', + innerHTML: '' + }, + { + type: 'clean', + title: '清屏', + innerHTML: '' + }, + { + type: 'download', + title: '下载', + innerHTML: '' + }, + { + type: 'fullScreen', + title: '全屏/取消全屏', + innerHTML: '' + }, + { + type: 'publish', + title: '发布文章', + innerHTML: '' + }, + { + type: 'about', + title: '关于', + innerHTML: '' + } + ]; + this.plugins = [classHighlightStyle, history(), bracketMatching(), closeBrackets()]; + this.keymaps = [defaultTabBinding, ...defaultKeymap, ...historyKeymap, ...closeBracketsKeymap]; + this.parser = new HyperDown(); + this._isPasting = false; + this.init_ViewPort(); + this.init_Editor(); + this.init_Preview(); + this.init_Tools(); + this.init_Insert(); + } - /* 已测 √ */ - init_ViewPort() { - try { - if ($('meta[name="viewport"]').length > 0) $('meta[name="viewport"]').attr('content', 'width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover'); - else $('head').append(''); - } catch (e) { - console.error('Init_ViewPort Error: ' + e); - } - } + /* 已测 √ */ + init_ViewPort() { + try { + if ($('meta[name="viewport"]').length > 0) $('meta[name="viewport"]').attr('content', 'width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover'); + else $('head').append(''); + } catch (e) { + console.error('Init_ViewPort Error: ' + e); + } + } - /* 已测 √ */ - init_Editor() { - try { - $('#text').before(` + /* 已测 √ */ + init_Editor() { + try { + $('#text').before(`
@@ -437,224 +437,224 @@ class Joe extends JoeAction {
`); - const cm = new EditorView({ - state: EditorState.create({ - doc: $('#text').val(), - extensions: [ - ...this.plugins, - keymap.of([...this.keymaps]), - EditorView.updateListener.of(update => { - if (!update.docChanged) return; - $('.cm-preview-content').html(this.parser.makeHtml(update.state.doc.toString())); - }), - EditorView.domEventHandlers({ - paste: e => { - const clipboardData = e.clipboardData; - if (!clipboardData || !clipboardData.items) return; - const items = clipboardData.items; - if (!items.length) return; - let blob = null; - for (let i = 0; i < items.length; i++) { - if (items[i].type.indexOf('image') !== -1) { - e.preventDefault(); - blob = items[i].getAsFile(); - break; - } - } - if (!blob) return; - let api = $('script[api]').attr('api'); - if (!api) return; - const cid = $('input[name="cid"]').val(); - cid && (api = api + '&cid=' + cid); - if (this._isPasting) return; - this._isPasting = true; - const fileName = Date.now().toString(36) + '.png'; - let formData = new FormData(); - formData.append('name', fileName); - formData.append('file', blob, fileName); - $.ajax({ - url: api, - method: 'post', - data: formData, - contentType: false, - processData: false, - dataType: 'json', - xhr: () => { - const xhr = $.ajaxSettings.xhr(); - if (!xhr.upload) return; - xhr.upload.addEventListener( - 'progress', - e => { - let percent = (e.loaded / e.total) * 100; - $('.cm-progress-left').width(percent / 2 + '%'); - $('.cm-progress-right').width(percent / 2 + '%'); - }, - false - ); - return xhr; - }, - success: res => { - $('.cm-progress-left').width(0); - $('.cm-progress-right').width(0); - this._isPasting = false; - const str = `${super._getLineCh(cm) ? '\n' : ''}![${res[1].title}](${res[0]})\n`; - super._replaceSelection(cm, str); - cm.focus(); - }, - error: () => { - $('.cm-progress-left').width(0); - $('.cm-progress-right').width(0); - this._isPasting = false; - } - }); - } - }) - ] - }) - }); - $('.cm-mainer').prepend(cm.dom); - $('form[name="write_post"]').on('submit', () => $('#text').val(cm.state.doc.toString())); - this.cm = cm; - } catch (e) { - console.error('Init_Editor Error: ' + e); - } - } + const cm = new EditorView({ + state: EditorState.create({ + doc: $('#text').val(), + extensions: [ + ...this.plugins, + keymap.of([...this.keymaps]), + EditorView.updateListener.of(update => { + if (!update.docChanged) return; + $('.cm-preview-content').html(this.parser.makeHtml(update.state.doc.toString())); + }), + EditorView.domEventHandlers({ + paste: e => { + const clipboardData = e.clipboardData; + if (!clipboardData || !clipboardData.items) return; + const items = clipboardData.items; + if (!items.length) return; + let blob = null; + for (let i = 0; i < items.length; i++) { + if (items[i].type.indexOf('image') !== -1) { + e.preventDefault(); + blob = items[i].getAsFile(); + break; + } + } + if (!blob) return; + let api = $('script[api]').attr('api'); + if (!api) return; + const cid = $('input[name="cid"]').val(); + cid && (api = api + '&cid=' + cid); + if (this._isPasting) return; + this._isPasting = true; + const fileName = Date.now().toString(36) + '.png'; + let formData = new FormData(); + formData.append('name', fileName); + formData.append('file', blob, fileName); + $.ajax({ + url: api, + method: 'post', + data: formData, + contentType: false, + processData: false, + dataType: 'json', + xhr: () => { + const xhr = $.ajaxSettings.xhr(); + if (!xhr.upload) return; + xhr.upload.addEventListener( + 'progress', + e => { + let percent = (e.loaded / e.total) * 100; + $('.cm-progress-left').width(percent / 2 + '%'); + $('.cm-progress-right').width(percent / 2 + '%'); + }, + false + ); + return xhr; + }, + success: res => { + $('.cm-progress-left').width(0); + $('.cm-progress-right').width(0); + this._isPasting = false; + const str = `${super._getLineCh(cm) ? '\n' : ''}![${res[1].title}](${res[0]})\n`; + super._replaceSelection(cm, str); + cm.focus(); + }, + error: () => { + $('.cm-progress-left').width(0); + $('.cm-progress-right').width(0); + this._isPasting = false; + } + }); + } + }) + ] + }) + }); + $('.cm-mainer').prepend(cm.dom); + $('#text')[0].form && $('#text')[0].form.addEventListener('submit', () => $('#text').val(cm.state.doc.toString())); + this.cm = cm; + } catch (e) { + console.error('Init_Editor Error: ' + e); + } + } - /* 已测 √ */ - init_Preview() { - const move = (nowClientX, nowWidth, clientX) => { - let moveX = nowClientX - clientX; - let moveWidth = nowWidth + moveX; - if (moveWidth <= 0) moveWidth = 0; - if (moveWidth >= $('.cm-mainer').outerWidth() - 16) moveWidth = $('.cm-mainer').outerWidth() - 16; - $('.cm-preview').width(moveWidth); - }; - $('.cm-resize').on({ - mousedown: e => { - e.preventDefault(); - e.stopPropagation(); - const nowWidth = $('.cm-preview').outerWidth(); - const nowClientX = e.clientX; - document.onmousemove = _e => { - if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.clientX)); - else move(nowClientX, nowWidth, _e.clientX); - }; - document.onmouseup = () => { - document.onmousemove = null; - document.onmouseup = null; - }; - return false; - }, - touchstart: e => { - e.preventDefault(); - e.stopPropagation(); - const nowWidth = $('.cm-preview').outerWidth(); - const nowClientX = e.originalEvent.targetTouches[0].clientX; - document.ontouchmove = _e => { - if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.targetTouches[0].clientX)); - else move(nowClientX, nowWidth, _e.targetTouches[0].clientX); - }; - document.ontouchend = () => { - document.ontouchmove = null; - document.ontouchend = null; - }; - return false; - } - }); - } + /* 已测 √ */ + init_Preview() { + const move = (nowClientX, nowWidth, clientX) => { + let moveX = nowClientX - clientX; + let moveWidth = nowWidth + moveX; + if (moveWidth <= 0) moveWidth = 0; + if (moveWidth >= $('.cm-mainer').outerWidth() - 16) moveWidth = $('.cm-mainer').outerWidth() - 16; + $('.cm-preview').width(moveWidth); + }; + $('.cm-resize').on({ + mousedown: e => { + e.preventDefault(); + e.stopPropagation(); + const nowWidth = $('.cm-preview').outerWidth(); + const nowClientX = e.clientX; + document.onmousemove = _e => { + if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.clientX)); + else move(nowClientX, nowWidth, _e.clientX); + }; + document.onmouseup = () => { + document.onmousemove = null; + document.onmouseup = null; + }; + return false; + }, + touchstart: e => { + e.preventDefault(); + e.stopPropagation(); + const nowWidth = $('.cm-preview').outerWidth(); + const nowClientX = e.originalEvent.targetTouches[0].clientX; + document.ontouchmove = _e => { + if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.targetTouches[0].clientX)); + else move(nowClientX, nowWidth, _e.targetTouches[0].clientX); + }; + document.ontouchend = () => { + document.ontouchmove = null; + document.ontouchend = null; + }; + return false; + } + }); + } - /* 已测 √ */ - init_Tools() { - this.tools.forEach(item => { - if (item.type === 'title') { - super.handleTitle(this.cm, item); - } else { - const el = $(`
${item.innerHTML}
`); - el.on('click', e => { - e.preventDefault(); - switch (item.type) { - case 'fullScreen': - super.handleFullScreen(el); - break; - case 'publish': - super.handlePublish(); - break; - case 'undo': - super.handleUndo(this.cm); - break; - case 'redo': - super.handleRedo(this.cm); - break; - case 'time': - super.handleTime(this.cm); - break; - case 'bold': - super._insetAmboText(this.cm, '**'); - break; - case 'italic': - super._insetAmboText(this.cm, '*'); - break; - case 'delete': - super._insetAmboText(this.cm, '~~'); - break; - case 'code-inline': - super._insetAmboText(this.cm, '`'); - break; - case 'indent': - super.handleIndent(this.cm); - break; - case 'hr': - super.handleHr(this.cm); - break; - case 'clean': - super.handleClean(this.cm); - break; - case 'ordered-list': - super.handleOrdered(this.cm); - break; - case 'unordered-list': - super.handleUnordered(this.cm); - break; - case 'quote': - super.handleQuote(this.cm); - break; - case 'download': - super.handleDownload(this.cm); - break; - case 'link': - super.handleLink(this.cm); - break; - case 'image': - super.handleImage(this.cm); - break; - case 'table': - super.handleTable(this.cm); - break; - case 'code-block': - super.handleCodeBlock(this.cm); - break; - case 'about': - super.handleAbout(); - break; - } - }); - $('.cm-tools').append(el); - } - }); - } + /* 已测 √ */ + init_Tools() { + this.tools.forEach(item => { + if (item.type === 'title') { + super.handleTitle(this.cm, item); + } else { + const el = $(`
${item.innerHTML}
`); + el.on('click', e => { + e.preventDefault(); + switch (item.type) { + case 'fullScreen': + super.handleFullScreen(el); + break; + case 'publish': + super.handlePublish(); + break; + case 'undo': + super.handleUndo(this.cm); + break; + case 'redo': + super.handleRedo(this.cm); + break; + case 'time': + super.handleTime(this.cm); + break; + case 'bold': + super._insetAmboText(this.cm, '**'); + break; + case 'italic': + super._insetAmboText(this.cm, '*'); + break; + case 'delete': + super._insetAmboText(this.cm, '~~'); + break; + case 'code-inline': + super._insetAmboText(this.cm, '`'); + break; + case 'indent': + super.handleIndent(this.cm); + break; + case 'hr': + super.handleHr(this.cm); + break; + case 'clean': + super.handleClean(this.cm); + break; + case 'ordered-list': + super.handleOrdered(this.cm); + break; + case 'unordered-list': + super.handleUnordered(this.cm); + break; + case 'quote': + super.handleQuote(this.cm); + break; + case 'download': + super.handleDownload(this.cm); + break; + case 'link': + super.handleLink(this.cm); + break; + case 'image': + super.handleImage(this.cm); + break; + case 'table': + super.handleTable(this.cm); + break; + case 'code-block': + super.handleCodeBlock(this.cm); + break; + case 'about': + super.handleAbout(); + break; + } + }); + $('.cm-tools').append(el); + } + }); + } - /* 已测 √ */ - init_Insert() { - try { - Typecho.insertFileToEditor = (file, url, isImage) => { - const str = `${super._getLineCh(this.cm) ? '\n' : ''}${isImage ? '!' : ''}[${file}](${url})\n`; - super._replaceSelection(this.cm, str); - this.cm.focus(); - }; - } catch (e) { - console.error('Init_Insert Error: ' + e); - } - } + /* 已测 √ */ + init_Insert() { + try { + Typecho.insertFileToEditor = (file, url, isImage) => { + const str = `${super._getLineCh(this.cm) ? '\n' : ''}${isImage ? '!' : ''}[${file}](${url})\n`; + super._replaceSelection(this.cm, str); + this.cm.focus(); + }; + } catch (e) { + console.error('Init_Insert Error: ' + e); + } + } } document.addEventListener('DOMContentLoaded', () => new Joe());