This commit is contained in:
杜恒 2021-04-22 10:45:37 +08:00
parent 37c5a38930
commit 88030a0b16
8 changed files with 389 additions and 376 deletions

View File

@ -50,7 +50,7 @@ class Editor
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/themes/prism-tomorrow.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/themes/prism-tomorrow.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="<?php Helper::options()->themeUrl('typecho/write/css/joe.write.min.css?v=2021042208') ?>"> <link rel="stylesheet" href="<?php Helper::options()->themeUrl('typecho/write/css/joe.write.min.css?v=2021042210') ?>">
<script> <script>
window.JoeConfig = { window.JoeConfig = {
uploadAPI: '<?php Helper::security()->index('/action/upload'); ?>', uploadAPI: '<?php Helper::security()->index('/action/upload'); ?>',
@ -59,14 +59,15 @@ class Editor
characterAPI: '<?php Helper::options()->themeUrl('typecho/write/json/character.json') ?>', characterAPI: '<?php Helper::options()->themeUrl('typecho/write/json/character.json') ?>',
playerAPI: '<?php Helper::options()->JCustomPlayer ? Helper::options()->JCustomPlayer() : Helper::options()->themeUrl('library/player.php?url=') ?>', playerAPI: '<?php Helper::options()->JCustomPlayer ? Helper::options()->JCustomPlayer() : Helper::options()->themeUrl('library/player.php?url=') ?>',
autoSave: <?php Helper::options()->autoSave(); ?>, autoSave: <?php Helper::options()->autoSave(); ?>,
themeURL: '<?php Helper::options()->themeUrl(); ?>' themeURL: '<?php Helper::options()->themeUrl(); ?>',
canPreview: false
} }
</script> </script>
<script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/typecho-joe-next@6.2.4/plugin/prism/prism.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/typecho-joe-next@6.2.4/plugin/prism/prism.min.js"></script>
<script src="<?php Helper::options()->themeUrl('typecho/write/js/joe.parse.min.js?v=2021042208') ?>"></script> <script src="<?php Helper::options()->themeUrl('typecho/write/js/joe.parse.min.js?v=2021042210') ?>"></script>
<script src="<?php Helper::options()->themeUrl('typecho/write/js/joe.write.chunk.js?v=2021042208') ?>"></script> <script src="<?php Helper::options()->themeUrl('typecho/write/js/joe.write.chunk.js?v=2021042210') ?>"></script>
<script src="<?php Helper::options()->themeUrl('assets/js/joe.short.min.js?v=2021042208') ?>"></script> <script src="<?php Helper::options()->themeUrl('assets/js/joe.short.min.js?v=2021042210') ?>"></script>
<?php <?php
} }
} }

View File

@ -2,7 +2,7 @@
/* 获取主题当前版本号 */ /* 获取主题当前版本号 */
function _getVersion() function _getVersion()
{ {
return "6.5.4"; return "6.5.5";
}; };
/* 判断是否是手机 */ /* 判断是否是手机 */

View File

