| 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; |