ui-default: init

将ui-default合并至主存储库便于维护
This commit is contained in:
undefined committed 2021-04-03 01:44:22 +08:00
1 parent 6317c9057f
commit 5faa54c7ca
564 files changed
+23083 -14

No files matched your search

@@ -0,0 +1,20 @@
import { AutoloadPage } from 'vj/misc/Page';
import delay from 'vj/utils/delay';
import CmEditor from '.';
function runSubstitute($container) {
const selector = ['textarea[data-markdown]'];
$container.find(selector.join(', ')).get().forEach((element) => {
CmEditor.getOrConstruct($(element));
});
}
const cmEditorPage = new AutoloadPage('cmEditorPage', () => {
runSubstitute($('body'));
$(document).on('vjContentNew', async (e) => {
await delay(0);
runSubstitute($(e.target));
});
});
export default cmEditorPage;
@@ -0,0 +1,91 @@
.simplemde
border: 1px solid $editor-border-color
margin: 0 0 1rem
position: relative
height: rem(200px)
box-sizing: border-box
overflow: hidden
.cm-s-simplemde
border: 0
min-height: 0
height: auto
padding: 0
position: absolute
left: 0
top: 40px
width: 100%
bottom: 0
color: inherit
.simplemde-toolbar
position: absolute
left: 0
top: 0
width: 100%
border-radius: 0
border: 0
opacity: 0
background: $toolbar-bg
transform: translateY(-20px)
transition: opacity .5s, transform .5s
transition-timing-function: ease-out-cubic
&:hover
opacity: 1
.toolbar--visible .simplemde-toolbar
opacity: 1
transform: translateY(0)
.cm-s-simplemde .CodeMirror-scroll
height: 100%
min-height: 0
font-family: $code-font-family
color: $text-1-color
.simplemde-toolbar:before,
.simplemde-toolbar:after
display: none
.simplemde-toolbar
padding: rem(5px)
.simplemde-toolbar i.separator
border-right: 0
.simplemde-toolbar a
color: $toolbar-fore !important
border: 0
background: none
border-radius: 0
font-size: rem($font-size-icon)
outline: 0
&:hover
background: $toolbar-bg-hover
color: $toolbar-fore-hover !important
border: 0
&.active
background: $toolbar-bg-selected
color: $toolbar-fore-selected !important
border: 0
.simplemde-toolbar.disabled-for-preview a:not(.no-disable)
background: none
opacity: $toolbar-disabled-opacity
.cm-s-simplemde .CodeMirror-code .cm-comment
background: none
.simplemde-statusbar
display: none
.simplemde-preview
background: #FFF
.no-heading .cm-s-simplemde .CodeMirror-code
.cm-header-1, .cm-header-2, .cm-header-3, .cm-header-4
font-size: 1em
line-height: 1.5
@@ -0,0 +1,66 @@
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
export default class CmEditor extends DOMAttachedObject {
static DOMAttachKey = 'vjCmEditorInstance';
constructor($dom, options = {}) {
super($dom);
this.editor = null;
this.options = options;
this.init();
}
async init() {
const { default: VjCmEditor } = await import('./vjcmeditor');
const hasFocus = this.$dom.is(':focus');
const srcHeight = this.$dom.outerHeight();
this.editor = new VjCmEditor({
...this.options,
element: this.$dom.get(0),
});
this.moveToEnd();
const $editor = $(this.editor.wrapper);
$editor.css('height', srcHeight);
$editor.addClass('toolbar--visible');
if (hasFocus) {
this.focus();
}
}
isValid() {
return (this.editor !== null);
}
ensureValid() {
if (!this.isValid()) {
throw new Error('VjCmEditor is not loaded');
}
}
value(...argv) {
this.ensureValid();
const ret = this.editor.value(...argv);
if (argv.length > 0) {
this.moveToEnd();
}
return ret;
}
focus() {
this.ensureValid();
this.editor.codemirror.focus();
}
moveToEnd() {
this.ensureValid();
const cm = this.editor.codemirror;
cm.setCursor(cm.lineCount(), 0);
}
}
_.assign(CmEditor, DOMAttachedObject);
@@ -0,0 +1,32 @@
import _ from 'lodash';
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
import CmEditor from '.';
export default class TextareaHandler extends DOMAttachedObject {
static DOMAttachKey = 'vjTextareaHandlerInstance';
getCmEditor() {
return CmEditor.get(this.$dom);
}
isCmEditor() {
const editor = this.getCmEditor();
return (editor !== undefined && editor.isValid());
}
val(...argv) {
if (this.isCmEditor()) {
return this.getCmEditor().value(...argv);
}
return this.$dom.val(...argv);
}
focus() {
if (this.isCmEditor()) {
this.getCmEditor().focus();
}
this.$dom.focus();
}
}
_.assign(TextareaHandler, DOMAttachedObject);
@@ -0,0 +1,120 @@
import _ from 'lodash';
import SimpleMDE from 'vj-simplemde';
import request from 'vj/utils/request';
import i18n from 'vj/utils/i18n';
export default class VjCmEditor extends SimpleMDE {
constructor(options = {}) {
super({
autoDownloadFontAwesome: false,
spellChecker: false,
forceSync: true,
toolbar: [
{
name: 'bold',
action: SimpleMDE.toggleBold,
className: 'icon icon-bold',
title: i18n('Bold'),
},
{
name: 'italic',
action: SimpleMDE.toggleItalic,
className: 'icon icon-italic',
title: i18n('Italic'),
},
'|',
{
name: 'quote',
action: SimpleMDE.toggleBlockquote,
className: 'icon icon-quote',
title: i18n('Quote'),
},
{
name: 'unordered-list',
action: SimpleMDE.toggleUnorderedList,
className: 'icon icon-unordered_list',
title: i18n('Unordered List'),
},
{
name: 'ordered-list',
action: SimpleMDE.toggleOrderedList,
className: 'icon icon-ordered_list',
title: i18n('Ordered List'),
},
'|',
{
name: 'code',
action: () => this.insertCodeBlock(),
className: 'icon icon-code',
title: i18n('Insert Code'),
default: true,
},
{
name: 'link',
action: SimpleMDE.drawLink,
className: 'icon icon-link',
title: i18n('Create Link'),
default: true,
},
{
name: 'image',
action: SimpleMDE.drawImage,
className: 'icon icon-insert--image',
title: i18n('Insert Image'),
default: true,
},
'|',
{
name: 'preview',
action: SimpleMDE.togglePreview,
preAction: SimpleMDE.preRenderPreview,
className: 'icon icon-preview no-disable',
title: i18n('Toggle Preview'),
default: true,
},
],
commonmark: {
safe: true,
},
...options,
});
}
async markdown(text) {
// FIXME preview wont update after first toggle
const data = await request.ajax({
url: '/markdown',
method: 'post',
data: $.param({ text }, true),
dataType: 'text',
});
_.defer(this.preparePreview.bind(this));
return data;
}
preparePreview() {
const $preview = $(this.wrapper).find('.simplemde-preview');
$preview.addClass('typo');
$preview.attr('data-emoji-enabled', 'true');
$preview.trigger('vjContentNew');
}
insertCodeBlock() {
const text = this.codemirror.getSelection();
const startPoint = this.codemirror.getCursor('start');
const endPoint = this.codemirror.getCursor('end');
const leadingLines = (startPoint.line === 0 && startPoint.ch === 0) ? 0 : 2;
// eslint-disable-next-line prefer-template
const startText = _.repeat('\n', leadingLines) + '```cpp\n';
const endText = '\n```\n';
this.codemirror.replaceSelection(`${startText}${text}${endText}`);
startPoint.line += leadingLines + 1;
startPoint.ch = 0;
if (startPoint !== endPoint) {
endPoint.line += leadingLines + 1;
}
this.codemirror.setSelection(startPoint, endPoint);
this.codemirror.focus();
}
}