proof of concept for components

This commit is contained in:
Leo Horie 2015-01-24 18:09:28 -05:00
parent 028425ca08
commit ad8b581077

View file

@ -237,9 +237,10 @@ var m = (function app(window, undefined) {
var dataAttrKeys = Object.keys(data.attrs) var dataAttrKeys = Object.keys(data.attrs)
var hasKeys = dataAttrKeys.length > ("key" in data.attrs ? 1 : 0) var hasKeys = dataAttrKeys.length > ("key" in data.attrs ? 1 : 0)
//if an element is different enough from the one in cache, recreate it //if an element is different enough from the one in cache, recreate it
if (data.tag != cached.tag || dataAttrKeys.join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) { if (data.tag != cached.tag || dataAttrKeys.join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id || data.attrs.key != cached.attrs.key) {
if (cached.nodes.length) clear(cached.nodes); if (cached.nodes.length) clear(cached.nodes);
if (cached.configContext && typeof cached.configContext.onunload === FUNCTION) cached.configContext.onunload() if (cached.configContext && typeof cached.configContext.onunload === FUNCTION) cached.configContext.onunload()
if (cached.controller && typeof cached.controller.onunload === FUNCTION) cached.controller.onunload({preventDefault: function() {}})
} }
if (type.call(data.tag) != STRING) return; if (type.call(data.tag) != STRING) return;
@ -247,7 +248,15 @@ var m = (function app(window, undefined) {
if (data.attrs.xmlns) namespace = data.attrs.xmlns; if (data.attrs.xmlns) namespace = data.attrs.xmlns;
else if (data.tag === "svg") namespace = "http://www.w3.org/2000/svg"; else if (data.tag === "svg") namespace = "http://www.w3.org/2000/svg";
else if (data.tag === "math") namespace = "http://www.w3.org/1998/Math/MathML"; else if (data.tag === "math") namespace = "http://www.w3.org/1998/Math/MathML";
if (isNew) { if (isNew) {
var module = m.tags[data.tag]
if (module) {
var constructor = module.controller || m.prop()
var controller = new constructor(data)
data = module.view(controller)
}
if (data.attrs.is) node = namespace === undefined ? $document.createElement(data.tag, data.attrs.is) : $document.createElementNS(namespace, data.tag, data.attrs.is); if (data.attrs.is) node = namespace === undefined ? $document.createElement(data.tag, data.attrs.is) : $document.createElementNS(namespace, data.tag, data.attrs.is);
else node = namespace === undefined ? $document.createElement(data.tag) : $document.createElementNS(namespace, data.tag); else node = namespace === undefined ? $document.createElement(data.tag) : $document.createElementNS(namespace, data.tag);
cached = { cached = {
@ -259,6 +268,9 @@ var m = (function app(window, undefined) {
data.children, data.children,
nodes: [node] nodes: [node]
}; };
if (module) cached.controller = controller
if (cached.children && !cached.children.nodes) cached.children.nodes = []; if (cached.children && !cached.children.nodes) cached.children.nodes = [];
//edge case: setting value on <select> doesn't work before children exist, so set it again after children have been created //edge case: setting value on <select> doesn't work before children exist, so set it again after children have been created
if (data.tag === "select" && data.attrs.value) setAttributes(node, data.tag, {value: data.attrs.value}, {}, namespace); if (data.tag === "select" && data.attrs.value) setAttributes(node, data.tag, {value: data.attrs.value}, {}, namespace);
@ -391,6 +403,7 @@ var m = (function app(window, undefined) {
} }
function unload(cached) { function unload(cached) {
if (cached.configContext && typeof cached.configContext.onunload === FUNCTION) cached.configContext.onunload(); if (cached.configContext && typeof cached.configContext.onunload === FUNCTION) cached.configContext.onunload();
if (cached.controller && typeof cached.controller.onunload === FUNCTION) cached.controller.onunload({preventDefault: function() {}});
if (cached.children) { if (cached.children) {
if (type.call(cached.children) === ARRAY) { if (type.call(cached.children) === ARRAY) {
for (var i = 0, child; child = cached.children[i]; i++) unload(child) for (var i = 0, child; child = cached.children[i]; i++) unload(child)
@ -446,6 +459,7 @@ var m = (function app(window, undefined) {
childNodes: [] childNodes: []
}; };
var nodeCache = [], cellCache = {}; var nodeCache = [], cellCache = {};
m.tags = {}
m.render = function(root, cell, forceRecreation) { m.render = function(root, cell, forceRecreation) {
var configs = []; var configs = [];
if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it."); if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it.");
@ -509,7 +523,8 @@ var m = (function app(window, undefined) {
m.startComputation(); m.startComputation();
roots[index] = root; roots[index] = root;
var currentModule = topModule = module = module || {}; var currentModule = topModule = module = module || {};
var controller = new (module.controller || function() {}); var constructor = module.controller || m.prop()
var controller = new constructor;
//controllers may call m.module recursively (via m.route redirects, for example) //controllers may call m.module recursively (via m.route redirects, for example)
//this conditional ensures only the last recursive m.module call is applied //this conditional ensures only the last recursive m.module call is applied
if (currentModule === topModule) { if (currentModule === topModule) {