更新
This commit is contained in:
parent
e97641ca99
commit
fc470d46ea
2
typecho/write/css/joe.write.min.css
vendored
2
typecho/write/css/joe.write.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
import { undo, redo } from '@codemirror/history';
|
import { undo, redo } from '@codemirror/history';
|
||||||
export default class JoeAction {
|
export default class JoeAction {
|
||||||
constructor() {
|
constructor() {
|
||||||
$('body').append(`
|
$('body').append(`
|
||||||
<div class="cm-modal">
|
<div class="cm-modal">
|
||||||
<div class="cm-modal__wrapper">
|
<div class="cm-modal__wrapper">
|
||||||
<div class="cm-modal__wrapper-header">
|
<div class="cm-modal__wrapper-header">
|
||||||
@ -16,186 +16,186 @@ export default class JoeAction {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
$('.cm-modal__wrapper-footer--cancle, .cm-modal__wrapper-header--close').on('click', () => $('.cm-modal').removeClass('active'));
|
$('.cm-modal__wrapper-footer--cancle, .cm-modal__wrapper-header--close').on('click', () => $('.cm-modal').removeClass('active'));
|
||||||
$('.cm-modal__wrapper-footer--confirm').on('click', () => {
|
$('.cm-modal__wrapper-footer--confirm').on('click', () => {
|
||||||
this.options.confirm();
|
this.options.confirm();
|
||||||
$('.cm-modal').removeClass('active');
|
$('.cm-modal').removeClass('active');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_openModal(options = {}) {
|
_openModal(options = {}) {
|
||||||
const _options = {
|
const _options = {
|
||||||
title: '提示',
|
title: '提示',
|
||||||
innerHtml: '内容',
|
innerHtml: '内容',
|
||||||
hasFooter: true,
|
hasFooter: true,
|
||||||
confirm: () => {},
|
confirm: () => {},
|
||||||
handler: () => {}
|
handler: () => {}
|
||||||
};
|
};
|
||||||
this.options = Object.assign(_options, options);
|
this.options = Object.assign(_options, options);
|
||||||
$('.cm-modal__wrapper-header--text').html(this.options.title);
|
$('.cm-modal__wrapper-header--text').html(this.options.title);
|
||||||
$('.cm-modal__wrapper-bodyer').html(this.options.innerHtml);
|
$('.cm-modal__wrapper-bodyer').html(this.options.innerHtml);
|
||||||
this.options.hasFooter ? $('.cm-modal__wrapper-footer').show() : $('.cm-modal__wrapper-footer').hide();
|
this.options.hasFooter ? $('.cm-modal__wrapper-footer').show() : $('.cm-modal__wrapper-footer').hide();
|
||||||
$('.cm-modal').addClass('active');
|
$('.cm-modal').addClass('active');
|
||||||
this.options.handler();
|
this.options.handler();
|
||||||
}
|
}
|
||||||
_getLineCh(cm) {
|
_getLineCh(cm) {
|
||||||
const head = cm.state.selection.main.head;
|
const head = cm.state.selection.main.head;
|
||||||
const line = cm.state.doc.lineAt(head);
|
const line = cm.state.doc.lineAt(head);
|
||||||
return head - line.from;
|
return head - line.from;
|
||||||
}
|
}
|
||||||
_replaceSelection(cm, str) {
|
_replaceSelection(cm, str) {
|
||||||
cm.dispatch(cm.state.replaceSelection(str));
|
cm.dispatch(cm.state.replaceSelection(str));
|
||||||
}
|
}
|
||||||
_setCursor(cm, pos) {
|
_setCursor(cm, pos) {
|
||||||
cm.dispatch({ selection: { anchor: pos } });
|
cm.dispatch({ selection: { anchor: pos } });
|
||||||
}
|
}
|
||||||
_getSelection(cm) {
|
_getSelection(cm) {
|
||||||
return cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to);
|
return cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to);
|
||||||
}
|
}
|
||||||
_insetAmboText(cm, str) {
|
_insetAmboText(cm, str) {
|
||||||
const cursor = cm.state.selection.main.head;
|
const cursor = cm.state.selection.main.head;
|
||||||
const selection = this._getSelection(cm);
|
const selection = this._getSelection(cm);
|
||||||
this._replaceSelection(cm, ` ${str + selection + str} `);
|
this._replaceSelection(cm, ` ${str + selection + str} `);
|
||||||
if (selection === '') this._setCursor(cm, cursor + str.length + 1);
|
if (selection === '') this._setCursor(cm, cursor + str.length + 1);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
_createTableLists(cm, url, activeTab = '', modalTitle) {
|
_createTableLists(cm, url, activeTab = '', modalTitle) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url,
|
url,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: res => {
|
success: res => {
|
||||||
let tabbarStr = '';
|
let tabbarStr = '';
|
||||||
let listsStr = '';
|
let listsStr = '';
|
||||||
for (let key in res) {
|
for (let key in res) {
|
||||||
const arr = res[key].split(' ');
|
const arr = res[key].split(' ');
|
||||||
tabbarStr += `<div class="tabbar-item ${key === activeTab ? 'active' : ''}" data-show="${key}">${key}</div>`;
|
tabbarStr += `<div class="tabbar-item ${key === activeTab ? 'active' : ''}" data-show="${key}">${key}</div>`;
|
||||||
listsStr += `<div class="lists ${key === activeTab ? 'active' : ''}" data-show="${key}">${arr.map(item => `<div class="lists-item" data-text="${item}">${item}</div>`).join(' ')}</div>`;
|
listsStr += `<div class="lists ${key === activeTab ? 'active' : ''}" data-show="${key}">${arr.map(item => `<div class="lists-item" data-text="${item}">${item}</div>`).join(' ')}</div>`;
|
||||||
}
|
}
|
||||||
this._openModal({
|
this._openModal({
|
||||||
title: modalTitle,
|
title: modalTitle,
|
||||||
hasFooter: false,
|
hasFooter: false,
|
||||||
innerHtml: `<div class="tabbar">${tabbarStr}</div>${listsStr}`,
|
innerHtml: `<div class="tabbar">${tabbarStr}</div>${listsStr}`,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
$('.cm-modal__wrapper-bodyer .tabbar-item').on('click', function () {
|
$('.cm-modal__wrapper-bodyer .tabbar-item').on('click', function () {
|
||||||
const activeTab = $(this);
|
const activeTab = $(this);
|
||||||
const show = activeTab.attr('data-show');
|
const show = activeTab.attr('data-show');
|
||||||
const tabbar = $('.cm-modal__wrapper-bodyer .tabbar');
|
const tabbar = $('.cm-modal__wrapper-bodyer .tabbar');
|
||||||
activeTab.addClass('active').siblings().removeClass('active');
|
activeTab.addClass('active').siblings().removeClass('active');
|
||||||
tabbar.stop().animate({
|
tabbar.stop().animate({
|
||||||
scrollLeft: activeTab[0].offsetLeft - tabbar[0].offsetWidth / 2 + activeTab[0].offsetWidth / 2 - 15
|
scrollLeft: activeTab[0].offsetLeft - tabbar[0].offsetWidth / 2 + activeTab[0].offsetWidth / 2 - 15
|
||||||
});
|
});
|
||||||
$('.cm-modal__wrapper-bodyer .lists').removeClass('active');
|
$('.cm-modal__wrapper-bodyer .lists').removeClass('active');
|
||||||
$(".cm-modal__wrapper-bodyer .lists[data-show='" + show + "']").addClass('active');
|
$(".cm-modal__wrapper-bodyer .lists[data-show='" + show + "']").addClass('active');
|
||||||
});
|
});
|
||||||
const _this = this;
|
const _this = this;
|
||||||
$('.cm-modal__wrapper-bodyer .lists-item').on('click', function () {
|
$('.cm-modal__wrapper-bodyer .lists-item').on('click', function () {
|
||||||
const text = $(this).attr('data-text');
|
const text = $(this).attr('data-text');
|
||||||
_this._replaceSelection(cm, ` ${text} `);
|
_this._replaceSelection(cm, ` ${text} `);
|
||||||
$('.cm-modal').removeClass('active');
|
$('.cm-modal').removeClass('active');
|
||||||
cm.focus();
|
cm.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleFullScreen(el) {
|
handleFullScreen(el) {
|
||||||
el.toggleClass('active');
|
el.toggleClass('active');
|
||||||
$('body').toggleClass('fullscreen');
|
$('body').toggleClass('fullscreen');
|
||||||
$('.cm-container').toggleClass('fullscreen');
|
$('.cm-container').toggleClass('fullscreen');
|
||||||
$('.cm-preview').width(0);
|
$('.cm-preview').width(0);
|
||||||
}
|
}
|
||||||
handlePublish() {
|
handlePublish() {
|
||||||
$('#btn-submit').click();
|
$('#btn-submit').click();
|
||||||
}
|
}
|
||||||
handleUndo(cm) {
|
handleUndo(cm) {
|
||||||
undo(cm);
|
undo(cm);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleRedo(cm) {
|
handleRedo(cm) {
|
||||||
redo(cm);
|
redo(cm);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleIndent(cm) {
|
handleIndent(cm) {
|
||||||
this._replaceSelection(cm, ' ');
|
this._replaceSelection(cm, ' ');
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleTime(cm) {
|
handleTime(cm) {
|
||||||
const time = new Date();
|
const time = new Date();
|
||||||
const _Year = time.getFullYear();
|
const _Year = time.getFullYear();
|
||||||
const _Month = String(time.getMonth() + 1).padStart(2, 0);
|
const _Month = String(time.getMonth() + 1).padStart(2, 0);
|
||||||
const _Date = String(time.getDate()).padStart(2, 0);
|
const _Date = String(time.getDate()).padStart(2, 0);
|
||||||
const _Hours = String(time.getHours()).padStart(2, 0);
|
const _Hours = String(time.getHours()).padStart(2, 0);
|
||||||
const _Minutes = String(time.getMinutes()).padStart(2, 0);
|
const _Minutes = String(time.getMinutes()).padStart(2, 0);
|
||||||
const _Seconds = String(time.getSeconds()).padStart(2, 0);
|
const _Seconds = String(time.getSeconds()).padStart(2, 0);
|
||||||
const _Day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][time.getDay()];
|
const _Day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][time.getDay()];
|
||||||
const _time = `${this._getLineCh(cm) ? '\n' : ''}${_Year}-${_Month}-${_Date} ${_Hours}:${_Minutes}:${_Seconds} ${_Day}\n`;
|
const _time = `${this._getLineCh(cm) ? '\n' : ''}${_Year}-${_Month}-${_Date} ${_Hours}:${_Minutes}:${_Seconds} ${_Day}\n`;
|
||||||
this._replaceSelection(cm, _time);
|
this._replaceSelection(cm, _time);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleHr(cm) {
|
handleHr(cm) {
|
||||||
const str = `${this._getLineCh(cm) ? '\n' : ''}\n------------\n\n`;
|
const str = `${this._getLineCh(cm) ? '\n' : ''}\n------------\n\n`;
|
||||||
this._replaceSelection(cm, str);
|
this._replaceSelection(cm, str);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleClean(cm) {
|
handleClean(cm) {
|
||||||
cm.dispatch({ changes: { from: 0, to: cm.state.doc.length, insert: '' } });
|
cm.dispatch({ changes: { from: 0, to: cm.state.doc.length, insert: '' } });
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleOrdered(cm) {
|
handleOrdered(cm) {
|
||||||
const selection = this._getSelection(cm);
|
const selection = this._getSelection(cm);
|
||||||
if (selection === '') {
|
if (selection === '') {
|
||||||
const str = (this._getLineCh(cm) ? '\n\n' : '') + '1. ';
|
const str = (this._getLineCh(cm) ? '\n\n' : '') + '1. ';
|
||||||
this._replaceSelection(cm, str);
|
this._replaceSelection(cm, str);
|
||||||
} else {
|
} else {
|
||||||
const selectionText = selection.split('\n');
|
const selectionText = selection.split('\n');
|
||||||
for (let i = 0, len = selectionText.length; i < len; i++) {
|
for (let i = 0, len = selectionText.length; i < len; i++) {
|
||||||
selectionText[i] = selectionText[i] === '' ? '' : i + 1 + '. ' + selectionText[i];
|
selectionText[i] = selectionText[i] === '' ? '' : i + 1 + '. ' + selectionText[i];
|
||||||
}
|
}
|
||||||
const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n');
|
const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n');
|
||||||
this._replaceSelection(cm, str);
|
this._replaceSelection(cm, str);
|
||||||
}
|
}
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleUnordered(cm) {
|
handleUnordered(cm) {
|
||||||
const selection = this._getSelection(cm);
|
const selection = this._getSelection(cm);
|
||||||
if (selection === '') {
|
if (selection === '') {
|
||||||
const str = (this._getLineCh(cm) ? '\n' : '') + '- ';
|
const str = (this._getLineCh(cm) ? '\n' : '') + '- ';
|
||||||
this._replaceSelection(cm, str);
|
this._replaceSelection(cm, str);
|
||||||
} else {
|
} else {
|
||||||
const selectionText = selection.split('\n');
|
const selectionText = selection.split('\n');
|
||||||
for (let i = 0, len = selectionText.length; i < len; i++) {
|
for (let i = 0, len = selectionText.length; i < len; i++) {
|
||||||
selectionText[i] = selectionText[i] === '' ? '' : '- ' + selectionText[i];
|
selectionText[i] = selectionText[i] === '' ? '' : '- ' + selectionText[i];
|
||||||
}
|
}
|
||||||
const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n');
|
const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n');
|
||||||
this._replaceSelection(cm, str);
|
this._replaceSelection(cm, str);
|
||||||
}
|
}
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleQuote(cm) {
|
handleQuote(cm) {
|
||||||
const selection = this._getSelection(cm);
|
const selection = this._getSelection(cm);
|
||||||
if (selection === '') {
|
if (selection === '') {
|
||||||
this._replaceSelection(cm, `${this._getLineCh(cm) ? '\n' : ''}> `);
|
this._replaceSelection(cm, `${this._getLineCh(cm) ? '\n' : ''}> `);
|
||||||
} else {
|
} else {
|
||||||
const selectionText = selection.split('\n');
|
const selectionText = selection.split('\n');
|
||||||
for (let i = 0, len = selectionText.length; i < len; i++) {
|
for (let i = 0, len = selectionText.length; i < len; i++) {
|
||||||
selectionText[i] = selectionText[i] === '' ? '' : '> ' + selectionText[i];
|
selectionText[i] = selectionText[i] === '' ? '' : '> ' + selectionText[i];
|
||||||
}
|
}
|
||||||
const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n');
|
const str = (this._getLineCh(cm) ? '\n' : '') + selectionText.join('\n');
|
||||||
this._replaceSelection(cm, str);
|
this._replaceSelection(cm, str);
|
||||||
}
|
}
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
handleDownload(cm) {
|
handleDownload(cm) {
|
||||||
const title = $('#title').val() || '新文章';
|
const title = $('#title').val() || '新文章';
|
||||||
const aTag = document.createElement('a');
|
const aTag = document.createElement('a');
|
||||||
let blob = new Blob([cm.state.doc.toString()]);
|
let blob = new Blob([cm.state.doc.toString()]);
|
||||||
aTag.download = title + '.md';
|
aTag.download = title + '.md';
|
||||||
aTag.href = URL.createObjectURL(blob);
|
aTag.href = URL.createObjectURL(blob);
|
||||||
aTag.click();
|
aTag.click();
|
||||||
URL.revokeObjectURL(blob);
|
URL.revokeObjectURL(blob);
|
||||||
}
|
}
|
||||||
handleTitle(cm, tool) {
|
handleTitle(cm, tool) {
|
||||||
const item = $(`
|
const item = $(`
|
||||||
<div class="cm-tools-item" title="${tool.title}">
|
<div class="cm-tools-item" title="${tool.title}">
|
||||||
${tool.innerHTML}
|
${tool.innerHTML}
|
||||||
<div class="cm-tools__dropdown">
|
<div class="cm-tools__dropdown">
|
||||||
@ -208,26 +208,26 @@ export default class JoeAction {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
item.on('click', function (e) {
|
item.on('click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
$(this).toggleClass('active');
|
$(this).toggleClass('active');
|
||||||
});
|
});
|
||||||
const _this = this;
|
const _this = this;
|
||||||
item.on('click', '.cm-tools__dropdown-item', function (e) {
|
item.on('click', '.cm-tools__dropdown-item', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const text = $(this).attr('data-text');
|
const text = $(this).attr('data-text');
|
||||||
if (_this._getLineCh(cm)) _this._replaceSelection(cm, '\n\n' + text);
|
if (_this._getLineCh(cm)) _this._replaceSelection(cm, '\n\n' + text);
|
||||||
else _this._replaceSelection(cm, text);
|
else _this._replaceSelection(cm, text);
|
||||||
item.removeClass('active');
|
item.removeClass('active');
|
||||||
cm.focus();
|
cm.focus();
|
||||||
});
|
});
|
||||||
$(document).on('click', () => item.removeClass('active'));
|
$(document).on('click', () => item.removeClass('active'));
|
||||||
$('.cm-tools').append(item);
|
$('.cm-tools').append(item);
|
||||||
}
|
}
|
||||||
handleLink(cm) {
|
handleLink(cm) {
|
||||||
this._openModal({
|
this._openModal({
|
||||||
title: '插入链接',
|
title: '插入链接',
|
||||||
innerHtml: `
|
innerHtml: `
|
||||||
<div class="fitem">
|
<div class="fitem">
|
||||||
<label>链接标题</label>
|
<label>链接标题</label>
|
||||||
<input autocomplete="off" name="title" placeholder="请输入链接标题"/>
|
<input autocomplete="off" name="title" placeholder="请输入链接标题"/>
|
||||||
@ -237,18 +237,18 @@ export default class JoeAction {
|
|||||||
<input autocomplete="off" name="url" placeholder="请输入链接地址"/>
|
<input autocomplete="off" name="url" placeholder="请输入链接地址"/>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
confirm: () => {
|
confirm: () => {
|
||||||
const title = $(".cm-modal input[name='title']").val() || 'Test';
|
const title = $(".cm-modal input[name='title']").val() || 'Test';
|
||||||
const url = $(".cm-modal input[name='url']").val() || 'http://';
|
const url = $(".cm-modal input[name='url']").val() || 'http://';
|
||||||
this._replaceSelection(cm, ` [${title}](${url}) `);
|
this._replaceSelection(cm, ` [${title}](${url}) `);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleImage(cm) {
|
handleImage(cm) {
|
||||||
this._openModal({
|
this._openModal({
|
||||||
title: '插入图片',
|
title: '插入图片',
|
||||||
innerHtml: `
|
innerHtml: `
|
||||||
<div class="fitem">
|
<div class="fitem">
|
||||||
<label>图片名称</label>
|
<label>图片名称</label>
|
||||||
<input autocomplete="off" name="title" placeholder="请输入图片名称"/>
|
<input autocomplete="off" name="title" placeholder="请输入图片名称"/>
|
||||||
@ -258,18 +258,18 @@ export default class JoeAction {
|
|||||||
<input autocomplete="off" name="url" placeholder="请输入图片地址"/>
|
<input autocomplete="off" name="url" placeholder="请输入图片地址"/>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
confirm: () => {
|
confirm: () => {
|
||||||
const title = $(".cm-modal input[name='title']").val() || 'Test';
|
const title = $(".cm-modal input[name='title']").val() || 'Test';
|
||||||
const url = $(".cm-modal input[name='url']").val() || 'http://';
|
const url = $(".cm-modal input[name='url']").val() || 'http://';
|
||||||
this._replaceSelection(cm, ` ![${title}](${url}) `);
|
this._replaceSelection(cm, ` ![${title}](${url}) `);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleTable(cm) {
|
handleTable(cm) {
|
||||||
this._openModal({
|
this._openModal({
|
||||||
title: '插入表格',
|
title: '插入表格',
|
||||||
innerHtml: `
|
innerHtml: `
|
||||||
<div class="fitem">
|
<div class="fitem">
|
||||||
<label>表格行</label>
|
<label>表格行</label>
|
||||||
<input style="width: 50px; flex: none; margin-right: 10px;" value="3" autocomplete="off" name="row"/>
|
<input style="width: 50px; flex: none; margin-right: 10px;" value="3" autocomplete="off" name="row"/>
|
||||||
@ -277,33 +277,33 @@ export default class JoeAction {
|
|||||||
<input style="width: 50px; flex: none;" value="3" autocomplete="off" name="column"/>
|
<input style="width: 50px; flex: none;" value="3" autocomplete="off" name="column"/>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
confirm: () => {
|
confirm: () => {
|
||||||
let row = $(".cm-modal input[name='row']").val();
|
let row = $(".cm-modal input[name='row']").val();
|
||||||
let column = $(".cm-modal input[name='column']").val();
|
let column = $(".cm-modal input[name='column']").val();
|
||||||
if (isNaN(row)) row = 3;
|
if (isNaN(row)) row = 3;
|
||||||
if (isNaN(column)) column = 3;
|
if (isNaN(column)) column = 3;
|
||||||
let rowStr = '';
|
let rowStr = '';
|
||||||
let rangeStr = '';
|
let rangeStr = '';
|
||||||
let columnlStr = '';
|
let columnlStr = '';
|
||||||
for (let i = 0; i < column; i++) {
|
for (let i = 0; i < column; i++) {
|
||||||
rowStr += '| 表头 ';
|
rowStr += '| 表头 ';
|
||||||
rangeStr += '| :--: ';
|
rangeStr += '| :--: ';
|
||||||
}
|
}
|
||||||
for (let i = 0; i < row; i++) {
|
for (let i = 0; i < row; i++) {
|
||||||
for (let j = 0; j < column; j++) columnlStr += '| 表格 ';
|
for (let j = 0; j < column; j++) columnlStr += '| 表格 ';
|
||||||
columnlStr += '|\n';
|
columnlStr += '|\n';
|
||||||
}
|
}
|
||||||
const htmlStr = `${rowStr}|\n${rangeStr}|\n${columnlStr}\n`;
|
const htmlStr = `${rowStr}|\n${rangeStr}|\n${columnlStr}\n`;
|
||||||
if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr);
|
if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr);
|
||||||
else this._replaceSelection(cm, htmlStr);
|
else this._replaceSelection(cm, htmlStr);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleCodeBlock(cm) {
|
handleCodeBlock(cm) {
|
||||||
this._openModal({
|
this._openModal({
|
||||||
title: '插入代码块',
|
title: '插入代码块',
|
||||||
innerHtml: `
|
innerHtml: `
|
||||||
<div class="fitem">
|
<div class="fitem">
|
||||||
<label>语言类型</label>
|
<label>语言类型</label>
|
||||||
<select name="type">
|
<select name="type">
|
||||||
@ -347,25 +347,30 @@ export default class JoeAction {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
confirm: () => {
|
confirm: () => {
|
||||||
const type = $(".cm-modal select[name='type']").val() || 'html';
|
const type = $(".cm-modal select[name='type']").val() || 'html';
|
||||||
const htmlStr = `\`\`\`${type}\ncode here...\n\`\`\``;
|
const htmlStr = `\`\`\`${type}\ncode here...\n\`\`\``;
|
||||||
if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr);
|
if (this._getLineCh(cm)) this._replaceSelection(cm, '\n\n' + htmlStr);
|
||||||
else this._replaceSelection(cm, htmlStr);
|
else this._replaceSelection(cm, htmlStr);
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleAbout() {
|
handleAbout() {
|
||||||
this._openModal({
|
this._openModal({
|
||||||
title: '关于',
|
title: '关于',
|
||||||
innerHtml: `
|
innerHtml: `
|
||||||
<ul>
|
<ul>
|
||||||
<li>短代码功能正在开发中...</li>
|
<li>短代码功能正在开发中...</li>
|
||||||
<li>仅支持网络图片粘贴上传(截图等)</li>
|
<li>仅支持网络图片粘贴上传(截图等)</li>
|
||||||
<li>本编辑器仅供Joe主题使用,未经允许不得移植至其他主题!</li>
|
<li>本编辑器仅供Joe主题使用,未经允许不得移植至其他主题!</li>
|
||||||
</ul>
|
</ul>
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
handleTask(cm, type) {
|
||||||
|
const str = type ? '{x}' : '{ }';
|
||||||
|
this._replaceSelection(cm, ` ${str} `);
|
||||||
|
cm.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
10
typecho/write/js/_create.js
Normal file
10
typecho/write/js/_create.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const parser = new HyperDown();
|
||||||
|
export default function createPreviewHtml(str) {
|
||||||
|
str = parser.makeHtml(str);
|
||||||
|
|
||||||
|
str = str.replace(/{x}/g, '<input type="checkbox" class="task" checked disabled></input>')
|
||||||
|
str = str.replace(/{ }/g, '<input type="checkbox" class="task" disabled></input>')
|
||||||
|
|
||||||
|
$('.cm-preview-content').html(str);
|
||||||
|
$('.cm-preview-content pre code').each((i, el) => Prism.highlightElement(el));
|
||||||
|
}
|
@ -84,6 +84,16 @@ export default [
|
|||||||
title: '符号表情',
|
title: '符号表情',
|
||||||
innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="19" height="19"><path d="M512 56.889A455.111 455.111 0 0 0 56.889 512 455.111 455.111 0 0 0 512 967.111 455.111 455.111 0 0 0 967.111 512 455.111 455.111 0 0 0 512 56.889zm111.047 270.336A69.086 69.086 0 0 1 671.29 307.2c17.863 0 35.67 7.396 48.242 20.025 12.629 12.572 20.025 30.379 20.025 48.242 0 17.863-7.396 35.669-20.025 48.241-12.8 12.744-30.151 19.912-48.242 20.025a68.95 68.95 0 0 1-48.242-20.025 68.95 68.95 0 0 1-20.025-48.241c0-17.863 7.396-35.67 20.025-48.242zm-318.578 0a69.086 69.086 0 0 1 48.242-20.025c17.863 0 35.67 7.396 48.242 20.025 12.63 12.572 20.025 30.379 20.025 48.242 0 17.863-7.396 35.669-20.025 48.241-12.8 12.744-30.151 19.912-48.242 20.025a68.95 68.95 0 0 1-48.242-20.025 68.95 68.95 0 0 1-20.025-48.241c0-17.863 7.396-35.67 20.025-48.242zM786.375 566.67c-10.24 132.893-118.556 236.544-270.563 235.975-156.331 1.707-264.704-107.178-270.507-235.975a23.324 23.324 0 0 1-2.446-10.41c0-13.597 11.605-24.633 26.282-24.52h493.796c14.336 0 26.055 11.037 26.055 24.52a24.292 24.292 0 0 1-2.617 10.41z"/></svg>'
|
innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="19" height="19"><path d="M512 56.889A455.111 455.111 0 0 0 56.889 512 455.111 455.111 0 0 0 512 967.111 455.111 455.111 0 0 0 967.111 512 455.111 455.111 0 0 0 512 56.889zm111.047 270.336A69.086 69.086 0 0 1 671.29 307.2c17.863 0 35.67 7.396 48.242 20.025 12.629 12.572 20.025 30.379 20.025 48.242 0 17.863-7.396 35.669-20.025 48.241-12.8 12.744-30.151 19.912-48.242 20.025a68.95 68.95 0 0 1-48.242-20.025 68.95 68.95 0 0 1-20.025-48.241c0-17.863 7.396-35.67 20.025-48.242zm-318.578 0a69.086 69.086 0 0 1 48.242-20.025c17.863 0 35.67 7.396 48.242 20.025 12.63 12.572 20.025 30.379 20.025 48.242 0 17.863-7.396 35.669-20.025 48.241-12.8 12.744-30.151 19.912-48.242 20.025a68.95 68.95 0 0 1-48.242-20.025 68.95 68.95 0 0 1-20.025-48.241c0-17.863 7.396-35.67 20.025-48.242zM786.375 566.67c-10.24 132.893-118.556 236.544-270.563 235.975-156.331 1.707-264.704-107.178-270.507-235.975a23.324 23.324 0 0 1-2.446-10.41c0-13.597 11.605-24.633 26.282-24.52h493.796c14.336 0 26.055 11.037 26.055 24.52a24.292 24.292 0 0 1-2.617 10.41z"/></svg>'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'task-no',
|
||||||
|
title: '任务 - 未完成',
|
||||||
|
innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20"><path d="M831.55 128.531c38.35 0 63.911 25.568 63.911 63.91v639.104c0 38.355-25.561 63.916-63.91 63.916H192.44c-38.34 0-63.908-25.56-63.908-63.916V192.442c0-38.343 25.567-63.91 63.908-63.91h639.11m0-63.91H192.44c-70.3 0-127.816 57.518-127.816 127.82v639.103c0 70.308 57.515 127.833 127.816 127.833h639.11c70.294 0 127.822-57.525 127.822-127.833V192.442c0-70.302-57.527-127.82-127.823-127.82zm0 0"/></svg>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'task-yes',
|
||||||
|
title: '任务 - 已完成',
|
||||||
|
innerHTML: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20"><path d="M831.551 64.623h-639.11c-70.3 0-127.816 57.517-127.816 127.819v639.103c0 70.308 57.515 127.833 127.816 127.833h639.11c70.294 0 127.822-57.525 127.822-127.833V192.442c0-70.302-57.527-127.82-127.822-127.82zM646.217 486.44c-108.652 159.779-204.52 345.115-204.52 345.115L192.443 550.351l63.916-70.303 153.385 146.994s76.695-127.822 178.95-236.469c102.261-108.652 223.689-198.127 223.689-198.127l19.17 63.916c0-.001-102.255 108.646-185.337 230.078z"/></svg>'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'code-block',
|
type: 'code-block',
|
||||||
title: '代码块',
|
title: '代码块',
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -7,36 +7,29 @@ import { history, historyKeymap } from '@codemirror/history';
|
|||||||
import { classHighlightStyle } from '@codemirror/highlight';
|
import { classHighlightStyle } from '@codemirror/highlight';
|
||||||
import tools from './_tools';
|
import tools from './_tools';
|
||||||
import JoeAction from './_actions';
|
import JoeAction from './_actions';
|
||||||
|
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.parser = new HyperDown();
|
this._isPasting = false;
|
||||||
this._isPasting = false;
|
this.init_ViewPort();
|
||||||
|
this.init_Editor();
|
||||||
|
this.init_Preview();
|
||||||
|
this.init_Tools();
|
||||||
|
this.init_Insert();
|
||||||
|
}
|
||||||
|
|
||||||
this.init_ViewPort();
|
/* 已测 √ */
|
||||||
this.init_Editor();
|
init_ViewPort() {
|
||||||
this.init_Preview();
|
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');
|
||||||
this.init_Tools();
|
else $('head').append('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, shrink-to-fit=no, viewport-fit=cover">');
|
||||||
this.init_Insert();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_createPreviewHtml(str) {
|
/* 已测 √ */
|
||||||
str = this.parser.makeHtml(str);
|
init_Editor() {
|
||||||
$('.cm-preview-content').html(str);
|
$('#text').before(`
|
||||||
$('.cm-preview-content pre code').each((i, el) => Prism.highlightElement(el));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 已测 √ */
|
|
||||||
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');
|
|
||||||
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() {
|
|
||||||
$('#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">
|
||||||
@ -47,225 +40,231 @@ class Joe extends JoeAction {
|
|||||||
<div class="cm-progress-right"></div>
|
<div class="cm-progress-right"></div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
this._createPreviewHtml($('#text').val());
|
createPreviewHtml($('#text').val());
|
||||||
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;
|
||||||
this._createPreviewHtml(update.state.doc.toString());
|
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;
|
||||||
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;
|
||||||
};
|
};
|
||||||
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;
|
||||||
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;
|
||||||
};
|
};
|
||||||
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':
|
||||||
});
|
super.handleTask(this.cm, false);
|
||||||
$('.cm-tools').append(el);
|
break;
|
||||||
}
|
case 'task-yes':
|
||||||
});
|
super.handleTask(this.cm, true);
|
||||||
}
|
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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => new Joe());
|
document.addEventListener('DOMContentLoaded', () => new Joe());
|
||||||
|
@ -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()]
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user