Skip to content

Commit

Permalink
update parchment to support multiple registries
Browse files Browse the repository at this point in the history
closes slab#1101
  • Loading branch information
jhchen committed Jun 2, 2018
1 parent d259e5d commit eda1472
Show file tree
Hide file tree
Showing 27 changed files with 130 additions and 173 deletions.
15 changes: 8 additions & 7 deletions blots/block.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import extend from 'extend';
import Delta from 'quill-delta';
import Parchment, {
import {
AttributorStore,
BlockBlot,
EmbedBlot,
LeafBlot,
Scope,
} from 'parchment';
import Break from './break';
import Inline from './inline';
Expand All @@ -13,8 +14,8 @@ import TextBlot from './text';
const NEWLINE_LENGTH = 1;

class Block extends BlockBlot {
constructor(domNode) {
super(domNode);
constructor(scroll, domNode) {
super(scroll, domNode);
this.cache = {};
}

Expand All @@ -39,7 +40,7 @@ class Block extends BlockBlot {

formatAt(index, length, name, value) {
if (length <= 0) return;
if (Parchment.query(name, Parchment.Scope.BLOCK)) {
if (this.scroll.query(name, Scope.BLOCK)) {
if (index + length === this.length()) {
this.format(name, value);
}
Expand Down Expand Up @@ -147,7 +148,7 @@ class BlockEmbed extends EmbedBlot {
}

format(name, value) {
const attribute = Parchment.query(name, Parchment.Scope.BLOCK_ATTRIBUTE);
const attribute = this.scroll.query(name, Scope.BLOCK_ATTRIBUTE);
if (attribute != null) {
this.attributes.attribute(attribute, value);
}
Expand All @@ -159,15 +160,15 @@ class BlockEmbed extends EmbedBlot {

insertAt(index, value, def) {
if (typeof value === 'string' && value.endsWith('\n')) {
const block = Parchment.create(Block.blotName);
const block = this.scroll.create(Block.blotName);
this.parent.insertBefore(block, index === 0 ? this : this.next);
block.insertAt(0, value.slice(0, -1));
} else {
super.insertAt(index, value, def);
}
}
}
BlockEmbed.scope = Parchment.Scope.BLOCK_BLOT;
BlockEmbed.scope = Scope.BLOCK_BLOT;
// It is important for cursor behavior BlockEmbeds use tags that are block level elements

function bubbleFormats(blot, formats = {}) {
Expand Down
13 changes: 5 additions & 8 deletions blots/cursor.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Parchment, { EmbedBlot } from 'parchment';
import { EmbedBlot, Scope } from 'parchment';
import TextBlot from './text';

class Cursor extends EmbedBlot {
static value() {
return undefined;
}

constructor(domNode, selection) {
super(domNode);
constructor(scroll, domNode, selection) {
super(scroll, domNode);
this.selection = selection;
this.textNode = document.createTextNode(Cursor.CONTENTS);
this.domNode.appendChild(this.textNode);
Expand All @@ -26,10 +26,7 @@ class Cursor extends EmbedBlot {
}
let target = this;
let index = 0;
while (
target != null &&
target.statics.scope !== Parchment.Scope.BLOCK_BLOT
) {
while (target != null && target.statics.scope !== Scope.BLOCK_BLOT) {
index += target.offset(target.parent);
target = target.parent;
}
Expand Down Expand Up @@ -94,7 +91,7 @@ class Cursor extends EmbedBlot {
this.textNode.data = Cursor.CONTENTS;
} else {
this.textNode.data = text;
this.parent.insertBefore(Parchment.create(this.textNode), this);
this.parent.insertBefore(this.scroll.create(this.textNode), this);
this.textNode = document.createTextNode(Cursor.CONTENTS);
this.domNode.appendChild(this.textNode);
}
Expand Down
10 changes: 5 additions & 5 deletions blots/embed.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Parchment, { EmbedBlot } from 'parchment';
import { EmbedBlot } from 'parchment';
import TextBlot from './text';

const GUARD_TEXT = '\uFEFF';

class Embed extends EmbedBlot {
constructor(node) {
super(node);
constructor(scroll, node) {
super(scroll, node);
this.contentNode = document.createElement('span');
this.contentNode.setAttribute('contenteditable', false);
Array.from(this.domNode.childNodes).forEach(childNode => {
Expand Down Expand Up @@ -38,7 +38,7 @@ class Embed extends EmbedBlot {
};
} else {
textNode = document.createTextNode(text);
this.parent.insertBefore(Parchment.create(textNode), this);
this.parent.insertBefore(this.scroll.create(textNode), this);
range = {
startNode: textNode,
startOffset: text.length,
Expand All @@ -53,7 +53,7 @@ class Embed extends EmbedBlot {
};
} else {
textNode = document.createTextNode(text);
this.parent.insertBefore(Parchment.create(textNode), this.next);
this.parent.insertBefore(this.scroll.create(textNode), this.next);
range = {
startNode: textNode,
startOffset: text.length,
Expand Down
4 changes: 2 additions & 2 deletions blots/inline.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Parchment, { EmbedBlot, InlineBlot } from 'parchment';
import { EmbedBlot, InlineBlot, Scope } from 'parchment';
import Break from './break';
import Text from './text';

Expand All @@ -19,7 +19,7 @@ class Inline extends InlineBlot {
formatAt(index, length, name, value) {
if (
Inline.compare(this.statics.blotName, name) < 0 &&
Parchment.query(name, Parchment.Scope.BLOT)
this.scroll.query(name, Scope.BLOT)
) {
const blot = this.isolate(index, length);
if (value) {
Expand Down
29 changes: 9 additions & 20 deletions blots/scroll.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Parchment, { ScrollBlot, ContainerBlot } from 'parchment';
import { Scope, ScrollBlot, ContainerBlot } from 'parchment';
import Emitter from '../core/emitter';
import Block, { BlockEmbed } from './block';
import Break from './break';
Expand All @@ -9,15 +9,9 @@ function isLine(blot) {
}

class Scroll extends ScrollBlot {
constructor(domNode, config) {
super(domNode);
this.emitter = config.emitter;
if (Array.isArray(config.whitelist)) {
this.whitelist = config.whitelist.reduce((whitelist, format) => {
whitelist[format] = true;
return whitelist;
}, {});
}
constructor(registry, domNode, { emitter }) {
super(registry, domNode);
this.emitter = emitter;
// Some reason fixes composition issues with character languages in Windows/Chrome, Safari
this.domNode.addEventListener('DOMNodeInserted', () => {});
this.optimize();
Expand Down Expand Up @@ -63,27 +57,22 @@ class Scroll extends ScrollBlot {
}

formatAt(index, length, format, value) {
if (this.whitelist != null && !this.whitelist[format]) return;
super.formatAt(index, length, format, value);
this.optimize();
}

insertAt(index, value, def) {
if (def != null && this.whitelist != null && !this.whitelist[value]) return;
if (index >= this.length()) {
if (
def == null ||
Parchment.query(value, Parchment.Scope.BLOCK) == null
) {
const blot = Parchment.create(this.statics.defaultChild.blotName);
if (def == null || this.scroll.query(value, Scope.BLOCK) == null) {
const blot = this.scroll.create(this.statics.defaultChild.blotName);
this.appendChild(blot);
if (def == null && value.endsWith('\n')) {
blot.insertAt(0, value.slice(0, -1), def);
} else {
blot.insertAt(0, value, def);
}
} else {
const embed = Parchment.create(value, def);
const embed = this.scroll.create(value, def);
this.appendChild(embed);
}
} else {
Expand All @@ -93,8 +82,8 @@ class Scroll extends ScrollBlot {
}

insertBefore(blot, ref) {
if (blot.statics.scope === Parchment.Scope.INLINE_BLOT) {
const wrapper = Parchment.create(this.statics.defaultChild.blotName);
if (blot.statics.scope === Scope.INLINE_BLOT) {
const wrapper = this.scroll.create(this.statics.defaultChild.blotName);
wrapper.appendChild(blot);
super.insertBefore(wrapper, ref);
} else {
Expand Down
3 changes: 0 additions & 3 deletions core.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Parchment from 'parchment';
import Quill from './core/quill';

import Block, { BlockEmbed } from './blots/block';
Expand Down Expand Up @@ -32,6 +31,4 @@ Quill.register({
'modules/uploader': Uploader,
});

Parchment.register(Block, Break, Cursor, Inline, Scroll, TextBlot);

export default Quill;
8 changes: 3 additions & 5 deletions core/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import equal from 'deep-equal';
import extend from 'extend';
import Delta from 'quill-delta';
import DeltaOp from 'quill-delta/lib/op';
import Parchment, { LeafBlot } from 'parchment';
import { LeafBlot } from 'parchment';
import CursorBlot from '../blots/cursor';
import Block, { bubbleFormats } from '../blots/block';
import Break from '../blots/break';
Expand Down Expand Up @@ -75,8 +75,6 @@ class Editor {
formatLine(index, length, formats = {}) {
this.scroll.update();
Object.keys(formats).forEach(format => {
if (this.scroll.whitelist != null && !this.scroll.whitelist[format])
return;
this.scroll.lines(index, Math.max(length, 1)).forEach(line => {
line.format(format, formats[format]);
});
Expand Down Expand Up @@ -187,10 +185,10 @@ class Editor {
mutations.length === 1 &&
mutations[0].type === 'characterData' &&
mutations[0].target.data.match(ASCII) &&
Parchment.find(mutations[0].target)
this.scroll.find(mutations[0].target)
) {
// Optimization for character changes
const textBlot = Parchment.find(mutations[0].target);
const textBlot = this.scroll.find(mutations[0].target);
const formats = bubbleFormats(textBlot);
const index = textBlot.offset(this.scroll);
const oldValue = mutations[0].oldValue.replace(CursorBlot.CONTENTS, '');
Expand Down
22 changes: 13 additions & 9 deletions core/quill.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Delta from 'quill-delta';
import Parchment from 'parchment';
import * as Parchment from 'parchment';
import extend from 'extend';
import Editor from './editor';
import Emitter from './emitter';
Expand All @@ -11,6 +11,8 @@ import Theme from './theme';

const debug = logger('quill');

const globalRegistry = new Parchment.Registry();

class Quill {
static debug(limit) {
if (limit === true) {
Expand All @@ -20,7 +22,7 @@ class Quill {
}

static find(node) {
return instances.get(node) || Parchment.find(node);
return instances.get(node) || globalRegistry.find(node);
}

static import(name) {
Expand Down Expand Up @@ -50,10 +52,10 @@ class Quill {
(path.startsWith('blots/') || path.startsWith('formats/')) &&
target.blotName !== 'abstract'
) {
Parchment.register(target);
globalRegistry.register(target);
}
if (typeof target.register === 'function') {
target.register();
target.register(globalRegistry);
}
}
}
Expand All @@ -79,9 +81,11 @@ class Quill {
this.root.setAttribute('data-gramm', false);
this.scrollingContainer = this.options.scrollingContainer || this.root;
this.emitter = new Emitter();
this.scroll = Parchment.create(this.root, {
const ScrollBlot = this.options.registry.query(
Parchment.ScrollBlot.blotName,
);
this.scroll = new ScrollBlot(this.options.registry, this.root, {
emitter: this.emitter,
whitelist: this.options.formats,
});
this.editor = new Editor(this.scroll);
this.selection = new Selection(this.scroll, this.emitter);
Expand Down Expand Up @@ -169,7 +173,7 @@ class Quill {
let change = new Delta();
if (range == null) {
return change;
} else if (Parchment.query(name, Parchment.Scope.BLOCK)) {
} else if (this.scroll.query(name, Parchment.Scope.BLOCK)) {
change = this.editor.formatLine(range.index, range.length, {
[name]: value,
});
Expand Down Expand Up @@ -420,10 +424,10 @@ class Quill {
}
Quill.DEFAULTS = {
bounds: null,
formats: null,
modules: {},
placeholder: '',
readOnly: false,
registry: globalRegistry,
scrollingContainer: null,
theme: 'default',
};
Expand Down Expand Up @@ -608,4 +612,4 @@ function shiftRange(range, index, length, source) {
return new Range(start, end - start);
}

export { expandConfig, overload, Quill as default };
export { globalRegistry, expandConfig, overload, Quill as default };
11 changes: 5 additions & 6 deletions core/selection.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Parchment, { LeafBlot, ContainerBlot } from 'parchment';
import { ContainerBlot, LeafBlot, Scope } from 'parchment';
import clone from 'clone';
import equal from 'deep-equal';
import Emitter from './emitter';
Expand All @@ -20,7 +20,7 @@ class Selection {
this.composing = false;
this.mouseDown = false;
this.root = this.scroll.domNode;
this.cursor = Parchment.create('cursor', this);
this.cursor = this.scroll.create('cursor', this);
// savedRange is last non-null range
this.savedRange = new Range(0, 0);
this.lastRange = this.savedRange;
Expand Down Expand Up @@ -98,17 +98,16 @@ class Selection {
}

format(format, value) {
if (this.scroll.whitelist != null && !this.scroll.whitelist[format]) return;
this.scroll.update();
const nativeRange = this.getNativeRange();
if (
nativeRange == null ||
!nativeRange.native.collapsed ||
Parchment.query(format, Parchment.Scope.BLOCK)
this.scroll.query(format, Scope.BLOCK)
)
return;
if (nativeRange.start.node !== this.cursor.textNode) {
const blot = Parchment.find(nativeRange.start.node, false);
const blot = this.scroll.find(nativeRange.start.node, false);
if (blot == null) return;
// TODO Give blot ability to not split
if (blot instanceof LeafBlot) {
Expand Down Expand Up @@ -199,7 +198,7 @@ class Selection {
}
const indexes = positions.map(position => {
const [node, offset] = position;
const blot = Parchment.find(node, true);
const blot = this.scroll.find(node, true);
const index = blot.offset(this.scroll);
if (offset === 0) {
return index;
Expand Down
8 changes: 2 additions & 6 deletions formats/align.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import Parchment, {
Attributor,
ClassAttributor,
StyleAttributor,
} from 'parchment';
import { Attributor, ClassAttributor, Scope, StyleAttributor } from 'parchment';

const config = {
scope: Parchment.Scope.BLOCK,
scope: Scope.BLOCK,
whitelist: ['right', 'center', 'justify'],
};

Expand Down
Loading

0 comments on commit eda1472

Please sign in to comment.