UNPKG

mframejs

Version:
232 lines 10.9 kB
import { ContainerElements } from '../container/exported'; import { ContainerAttributes } from '../container/exported'; import { Cache } from '../utils/exported'; import { AttributeController } from './attributeController'; import { ElementController } from './elementController'; import { InterpolateController } from './interpolateController'; import { DOM } from '../utils/exported'; export class View { static parseAndCreateElement(_class, element, bindingContext, templateString, viewController) { const elementController = new ElementController(bindingContext, element, _class, null, templateString, viewController); const controller = elementController.init(); return controller; } static cleanTemplate(template) { const loopNodes = (node) => { for (let n = 0; n < node.childNodes.length; n++) { let child = node.childNodes[n]; if (child.nodeType === 8 || (child.nodeType === 3 && !/\S/.test(child.nodeValue))) { node.removeChild(child); n--; } else if (child.nodeType === 1) { loopNodes(child); } child = null; } }; loopNodes(template); } static createTemplate(markup) { let template; if (!Cache.templateMap.has(markup)) { const container = DOM.document.createElement('div'); container.innerHTML = markup.default || markup; const fragment = container.firstElementChild; if (!fragment.content) { fragment.content = DOM.document.createDocumentFragment(); while (fragment.childNodes[0]) { fragment.content.appendChild(fragment.childNodes[0]); } } template = DOM.document.createElement('mf-template'); View.cleanTemplate(fragment.content); template.appendChild(fragment.content); Cache.templateMap.set(markup, template); } else { template = Cache.templateMap.get(markup); } const x = template.cloneNode(true); template = null; return x; } static attachTemplate(template, toNode, controllers) { const el = []; while (template.firstChild) { el.push(template.firstChild); toNode.appendChild(template.firstChild); } controllers.forEach((x) => { if (x.attached) { x.attached(); } }); return el; } static clearViews(elements, viewController) { if (viewController) { viewController.clearView(); } elements.forEach((el) => { if (el.parentNode) { el.parentNode.removeChild(el); } }); } static parseTemplate(template, bindingContext, viewController) { const templateCache = View.createTemplateCache(template); const controllers = View.parseTemplateCache(template, bindingContext, viewController, templateCache); return controllers; } static parseTemplateCache(template, bindingContext, viewController, cacheX) { const arr = []; const cache = cacheX.slice().reverse(); const loopNodes = function (_node) { for (let n = 0; n < _node.childNodes.length; n++) { const htmlNode = _node.childNodes[n]; const curcach = cache.pop(); curcach.attributes.forEach((attr) => { let controller; let attrNode; switch (attr.type) { case 'controller': attrNode = htmlNode.getAttributeNode(attr.name); controller = new AttributeController(bindingContext, htmlNode, attrNode, attr.container, viewController); arr.push(controller); break; case 'value': attrNode = htmlNode.getAttributeNode(attr.name); controller = new InterpolateController(bindingContext, attrNode, viewController, true); arr.push(controller); break; case 'attribute': attrNode = htmlNode.getAttributeNode(attr.name); controller = new AttributeController(bindingContext, htmlNode, attrNode, attr.container, viewController); arr.push(controller); break; } }); switch (curcach.type) { case 'element': const elementController = new ElementController(bindingContext, htmlNode, null, curcach.container, null, viewController); arr.push(elementController); break; case 'text': const interpolateController = new InterpolateController(bindingContext, htmlNode, viewController, false); arr.push(interpolateController); break; default: if (curcach.gotoChild) { loopNodes(htmlNode); } } } }; const tempTemplate = { childNodes: [template] }; loopNodes(tempTemplate); arr.forEach((instance) => { instance.init(); }); return arr; } static createTemplateCache(template) { const arr = []; const loopNodes = function (_node) { for (let n = 0; n < _node.childNodes.length; n++) { const currentNode = _node.childNodes[n]; const instance = { type: 'blank', attributes: [], container: null, gotoChild: false }; arr.push(instance); let isControllerAttribute = false; if (currentNode.getAttribute) { ['repeat.for', 'if.bind'].forEach((attribute) => { if (!isControllerAttribute) { const attributeNode = currentNode.getAttributeNode(attribute); if (attributeNode) { isControllerAttribute = true; const customAttribute = ContainerAttributes.findAttribute(attributeNode.name); instance.attributes.push({ type: 'controller', name: attribute, container: customAttribute }); } } }); } if (!isControllerAttribute) { const childAttributes = []; const length = currentNode.attributes && currentNode.attributes.length || 0; for (let i = 0; i < length; i++) { childAttributes.push(currentNode.attributes[i]); } for (let i = 0; i < childAttributes.length; i++) { const attributeNode = childAttributes[i]; let customAttribute = ContainerAttributes.findAttribute(attributeNode.name); if (!customAttribute && attributeNode.name) { customAttribute = ContainerAttributes.findAttribute(attributeNode.name.replace('.bind', '')); if (!customAttribute && attributeNode.name) { customAttribute = ContainerAttributes.findAttribute(View.getAttributeExpression(attributeNode.name)); } } if (customAttribute) { instance.attributes.push({ type: 'attribute', name: attributeNode.name, container: customAttribute }); } else { if (attributeNode.value.indexOf('${') !== -1 || attributeNode.value.indexOf('@{') !== -1) { if (attributeNode.name.indexOf('.bind') === -1) { instance.attributes.push({ type: 'value', name: attributeNode.name, container: null }); } } } } } if (!isControllerAttribute) { if (currentNode.nodeType === 1) { const customElement = ContainerElements.findElement(currentNode.localName); if (customElement) { instance.type = 'element'; instance.container = customElement; } else { if (currentNode.childNodes) { instance.gotoChild = true; loopNodes(currentNode); } } } else { if (currentNode.textContent) { if (currentNode.textContent.indexOf('${') !== -1 || currentNode.textContent.indexOf('@{') !== -1) { instance.type = 'text'; } } } } } }; const tempTemplate = { childNodes: [template] }; loopNodes(tempTemplate); return arr; } static getAttributeExpression(stringAttribute) { const atIndex = stringAttribute.indexOf('@') !== -1 ? stringAttribute.indexOf('@') : 0; const dotIndex = stringAttribute.lastIndexOf('.') !== -1 ? stringAttribute.lastIndexOf('.') : stringAttribute.length; const toReplace = stringAttribute.substring(atIndex, dotIndex); return stringAttribute.replace(toReplace, '#VARIABLE#'); } } //# sourceMappingURL=view.js.map