@ -1,6 +1,6 @@
{ {
"name": "typecho-joe-next", "name": "typecho-joe-next",
"version": "6.5.4", "version": "6.5.5",
"description": "A Theme Of Typecho", "description": "A Theme Of Typecho",
"main": "index.php", "main": "index.php",
"keywords": [ "keywords": [

View File

@ -1,38 +1,39 @@
const parser = new HyperDown(); const parser = new HyperDown();
const player = window.JoeConfig.playerAPI; const player = window.JoeConfig.playerAPI;
const div = document.createElement('div');
export default function createPreviewHtml(str) { export default function createPreviewHtml(str) {
str = str.replace(/ /g, '&emsp;'); if (!window.JoeConfig.canPreview) return $('.cm-preview-content').html('1. 预览已默认关闭<br>2. 点击上方预览按钮启用预览<br>3. 若编辑器卡顿可尝试关闭预览');
str = parser.makeHtml(str); str = str.replace(/ /g, '&emsp;');
str = str.replace(/{x}/g, '<input type="checkbox" class="joe_detail__article-checkbox" checked disabled></input>'); str = parser.makeHtml(str);
str = str.replace(/{ }/g, '<input type="checkbox" class="joe_detail__article-checkbox" disabled></input>');
str = str.replace(/\:\:\(\s*(呵呵|哈哈|吐舌|太开心|笑眼|花心|小乖|乖|捂嘴笑|滑稽|你懂的|不高兴|怒|汗|黑线|泪|真棒|喷|惊哭|阴险|鄙视|酷|啊|狂汗|what|疑问|酸爽|呀咩爹|委屈|惊讶|睡觉|笑尿|挖鼻|吐|犀利|小红脸|懒得理|勉强|爱心|心碎|玫瑰|礼物|彩虹|太阳|星星月亮|钱币|茶杯|蛋糕|大拇指|胜利|haha|OK|沙发|手纸|香蕉|便便|药丸|红领巾|蜡烛|音乐|灯泡|开心|钱|咦|呼|冷|生气|弱|吐血|狗头)\s*\)/g, function ($0, $1) {
$1 = encodeURI($1).replace(/%/g, '');
return `<img class="owo" src="${window.JoeConfig.themeURL}assets/owo/paopao/${$1}_2x.png" />`;
});
str = str.replace(/\:\@\(\s*(高兴|小怒|脸红|内伤|装大款|赞一个|害羞|汗|吐血倒地|深思|不高兴|无语|亲亲|口水|尴尬|中指|想一想|哭泣|便便|献花|皱眉|傻笑|狂汗|吐|喷水|看不见|鼓掌|阴暗|长草|献黄瓜|邪恶|期待|得意|吐舌|喷血|无所谓|观察|暗地观察|肿包|中枪|大囧|呲牙|抠鼻|不说话|咽气|欢呼|锁眉|蜡烛|坐等|击掌|惊喜|喜极而泣|抽烟|不出所料|愤怒|无奈|黑线|投降|看热闹|扇耳光|小眼睛|中刀)\s*\)/g, function ($0, $1) {
$1 = encodeURI($1).replace(/%/g, '');
return `<img class="owo" src="${window.JoeConfig.themeURL}assets/owo/aru/${$1}_2x.png" />`;
});
str = str.replace(/{mtitle([^}]*)\/}/g, '<joe-mtitle $1></joe-mtitle>');
str = str.replace(/{dplayer([^}]*)\/}/g, '<joe-dplayer player="' + player + '" $1></joe-dplayer>');
str = str.replace(/{bilibili([^}]*)\/}/g, '<joe-bilibili $1></joe-bilibili>');
str = str.replace(/{music-list([^}]*)\/}/g, '<joe-mlist $1></joe-mlist>');
str = str.replace(/{music([^}]*)\/}/g, '<joe-music $1></joe-music>');
str = str.replace(/{mp3([^}]*)\/}/g, '<joe-mp3 $1></joe-mp3>');
str = str.replace(/{abtn([^}]*)\/}/g, '<joe-abtn $1></joe-abtn>');
str = str.replace(/{anote([^}]*)\/}/g, '<joe-anote $1></joe-anote>');
str = str.replace(/{dotted([^}]*)\/}/g, '<joe-dotted $1></joe-dotted>');
str = str.replace(/{message([^}]*)\/}/g, '<joe-message $1></joe-message>');
str = str.replace(/{progress([^}]*)\/}/g, '<joe-progress $1></joe-progress>');
str = str.replace(/{hide[^}]*}([\s\S]*?){\/hide}/g, '<joe-hide></joe-hide>');
str = str.replace(/{card-default([^}]*)}([\s\S]*?){\/card-default}/g, '<section style="margin-bottom: 15px"><joe-card-default $1><span class="_temp" style="display: none">$2</span></joe-card-default></section>');
str = str.replace(/{callout([^}]*)}([\s\S]*?){\/callout}/g, '<section style="margin-bottom: 15px"><joe-callout $1><span class="_temp" style="display: none">$2</span></joe-callout></section>');
$('.cm-preview-content').html(str); str = str.replace(/{x}/g, '<input type="checkbox" class="joe_detail__article-checkbox" checked disabled></input>');
$('.cm-preview-content p:empty').remove(); str = str.replace(/{ }/g, '<input type="checkbox" class="joe_detail__article-checkbox" disabled></input>');
$('.cm-preview-content pre code').each((i, el) => Prism.highlightElement(el)); str = str.replace(/\:\:\(\s*(呵呵|哈哈|吐舌|太开心|笑眼|花心|小乖|乖|捂嘴笑|滑稽|你懂的|不高兴|怒|汗|黑线|泪|真棒|喷|惊哭|阴险|鄙视|酷|啊|狂汗|what|疑问|酸爽|呀咩爹|委屈|惊讶|睡觉|笑尿|挖鼻|吐|犀利|小红脸|懒得理|勉强|爱心|心碎|玫瑰|礼物|彩虹|太阳|星星月亮|钱币|茶杯|蛋糕|大拇指|胜利|haha|OK|沙发|手纸|香蕉|便便|药丸|红领巾|蜡烛|音乐|灯泡|开心|钱|咦|呼|冷|生气|弱|吐血|狗头)\s*\)/g, function ($0, $1) {
$1 = encodeURI($1).replace(/%/g, '');
return `<img class="owo" src="${window.JoeConfig.themeURL}assets/owo/paopao/${$1}_2x.png" />`;
});
str = str.replace(/\:\@\(\s*(高兴|小怒|脸红|内伤|装大款|赞一个|害羞|汗|吐血倒地|深思|不高兴|无语|亲亲|口水|尴尬|中指|想一想|哭泣|便便|献花|皱眉|傻笑|狂汗|吐|喷水|看不见|鼓掌|阴暗|长草|献黄瓜|邪恶|期待|得意|吐舌|喷血|无所谓|观察|暗地观察|肿包|中枪|大囧|呲牙|抠鼻|不说话|咽气|欢呼|锁眉|蜡烛|坐等|击掌|惊喜|喜极而泣|抽烟|不出所料|愤怒|无奈|黑线|投降|看热闹|扇耳光|小眼睛|中刀)\s*\)/g, function ($0, $1) {
$1 = encodeURI($1).replace(/%/g, '');
return `<img class="owo" src="${window.JoeConfig.themeURL}assets/owo/aru/${$1}_2x.png" />`;
});
str = str.replace(/{mtitle([^}]*)\/}/g, '<joe-mtitle $1></joe-mtitle>');
str = str.replace(/{dplayer([^}]*)\/}/g, '<joe-dplayer player="' + player + '" $1></joe-dplayer>');
str = str.replace(/{bilibili([^}]*)\/}/g, '<joe-bilibili $1></joe-bilibili>');
str = str.replace(/{music-list([^}]*)\/}/g, '<joe-mlist $1></joe-mlist>');
str = str.replace(/{music([^}]*)\/}/g, '<joe-music $1></joe-music>');
str = str.replace(/{mp3([^}]*)\/}/g, '<joe-mp3 $1></joe-mp3>');
str = str.replace(/{abtn([^}]*)\/}/g, '<joe-abtn $1></joe-abtn>');
str = str.replace(/{anote([^}]*)\/}/g, '<joe-anote $1></joe-anote>');
str = str.replace(/{dotted([^}]*)\/}/g, '<joe-dotted $1></joe-dotted>');
str = str.replace(/{message([^}]*)\/}/g, '<joe-message $1></joe-message>');
str = str.replace(/{progress([^}]*)\/}/g, '<joe-progress $1></joe-progress>');
str = str.replace(/{hide[^}]*}([\s\S]*?){\/hide}/g, '<joe-hide></joe-hide>');
str = str.replace(/{card-default([^}]*)}([\s\S]*?){\/card-default}/g, '<section style="margin-bottom: 15px"><joe-card-default $1><span class="_temp" style="display: none">$2</span></joe-card-default></section>');
str = str.replace(/{callout([^}]*)}([\s\S]*?){\/callout}/g, '<section style="margin-bottom: 15px"><joe-callout $1><span class="_temp" style="display: none">$2</span></joe-callout></section>');
$('.cm-preview-content').html(str);
$('.cm-preview-content p:empty').remove();
$('.cm-preview-content pre code').each((i, el) => Prism.highlightElement(el));
} }

