131 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
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 };
 |