You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					131 lines
				
				3.4 KiB
			
		
		
			
		
	
	
					131 lines
				
				3.4 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								import Parchment from 'parchment';
							 | 
						||
| 
								 | 
							
								import Block from '../blots/block';
							 | 
						||
| 
								 | 
							
								import Container from '../blots/container';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class ListItem extends Block {
							 | 
						||
| 
								 | 
							
								  static formats(domNode) {
							 | 
						||
| 
								 | 
							
								    return domNode.tagName === this.tagName ? undefined : super.formats(domNode);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  format(name, value) {
							 | 
						||
| 
								 | 
							
								    if (name === List.blotName && !value) {
							 | 
						||
| 
								 | 
							
								      this.replaceWith(Parchment.create(this.statics.scope));
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      super.format(name, value);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  remove() {
							 | 
						||
| 
								 | 
							
								    if (this.prev == null && this.next == null) {
							 | 
						||
| 
								 | 
							
								      this.parent.remove();
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      super.remove();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  replaceWith(name, value) {
							 | 
						||
| 
								 | 
							
								    this.parent.isolate(this.offset(this.parent), this.length());
							 | 
						||
| 
								 | 
							
								    if (name === this.parent.statics.blotName) {
							 | 
						||
| 
								 | 
							
								      this.parent.replaceWith(name, value);
							 | 
						||
| 
								 | 
							
								      return this;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      this.parent.unwrap();
							 | 
						||
| 
								 | 
							
								      return super.replaceWith(name, value);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								ListItem.blotName = 'list-item';
							 | 
						||
| 
								 | 
							
								ListItem.tagName = 'LI';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class List extends Container {
							 | 
						||
| 
								 | 
							
								  static create(value) {
							 | 
						||
| 
								 | 
							
								    let tagName = value === 'ordered' ? 'OL' : 'UL';
							 | 
						||
| 
								 | 
							
								    let node = super.create(tagName);
							 | 
						||
| 
								 | 
							
								    if (value === 'checked' || value === 'unchecked') {
							 | 
						||
| 
								 | 
							
								      node.setAttribute('data-checked', value === 'checked');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return node;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  static formats(domNode) {
							 | 
						||
| 
								 | 
							
								    if (domNode.tagName === 'OL') return 'ordered';
							 | 
						||
| 
								 | 
							
								    if (domNode.tagName === 'UL') {
							 | 
						||
| 
								 | 
							
								      if (domNode.hasAttribute('data-checked')) {
							 | 
						||
| 
								 | 
							
								        return domNode.getAttribute('data-checked') === 'true' ? 'checked' : 'unchecked';
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        return 'bullet';
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return undefined;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  constructor(domNode) {
							 | 
						||
| 
								 | 
							
								    super(domNode);
							 | 
						||
| 
								 | 
							
								    const listEventHandler = (e) => {
							 | 
						||
| 
								 | 
							
								      if (e.target.parentNode !== domNode) return;
							 | 
						||
| 
								 | 
							
								      let format = this.statics.formats(domNode);
							 | 
						||
| 
								 | 
							
								      let blot = Parchment.find(e.target);
							 | 
						||
| 
								 | 
							
								      if (format === 'checked') {
							 | 
						||
| 
								 | 
							
								        blot.format('list', 'unchecked');
							 | 
						||
| 
								 | 
							
								      } else if(format === 'unchecked') {
							 | 
						||
| 
								 | 
							
								        blot.format('list', 'checked');
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    domNode.addEventListener('touchstart', listEventHandler);
							 | 
						||
| 
								 | 
							
								    domNode.addEventListener('mousedown', listEventHandler);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  format(name, value) {
							 | 
						||
| 
								 | 
							
								    if (this.children.length > 0) {
							 | 
						||
| 
								 | 
							
								      this.children.tail.format(name, value);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  formats() {
							 | 
						||
| 
								 | 
							
								    // We don't inherit from FormatBlot
							 | 
						||
| 
								 | 
							
								    return { [this.statics.blotName]: this.statics.formats(this.domNode) };
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  insertBefore(blot, ref) {
							 | 
						||
| 
								 | 
							
								    if (blot instanceof ListItem) {
							 | 
						||
| 
								 | 
							
								      super.insertBefore(blot, ref);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      let index = ref == null ? this.length() : ref.offset(this);
							 | 
						||
| 
								 | 
							
								      let after = this.split(index);
							 | 
						||
| 
								 | 
							
								      after.parent.insertBefore(blot, after);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  optimize(context) {
							 | 
						||
| 
								 | 
							
								    super.optimize(context);
							 | 
						||
| 
								 | 
							
								    let next = this.next;
							 | 
						||
| 
								 | 
							
								    if (next != null && next.prev === this &&
							 | 
						||
| 
								 | 
							
								        next.statics.blotName === this.statics.blotName &&
							 | 
						||
| 
								 | 
							
								        next.domNode.tagName === this.domNode.tagName &&
							 | 
						||
| 
								 | 
							
								        next.domNode.getAttribute('data-checked') === this.domNode.getAttribute('data-checked')) {
							 | 
						||
| 
								 | 
							
								      next.moveChildren(this);
							 | 
						||
| 
								 | 
							
								      next.remove();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  replace(target) {
							 | 
						||
| 
								 | 
							
								    if (target.statics.blotName !== this.statics.blotName) {
							 | 
						||
| 
								 | 
							
								      let item = Parchment.create(this.statics.defaultChild);
							 | 
						||
| 
								 | 
							
								      target.moveChildren(item);
							 | 
						||
| 
								 | 
							
								      this.appendChild(item);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    super.replace(target);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								List.blotName = 'list';
							 | 
						||
| 
								 | 
							
								List.scope = Parchment.Scope.BLOCK_BLOT;
							 | 
						||
| 
								 | 
							
								List.tagName = ['OL', 'UL'];
							 | 
						||
| 
								 | 
							
								List.defaultChild = 'list-item';
							 | 
						||
| 
								 | 
							
								List.allowedChildren = [ListItem];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export { ListItem, List as default };
							 |