Archived
1
0
This repository has been archived on 2020-12-10. You can view files and clone it, but cannot push or open issues or pull requests.
old/assets/js/formats/code.js

119 lines
3.3 KiB
JavaScript
Raw Permalink Normal View History

2018-10-16 16:28:42 +00:00
import Delta from 'quill-delta';
import Parchment from 'parchment';
import Block from '../blots/block';
import Inline from '../blots/inline';
import TextBlot from '../blots/text';
class Code extends Inline {}
Code.blotName = 'code';
Code.tagName = 'CODE';
class CodeBlock extends Block {
static create(value) {
let domNode = super.create(value);
domNode.setAttribute('spellcheck', false);
return domNode;
}
static formats() {
return true;
}
delta() {
let text = this.domNode.textContent;
if (text.endsWith('\n')) { // Should always be true
text = text.slice(0, -1);
}
return text.split('\n').reduce((delta, frag) => {
return delta.insert(frag).insert('\n', this.formats());
}, new Delta());
}
format(name, value) {
if (name === this.statics.blotName && value) return;
let [text, ] = this.descendant(TextBlot, this.length() - 1);
if (text != null) {
text.deleteAt(text.length() - 1, 1);
}
super.format(name, value);
}
formatAt(index, length, name, value) {
if (length === 0) return;
if (Parchment.query(name, Parchment.Scope.BLOCK) == null ||
(name === this.statics.blotName && value === this.statics.formats(this.domNode))) {
return;
}
let nextNewline = this.newlineIndex(index);
if (nextNewline < 0 || nextNewline >= index + length) return;
let prevNewline = this.newlineIndex(index, true) + 1;
let isolateLength = nextNewline - prevNewline + 1;
let blot = this.isolate(prevNewline, isolateLength);
let next = blot.next;
blot.format(name, value);
if (next instanceof CodeBlock) {
next.formatAt(0, index - prevNewline + length - isolateLength, name, value);
}
}
insertAt(index, value, def) {
if (def != null) return;
let [text, offset] = this.descendant(TextBlot, index);
text.insertAt(offset, value);
}
length() {
let length = this.domNode.textContent.length;
if (!this.domNode.textContent.endsWith('\n')) {
return length + 1;
}
return length;
}
newlineIndex(searchIndex, reverse = false) {
if (!reverse) {
let offset = this.domNode.textContent.slice(searchIndex).indexOf('\n');
return offset > -1 ? searchIndex + offset : -1;
} else {
return this.domNode.textContent.slice(0, searchIndex).lastIndexOf('\n');
}
}
optimize(context) {
if (!this.domNode.textContent.endsWith('\n')) {
this.appendChild(Parchment.create('text', '\n'));
}
super.optimize(context);
let next = this.next;
if (next != null && next.prev === this &&
next.statics.blotName === this.statics.blotName &&
this.statics.formats(this.domNode) === next.statics.formats(next.domNode)) {
next.optimize(context);
next.moveChildren(this);
next.remove();
}
}
replace(target) {
super.replace(target);
[].slice.call(this.domNode.querySelectorAll('*')).forEach(function(node) {
let blot = Parchment.find(node);
if (blot == null) {
node.parentNode.removeChild(node);
} else if (blot instanceof Parchment.Embed) {
blot.remove();
} else {
blot.unwrap();
}
});
}
}
CodeBlock.blotName = 'code-block';
CodeBlock.tagName = 'PRE';
CodeBlock.TAB = ' ';
export { Code, CodeBlock as default };