mframejs
Version:
simple framework
232 lines • 10.9 kB
JavaScript
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