All files Template.js

97.44% Statements 76/78
86.67% Branches 26/30
100% Functions 12/12
100% Lines 64/64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90    1x     1x   5x   1x   1x   1x   1x   1x   1x   1x 1x 1x 1x 1x 1x 1x 1x 1x     1x     1x         21x 21x 21x 21x 21x         21x 21x 168x           1x 1x 1x 1x 1x 1x 1x         22x   22x 814x 814x   814x     286x   286x 176x 176x 176x 308x 308x 44x   308x 88x 88x
import { ContentNode } from './ContentNode.js';
import { AttributeNode } from './AttributeNode.js';
import { valuePattern, eventPattern, propPattern, startSeparator, endSeparator } from './patterns.js';
 
export class Template {
  constructor(base, location, context) {
    const template = document.createElement('template');
    const content = base.replace(startSeparator, '').replace(endSeparator, '');IEE
    template.innerHTML = content;
    this.node = document.importNode(template.content, true);
    this.parts = new Map();
    this.eventHandlers = [];
    this.location = location;
    this.context = context;
    this._init(base);
  }I
 
  paint() {
    this.location.appendChild(this.node);
  }
 
  update(content) {
    const template = document.createElement('template');
    template.innerHTML = content;
    const newNode = document.importNode(template.content, true);
    const newNodeWalker = document.createTreeWalker(newNode, 133, null, false);
    this._parseUpdates(newNodeWalker);
  }
 
  _parseUpdates(walker) {
    const updatedParts = this._walk(walker, new Map());
    this.parts.forEach((part, index) => part.update(updatedParts.get(index)));
  }
 
  _init(base) {
    const baseTemplate = document.createElement('template');
    baseTemplate.innerHTML = base;
    const baseNode = document.importNode(baseTemplate.content, true);
    const walker = document.createTreeWalker(baseNode, 133, null, false);
    this._walk(walker, this.parts);
    this.node = baseNode;
    this.paint();
  }
 
  _walk(walker, parts) {
    let index = -1;
 
    while (walker.nextNode()) {
      index += 1;
      const { currentNode } = walker;
      switch (currentNode.nodeType) {
      case 1: {
        const { attributes } = currentNode;
        if (attributes.length) {
          const boundAttrs = new Map();
          const boundEvents = new Map();
          for (let i = 0; i < attributes.length; i += 1) {
            const attribute = attributes[i];
            if (attribute.value.match(valuePattern) || attribute.name.match(propPattern)) {
              boundAttrs.set(attribute.name, attribute);
            }
            if (attribute.name.match(eventPattern)) {
              const eventName = attribute.name.substring(1, attribute.name.length - 1);
              boundEvents.set(eventName, attribute.value);
              this.eventHandlers.push({ eventName, currentNode });
            }
          }
          if (boundAttrs.size >= 1 || boundEvents.size >= 1 || this.parts.has(index)) {
            const attrNode = new AttributeNode(currentNode, index, boundAttrs, boundEvents, this.context);
            parts.set(index, attrNode);
            attrNode.cleanUp();
          }
        }
        break;
      }
      case 3: {
        if (currentNode.textContent && currentNode.textContent.match(valuePattern) || this.parts.has(index)) {
          const contentNode = new ContentNode(currentNode, index);
          parts.set(index, contentNode);
          contentNode.cleanUp();
        }
        break;
      }
      }
    }
 
    return parts;
  }
}