View File

@ -201,6 +201,11 @@ export default [
title: '全屏/取消全屏', title: '全屏/取消全屏',
innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20"><path d="M181.2 803.4V637H98v208c0 45.9 37.2 83.2 83.2 83.2h208V845H222.8c-23 0-41.6-18.6-41.6-41.6zM844.8 98.6h-208v83.2h166.4c23 0 41.6 18.6 41.6 41.6v166.4H928v-208c0-46-37.3-83.2-83.2-83.2zm-746.6 83v208h83.2V223.2c0-23 18.6-41.6 41.6-41.6h166.4V98.4h-208c-46 0-83.2 37.3-83.2 83.2zm746.4 455.6v166.4c0 23-18.6 41.6-41.6 41.6H636.6v83.2h208c45.9 0 83.2-37.2 83.2-83.2v-208h-83.2z"/></svg>' innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20"><path d="M181.2 803.4V637H98v208c0 45.9 37.2 83.2 83.2 83.2h208V845H222.8c-23 0-41.6-18.6-41.6-41.6zM844.8 98.6h-208v83.2h166.4c23 0 41.6 18.6 41.6 41.6v166.4H928v-208c0-46-37.3-83.2-83.2-83.2zm-746.6 83v208h83.2V223.2c0-23 18.6-41.6 41.6-41.6h166.4V98.4h-208c-46 0-83.2 37.3-83.2 83.2zm746.4 455.6v166.4c0 23-18.6 41.6-41.6 41.6H636.6v83.2h208c45.9 0 83.2-37.2 83.2-83.2v-208h-83.2z"/></svg>'
}, },
{
type: 'preview',
title: '预览/取消预览',
innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20"><path d="M832 128c70.692 0 128 57.308 128 128v512c0 70.692-57.308 128-128 128H192c-70.692 0-128-57.308-128-128V256c0-70.692 57.308-128 128-128h640zm0 72H192c-30.619 0-55.498 24.573-56 55.074V768c0 30.619 24.573 55.498 55.074 55.992L192 824h640c30.619 0 55.498-24.573 56-55.074V256c0-30.619-24.573-55.498-55.074-55.992L832 200zM693.031 450.127l.425.417 128 128c13.918 13.918 14.057 36.398.417 50.487l-.417.425-128 128c-14.059 14.059-36.853 14.059-50.912 0-13.918-13.918-14.057-36.398-.417-50.487l.417-.425L745.09 604 642.544 501.456c-13.918-13.918-14.057-36.398-.417-50.487l.417-.425c13.918-13.918 36.398-14.057 50.487-.417zM284 312c19.882 0 36 16.118 36 36s-16.118 36-36 36h-56c-19.882 0-36-16.118-36-36s16.118-36 36-36h56zm512 0c19.882 0 36 16.118 36 36s-16.118 36-36 36H420c-19.882 0-36-16.118-36-36s16.118-36 36-36h376z"/></svg>'
},
{ {
type: 'draft', type: 'draft',
title: '保存草稿', title: '保存草稿',

File diff suppressed because one or more lines are too long

View File

@ -10,27 +10,27 @@ import JoeAction from './_actions';
import createPreviewHtml from './_create'; import createPreviewHtml from './_create';
class Joe extends JoeAction { class Joe extends JoeAction {
constructor() { constructor() {
super(); super();
this.plugins = [history(), classHighlightStyle, bracketMatching(), closeBrackets()]; this.plugins = [history(), classHighlightStyle, bracketMatching(), closeBrackets()];
this._isPasting = false; this._isPasting = false;
this.init_ViewPort(); this.init_ViewPort();
this.init_Editor(); this.init_Editor();
this.init_Preview(); this.init_Preview();
this.init_Tools(); this.init_Tools();
this.init_Insert(); this.init_Insert();
this.init_AutoSave(); this.init_AutoSave();
} }
/* 已测 √ */ /* 已测 √ */
init_ViewPort() { init_ViewPort() {
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'); 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('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover">'); else $('head').append('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover">');
} }
/* 已测 √ */ /* 已测 √ */
init_Editor() { init_Editor() {
$('#text').before(` $('#text').before(`
<div class="cm-container"> <div class="cm-container">
<div class="cm-tools"></div> <div class="cm-tools"></div>
<div class="cm-mainer"> <div class="cm-mainer">
@ -42,322 +42,328 @@ class Joe extends JoeAction {
<div class="cm-progress-right"></div> <div class="cm-progress-right"></div>
</div> </div>
`); `);
createPreviewHtml($('#text').val()); createPreviewHtml($('#text').val());
let _temp = null; let _temp = null;
const cm = new EditorView({ const cm = new EditorView({
state: EditorState.create({ state: EditorState.create({
doc: $('#text').val(), doc: $('#text').val(),
extensions: [ extensions: [
...this.plugins, ...this.plugins,
keymap.of([defaultTabBinding, ...defaultKeymap, ...historyKeymap, ...closeBracketsKeymap]), keymap.of([defaultTabBinding, ...defaultKeymap, ...historyKeymap, ...closeBracketsKeymap]),
EditorView.updateListener.of(update => { EditorView.updateListener.of(update => {
if (!update.docChanged) return; if (!update.docChanged) return;
if (_temp !== update.state.doc.toString()) { if (_temp !== update.state.doc.toString()) {
_temp = update.state.doc.toString(); _temp = update.state.doc.toString();
if (window.requestAnimationFrame) window.requestAnimationFrame(() => createPreviewHtml(update.state.doc.toString())); if (window.requestAnimationFrame) window.requestAnimationFrame(() => createPreviewHtml(update.state.doc.toString()));
else createPreviewHtml(update.state.doc.toString()); else createPreviewHtml(update.state.doc.toString());
} }
}), }),
EditorView.domEventHandlers({ EditorView.domEventHandlers({
paste: e => { paste: e => {
const clipboardData = e.clipboardData; const clipboardData = e.clipboardData;
if (!clipboardData || !clipboardData.items) return; if (!clipboardData || !clipboardData.items) return;
const items = clipboardData.items; const items = clipboardData.items;
if (!items.length) return; if (!items.length) return;
let blob = null; let blob = null;
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) { if (items[i].type.indexOf('image') !== -1) {
e.preventDefault(); e.preventDefault();
blob = items[i].getAsFile(); blob = items[i].getAsFile();
break; break;
} }
} }
if (!blob) return; if (!blob) return;
let api = window.JoeConfig.uploadAPI; let api = window.JoeConfig.uploadAPI;
if (!api) return; if (!api) return;
const cid = $('input[name="cid"]').val(); const cid = $('input[name="cid"]').val();
cid && (api = api + '&cid=' + cid); cid && (api = api + '&cid=' + cid);
if (this._isPasting) return; if (this._isPasting) return;
this._isPasting = true; this._isPasting = true;
const fileName = Date.now().toString(36) + '.png'; const fileName = Date.now().toString(36) + '.png';
let formData = new FormData(); let formData = new FormData();
formData.append('name', fileName); formData.append('name', fileName);
formData.append('file', blob, fileName); formData.append('file', blob, fileName);
$.ajax({ $.ajax({
url: api, url: api,
method: 'post', method: 'post',
data: formData, data: formData,
contentType: false, contentType: false,
processData: false, processData: false,
dataType: 'json', dataType: 'json',
xhr: () => { xhr: () => {
const xhr = $.ajaxSettings.xhr(); const xhr = $.ajaxSettings.xhr();
if (!xhr.upload) return; if (!xhr.upload) return;
xhr.upload.addEventListener( xhr.upload.addEventListener(
'progress', 'progress',
e => { e => {
let percent = (e.loaded / e.total) * 100; let percent = (e.loaded / e.total) * 100;
$('.cm-progress-left').width(percent / 2 + '%'); $('.cm-progress-left').width(percent / 2 + '%');
$('.cm-progress-right').width(percent / 2 + '%'); $('.cm-progress-right').width(percent / 2 + '%');
}, },
false false
); );
return xhr; return xhr;
}, },
success: res => { success: res => {
$('.cm-progress-left').width(0); $('.cm-progress-left').width(0);
$('.cm-progress-right').width(0); $('.cm-progress-right').width(0);
this._isPasting = false; this._isPasting = false;
const str = `${super._getLineCh(cm) ? '\n' : ''}![${res[1].title}](${res[0]})\n`; const str = `${super._getLineCh(cm) ? '\n' : ''}![${res[1].title}](${res[0]})\n`;
super._replaceSelection(cm, str); super._replaceSelection(cm, str);
cm.focus(); cm.focus();
}, },
error: () => { error: () => {
$('.cm-progress-left').width(0); $('.cm-progress-left').width(0);
$('.cm-progress-right').width(0); $('.cm-progress-right').width(0);
this._isPasting = false; this._isPasting = false;
} }
}); });
} }
}) })
], ],
tabSize: 4 tabSize: 4
}) })
}); });
$('.cm-mainer').prepend(cm.dom); $('.cm-mainer').prepend(cm.dom);
$('#text')[0].form && $('#text')[0].form.addEventListener('submit', () => $('#text').val(cm.state.doc.toString())); $('#text')[0].form && $('#text')[0].form.addEventListener('submit', () => $('#text').val(cm.state.doc.toString()));
this.cm = cm; this.cm = cm;
} }
/* 已测 √ */ /* 已测 √ */
init_Preview() { init_Preview() {
const move = (nowClientX, nowWidth, clientX) => { const move = (nowClientX, nowWidth, clientX) => {
let moveX = nowClientX - clientX; let moveX = nowClientX - clientX;
let moveWidth = nowWidth + moveX; let moveWidth = nowWidth + moveX;
if (moveWidth <= 0) moveWidth = 0; if (moveWidth <= 0) moveWidth = 0;
if (moveWidth >= $('.cm-mainer').outerWidth() - 16) moveWidth = $('.cm-mainer').outerWidth() - 16; if (moveWidth >= $('.cm-mainer').outerWidth() - 16) moveWidth = $('.cm-mainer').outerWidth() - 16;
$('.cm-preview').width(moveWidth); $('.cm-preview').width(moveWidth);
}; };
$('.cm-resize').on({ $('.cm-resize').on({
mousedown: e => { mousedown: e => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const nowWidth = $('.cm-preview').outerWidth(); const nowWidth = $('.cm-preview').outerWidth();
const nowClientX = e.clientX; const nowClientX = e.clientX;
$('.cm-preview').addClass('move'); $('.cm-preview').addClass('move');
document.onmousemove = _e => { document.onmousemove = _e => {
if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.clientX)); if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.clientX));
else move(nowClientX, nowWidth, _e.clientX); else move(nowClientX, nowWidth, _e.clientX);
}; };
document.onmouseup = () => { document.onmouseup = () => {
document.onmousemove = null; document.onmousemove = null;
document.onmouseup = null; document.onmouseup = null;
$('.cm-preview').removeClass('move'); $('.cm-preview').removeClass('move');
}; };
return false; return false;
}, },
touchstart: e => { touchstart: e => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const nowWidth = $('.cm-preview').outerWidth(); const nowWidth = $('.cm-preview').outerWidth();
const nowClientX = e.originalEvent.targetTouches[0].clientX; const nowClientX = e.originalEvent.targetTouches[0].clientX;
$('.cm-preview').addClass('move'); $('.cm-preview').addClass('move');
document.ontouchmove = _e => { document.ontouchmove = _e => {
if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.targetTouches[0].clientX)); if (window.requestAnimationFrame) requestAnimationFrame(() => move(nowClientX, nowWidth, _e.targetTouches[0].clientX));
else move(nowClientX, nowWidth, _e.targetTouches[0].clientX); else move(nowClientX, nowWidth, _e.targetTouches[0].clientX);
}; };
document.ontouchend = () => { document.ontouchend = () => {
document.ontouchmove = null; document.ontouchmove = null;
document.ontouchend = null; document.ontouchend = null;
$('.cm-preview').removeClass('move'); $('.cm-preview').removeClass('move');
}; };
return false; return false;
} }
}); });
} }
/* 已测 √ */ /* 已测 √ */
init_Tools() { init_Tools() {
tools.forEach(item => { tools.forEach(item => {
if (item.type === 'title') { if (item.type === 'title') {
super.handleTitle(this.cm, item); super.handleTitle(this.cm, item);
} else { } else {
const el = $(`<div class="cm-tools-item" title="${item.title}">${item.innerHTML}</div>`); const el = $(`<div class="cm-tools-item" title="${item.title}">${item.innerHTML}</div>`);
el.on('click', e => { el.on('click', e => {
e.preventDefault(); e.preventDefault();
switch (item.type) { switch (item.type) {
case 'fullScreen': case 'fullScreen':
super.handleFullScreen(el); super.handleFullScreen(el);
break; break;
case 'publish': case 'publish':
super.handlePublish(); super.handlePublish();
break; break;
case 'undo': case 'undo':
super.handleUndo(this.cm); super.handleUndo(this.cm);
break; break;
case 'redo': case 'redo':
super.handleRedo(this.cm); super.handleRedo(this.cm);
break; break;
case 'time': case 'time':
super.handleTime(this.cm); super.handleTime(this.cm);
break; break;
case 'bold': case 'bold':
super._insetAmboText(this.cm, '**'); super._insetAmboText(this.cm, '**');
break; break;
case 'italic': case 'italic':
super._insetAmboText(this.cm, '*'); super._insetAmboText(this.cm, '*');
break; break;
case 'delete': case 'delete':
super._insetAmboText(this.cm, '~~'); super._insetAmboText(this.cm, '~~');
break; break;
case 'code-inline': case 'code-inline':
super._insetAmboText(this.cm, '`'); super._insetAmboText(this.cm, '`');
break; break;
case 'indent': case 'indent':
super.handleIndent(this.cm); super.handleIndent(this.cm);
break; break;
case 'hr': case 'hr':
super.handleHr(this.cm); super.handleHr(this.cm);
break; break;
case 'clean': case 'clean':
super.handleClean(this.cm); super.handleClean(this.cm);
break; break;
case 'ordered-list': case 'ordered-list':
super.handleOrdered(this.cm); super.handleOrdered(this.cm);
break; break;
case 'unordered-list': case 'unordered-list':
super.handleUnordered(this.cm); super.handleUnordered(this.cm);
break; break;
case 'quote': case 'quote':
super.handleQuote(this.cm); super.handleQuote(this.cm);
break; break;
case 'download': case 'download':
super.handleDownload(this.cm); super.handleDownload(this.cm);
break; break;
case 'link': case 'link':
super.handleLink(this.cm); super.handleLink(this.cm);
break; break;
case 'image': case 'image':
super.handleImage(this.cm); super.handleImage(this.cm);
break; break;
case 'table': case 'table':
super.handleTable(this.cm); super.handleTable(this.cm);
break; break;
case 'code-block': case 'code-block':
super.handleCodeBlock(this.cm); super.handleCodeBlock(this.cm);
break; break;
case 'about': case 'about':
super.handleAbout(); super.handleAbout();
break; break;
case 'character': case 'character':
super._createTableLists(this.cm, JoeConfig.characterAPI, '星星符号', '字符大全'); super._createTableLists(this.cm, JoeConfig.characterAPI, '星星符号', '字符大全');
break; break;
case 'emoji': case 'emoji':
super._createTableLists(this.cm, JoeConfig.emojiAPI, '表情', '符号表情(需数据库支持)'); super._createTableLists(this.cm, JoeConfig.emojiAPI, '表情', '符号表情(需数据库支持)');
break; break;
case 'task-no': case 'task-no':
super.handleTask(this.cm, false); super.handleTask(this.cm, false);
break; break;
case 'task-yes': case 'task-yes':
super.handleTask(this.cm, true); super.handleTask(this.cm, true);
break; break;
case 'netease-list': case 'netease-list':
super.handleNetease(this.cm, true); super.handleNetease(this.cm, true);
break; break;
case 'netease-single': case 'netease-single':
super.handleNetease(this.cm, false); super.handleNetease(this.cm, false);
break; break;
case 'bilibili': case 'bilibili':
super.handleBilibili(this.cm); super.handleBilibili(this.cm);
break; break;
case 'dplayer': case 'dplayer':
super.handleDplayer(this.cm); super.handleDplayer(this.cm);
break; break;
case 'draft': case 'draft':
super.handleDraft(); super.handleDraft();
break; break;
case 'expression': case 'expression':
super.handleExpression(this.cm); super.handleExpression(this.cm);
break; break;
case 'mtitle': case 'mtitle':
super.handleMtitle(this.cm); super.handleMtitle(this.cm);
break; break;
case 'html': case 'html':
super.handleHtml(this.cm); super.handleHtml(this.cm);
break; break;
case 'abtn': case 'abtn':
super.handleAbtn(this.cm); super.handleAbtn(this.cm);
break; break;
case 'anote': case 'anote':
super.handleAnote(this.cm); super.handleAnote(this.cm);
break; break;
case 'dotted': case 'dotted':
super.handleDotted(this.cm); super.handleDotted(this.cm);
break; break;
case 'hide': case 'hide':
super.handleHide(this.cm); super.handleHide(this.cm);
break; break;
case 'card-default': case 'card-default':
super.handleCardDefault(this.cm); super.handleCardDefault(this.cm);
break; break;
case 'message': case 'message':
super.handleMessage(this.cm); super.handleMessage(this.cm);
break; break;
case 'progress': case 'progress':
super.handleProgress(this.cm); super.handleProgress(this.cm);
break; break;
case 'callout': case 'callout':
super.handleCallout(this.cm); super.handleCallout(this.cm);
break; break;
case 'mp3': case 'mp3':
super.handleMp3(this.cm); super.handleMp3(this.cm);
break; break;
} case 'preview':
}); el.toggleClass('active');
$('.cm-tools').append(el); if (el.hasClass('active')) window.JoeConfig.canPreview = true;
} else window.JoeConfig.canPreview = false;
}); createPreviewHtml(this.cm.state.doc.toString());
} break;
}
});
$('.cm-tools').append(el);
}
});
}
/* 已测 √ */ /* 已测 √ */
init_Insert() { init_Insert() {
Typecho.insertFileToEditor = (file, url, isImage) => { Typecho.insertFileToEditor = (file, url, isImage) => {
const str = `${super._getLineCh(this.cm) ? '\n' : ''}${isImage ? '!' : ''}[${file}](${url})\n`; const str = `${super._getLineCh(this.cm) ? '\n' : ''}${isImage ? '!' : ''}[${file}](${url})\n`;
super._replaceSelection(this.cm, str); super._replaceSelection(this.cm, str);
this.cm.focus(); this.cm.focus();
}; };
} }
/* 已测 √ */ /* 已测 √ */
init_AutoSave() { init_AutoSave() {
if (window.JoeConfig.autoSave !== 1) return; if (window.JoeConfig.autoSave !== 1) return;
const formEl = $('#text')[0].form; const formEl = $('#text')[0].form;
let cid = $('input[name="cid"]').val(); let cid = $('input[name="cid"]').val();
let temp = null; let temp = null;
const saveFn = () => { const saveFn = () => {
$('input[name="cid"]').val(cid); $('input[name="cid"]').val(cid);
$('#text').val(this.cm.state.doc.toString()); $('#text').val(this.cm.state.doc.toString());
let data = $(formEl).serialize(); let data = $(formEl).serialize();
if (data !== temp) { if (data !== temp) {
$('.cm-autosave').addClass('active'); $('.cm-autosave').addClass('active');
$.ajax({ $.ajax({
url: formEl.action, url: formEl.action,
type: 'POST', type: 'POST',
data: data + '&do=save', data: data + '&do=save',
dataType: 'json', dataType: 'json',
success: res => { success: res => {
cid = res.cid; cid = res.cid;
temp = data; temp = data;
let timer = setTimeout(() => { let timer = setTimeout(() => {
$('.cm-autosave').removeClass('active'); $('.cm-autosave').removeClass('active');
clearTimeout(timer); clearTimeout(timer);
}, 1000); }, 1000);
} }
}); });
} }
}; };
setInterval(saveFn, 5000); setInterval(saveFn, 5000);
} }
} }
document.addEventListener('DOMContentLoaded', () => new Joe()); document.addEventListener('DOMContentLoaded', () => new Joe());

View File

@ -1,10 +1,10 @@
import { nodeResolve } from '@rollup/plugin-node-resolve'; import { nodeResolve } from '@rollup/plugin-node-resolve';
import { uglify } from 'rollup-plugin-uglify'; import { uglify } from 'rollup-plugin-uglify';
export default { export default {
input: './js/joe.write.js', input: './js/joe.write.js',
output: { output: {
file: './js/joe.write.chunk.js', file: './js/joe.write.chunk.js',
format: 'iife' format: 'iife'
}, },
plugins: [nodeResolve(), uglify()] plugins: [nodeResolve(), uglify()]
}; };