123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import Parchment from 'parchment';
- import TextBlot from './text';
- class Cursor extends Parchment.Embed {
- static value() {
- return undefined;
- }
- constructor(domNode, selection) {
- super(domNode);
- this.selection = selection;
- this.textNode = document.createTextNode(Cursor.CONTENTS);
- this.domNode.appendChild(this.textNode);
- this._length = 0;
- }
- detach() {
- // super.detach() will also clear domNode.__blot
- if (this.parent != null) this.parent.removeChild(this);
- }
- format(name, value) {
- if (this._length !== 0) {
- return super.format(name, value);
- }
- let target = this, index = 0;
- while (target != null && target.statics.scope !== Parchment.Scope.BLOCK_BLOT) {
- index += target.offset(target.parent);
- target = target.parent;
- }
- if (target != null) {
- this._length = Cursor.CONTENTS.length;
- target.optimize();
- target.formatAt(index, Cursor.CONTENTS.length, name, value);
- this._length = 0;
- }
- }
- index(node, offset) {
- if (node === this.textNode) return 0;
- return super.index(node, offset);
- }
- length() {
- return this._length;
- }
- position() {
- return [this.textNode, this.textNode.data.length];
- }
- remove() {
- super.remove();
- this.parent = null;
- }
- restore() {
- if (this.selection.composing || this.parent == null) return;
- let textNode = this.textNode;
- let range = this.selection.getNativeRange();
- let restoreText, start, end;
- if (range != null && range.start.node === textNode && range.end.node === textNode) {
- [restoreText, start, end] = [textNode, range.start.offset, range.end.offset];
- }
- // Link format will insert text outside of anchor tag
- while (this.domNode.lastChild != null && this.domNode.lastChild !== this.textNode) {
- this.domNode.parentNode.insertBefore(this.domNode.lastChild, this.domNode);
- }
- if (this.textNode.data !== Cursor.CONTENTS) {
- let text = this.textNode.data.split(Cursor.CONTENTS).join('');
- if (this.next instanceof TextBlot) {
- restoreText = this.next.domNode;
- this.next.insertAt(0, text);
- this.textNode.data = Cursor.CONTENTS;
- } else {
- this.textNode.data = text;
- this.parent.insertBefore(Parchment.create(this.textNode), this);
- this.textNode = document.createTextNode(Cursor.CONTENTS);
- this.domNode.appendChild(this.textNode);
- }
- }
- this.remove();
- if (start != null) {
- [start, end] = [start, end].map(function(offset) {
- return Math.max(0, Math.min(restoreText.data.length, offset - 1));
- });
- return {
- startNode: restoreText,
- startOffset: start,
- endNode: restoreText,
- endOffset: end
- };
- }
- }
- update(mutations, context) {
- if (mutations.some((mutation) => {
- return mutation.type === 'characterData' && mutation.target === this.textNode;
- })) {
- let range = this.restore();
- if (range) context.range = range;
- }
- }
- value() {
- return '';
- }
- }
- Cursor.blotName = 'cursor';
- Cursor.className = 'ql-cursor';
- Cursor.tagName = 'span';
- Cursor.CONTENTS = "\uFEFF"; // Zero width no break space
- export default Cursor;
|