Skip to content

Commit

Permalink
updated design to meet goals and extended test case
Browse files Browse the repository at this point in the history
  • Loading branch information
idibidiart committed Apr 17, 2012
1 parent 75b39ec commit ba77786
Showing 1 changed file with 67 additions and 120 deletions.
187 changes: 67 additions & 120 deletions idom.js
@@ -1,6 +1,6 @@
/*! idi.bidi.dom /*! idi.bidi.dom
* *
* v0.4 * v0.5
* *
* New Way To Interact With The DOM * New Way To Interact With The DOM
* *
Expand All @@ -20,13 +20,13 @@
* *
* This version works in Gecko and Webkit, not tested on IE * This version works in Gecko and Webkit, not tested on IE
* *
* idi.bidi.dom - Anti-Templating Framework For Javascript -- offering a radically * idi.bidi.dom - Anti-Templating Framework For Javascript -- offers a radically
* new way for interfacing to the DOM. In abstract terms, idi.bidi.dom takes the DOM * different way for interfacting with the DOM. In abstract terms, it takes the DOM
* and adds variables, variable memoization, encapsulation, multiple-inheritance and * and adds variables, variable memoization, encapsulation, multiple-inheritance and
* type polymorphism (with the Node Prototype as the user defined type) In logical * type polymorphism (with the Node Prototype as the user defined type) In logical
* terms, idi.bidi.dom offers a list-wise API to create, update, and delete pred- * terms, it offers a list-based API for creating, updating, and deleting predetermined
* determined structures without losing the ability to directly access nested versions * DOM structures with the ability to dynamically nest and directly access other
* of such structures. * predetermined DOM structures at any depth within them.
* *
* Why use it? * Why use it?
* *
Expand All @@ -36,16 +36,16 @@
* How does it work? * How does it work?
* *
* idi.bidi.dom allows the DOM to be decomposed into Nodes each having a * idi.bidi.dom allows the DOM to be decomposed into Nodes each having a
* Node Prototype of which instances (copies, usually with different data) can * Node Prototype of which instances (copies, with the same or entirely different data)
* be created, populated with JSON data, inserted into and deleted from the Node * may be created, populated with JSON data, inserted into --and deleted from-- the Node
* (with the ability to target specific, previously inserted instances of the Node * (with the ability to target specific, previously inserted instances of the Node
* Prototype or all such instances) and where the Node itself can be linked into * Prototype or all such instances), and where each Node can be linked by reference into
* any number of other Nodes. * any number of other Nodes.
* *
* Additionally, idi.bidi.dom allows the cloning of each Node and all the populated * Additionally, idi.bidi.dom allows the cloning of each Node and all the populated
* instances within it (including any Linked Nodes inserted into the Node Prototype and * instances within it (including any Linked Nodes inserted into the host's Node Prototype
* the populated instances of those Linked Nodes) This means that we may re-use the same * and their populated instances) This means that we may re-use the same Node to create
* Node to create any number of differently populated Nodes. * any number of differently populated Nodes.
* *
* Unlike other template-less DOM rendering frameworks, idi.bidi.dom does not attempt * Unlike other template-less DOM rendering frameworks, idi.bidi.dom does not attempt
* to take the place of Javascript itself nor does it add its own boilerplate; it * to take the place of Javascript itself nor does it add its own boilerplate; it
Expand Down Expand Up @@ -87,7 +87,7 @@
* *
* Other available are methods are * Other available are methods are
* *
* .idom$dePopulate([settings]) which can delete certain populated instances of the Node * .idom$delete([settings]) which can delete certain populated instances of the Node
* Prototype or all populated instances * Prototype or all populated instances
* *
* .idom$isPopulated() may be queried before specifying targetInstanceId * .idom$isPopulated() may be queried before specifying targetInstanceId
Expand All @@ -111,7 +111,7 @@
* are attached via different means, like jQuery, will be supported in the future * are attached via different means, like jQuery, will be supported in the future
* *
*********************************************************************************/ *********************************************************************************/

// define the glpbal idom object // define the glpbal idom object
var idom = {}; var idom = {};


Expand Down Expand Up @@ -320,10 +320,10 @@ idom.forEachExec = function(nodelist, str) {


idom.eventHandler = function(event, el, func) { idom.eventHandler = function(event, el, func) {


var elem = el;

function getNodeId() { function getNodeId() {


var elem = el;

while (elem.parentNode) { while (elem.parentNode) {
elem = elem.parentNode; elem = elem.parentNode;
var id = elem.getAttribute('idom-node-id') var id = elem.getAttribute('idom-node-id')
Expand All @@ -334,9 +334,9 @@ idom.eventHandler = function(event, el, func) {
} }


function getInstanceId() { function getInstanceId() {

var elem = el;


var elem = el;

while (elem.parentNode) { while (elem.parentNode) {
elem = elem.parentNode; elem = elem.parentNode;
var id = elem.getAttribute('idom-instance-id') var id = elem.getAttribute('idom-instance-id')
Expand Down Expand Up @@ -571,15 +571,6 @@ Element.prototype.idom$ = Element.prototype.idom$ || function() {
// wildcards and the whole pattern repeating {1,} to see if the element has been wrongly updated // wildcards and the whole pattern repeating {1,} to see if the element has been wrongly updated
// (from outside of idom), i.e. will not match the pattern, which would throw an error // (from outside of idom), i.e. will not match the pattern, which would throw an error


if (!this.children.length) {

var err = new Error;

err.message = "node is missing node prototype";

throw err.message + '\n' + err.stack;
}

var cloneId = arguments[0]; var cloneId = arguments[0];


// assuming simple JSON // assuming simple JSON
Expand Down Expand Up @@ -646,23 +637,14 @@ Element.prototype.idom$ = Element.prototype.idom$ || function() {


} }


if (!this.children || if (!this.children[0] ||
// condition 1: if Node has no populated instances of its Prototype Node // condition 1: if Node has no populated instances of its Prototype Node
this.innerHTML == idomDOM.cache[nid] || this.innerHTML == idomDOM.cache[nid] ||
// condition 2: or settings were not given // condition 2: or settings were not given
!settings || settings == {} || !settings || settings == {} ||
// condition 3: or 'replace all' is assumed (if no target was specified and mode is replace or not specified) // condition 3: or 'replace all' is assumed (if no target was specified and mode is replace or not specified)
(settings && !settings.targetInstanceId && (settings.mode == 'replace' || settings.mode == ''))) { (settings && !settings.targetInstanceId && (settings.mode == 'replace' || settings.mode == ''))) {


if (!this.children) {

var err = new Error;

err.message = "node is missing its node prototype";

throw err.message + '\n' + err.stack;
}

//exception under condition 1 if target is specified //exception under condition 1 if target is specified
if (settings && settings.targetInstanceId) { if (settings && settings.targetInstanceId) {


Expand Down Expand Up @@ -896,16 +878,17 @@ Element.prototype.idom$ = Element.prototype.idom$ || function() {




function setInstanceId(elem) { function setInstanceId(elem) {


elem.setAttribute("idom-instance-id", settings.instanceId)

var parentSel = elem.parentNode.getAttribute("idom-node-id") var parentSel = elem.parentNode.getAttribute("idom-node-id")


var refStart = elem.parentNode.getAttribute("idom-node-id").indexOf('@') var refStart = parentSel.indexOf('@')


if (refStart != -1) { if (refStart != -1) {


elem.setAttribute("idom-instance-id", settings.instanceId + parentSel.substring(refStart)) elem.setAttribute("idom-instance-id", settings.instanceId + parentSel.substring(refStart))
} else {

elem.setAttribute("idom-instance-id", settings.instanceId)
} }


}; };
Expand Down Expand Up @@ -966,38 +949,17 @@ Element.prototype.idom$ = Element.prototype.idom$ || function() {
var el = nestedCommentNodes[n].parentNode.insertBefore(linkedNode.cloneNode(true), nestedCommentNodes[n]); var el = nestedCommentNodes[n].parentNode.insertBefore(linkedNode.cloneNode(true), nestedCommentNodes[n]);


el.parentNode.removeChild(nestedCommentNodes[n]); el.parentNode.removeChild(nestedCommentNodes[n]);

var sel = elem.getAttribute("idom-instance-id")

var refStart = sel.indexOf('@cloned')

// in case of cloned node, re-add clone reference to linked node
if (refStart != -1) {

var refStr = sel.substring(refStart);

for (var n = 0; n < el.children.length || n < 1; n++) {

el.children[n].setAttribute("idom-instance-id", el.children[n].getAttribute("idom-instance-id") + "@linked@" + elem.getAttribute("idom-instance-id") + refStr);

}

el.setAttribute("idom-node-id", el.getAttribute("idom-node-id") + "@linked@" + elem.getAttribute("idom-instance-id") + refStr);

} else {


for (var n = 0; n < el.children.length || n < 1; n++) { for (var n = 0; n < el.children.length || n < 1; n++) {


el.children[n].setAttribute("idom-instance-id", el.children[n].getAttribute("idom-instance-id") + "@linked@" + elem.getAttribute("idom-instance-id")); el.children[n].setAttribute("idom-instance-id", el.children[n].getAttribute("idom-instance-id") + "@linked@" + elem.getAttribute("idom-instance-id"));


} }

el.setAttribute("idom-node-id", el.getAttribute("idom-node-id") + "@linked@" + elem.getAttribute("idom-instance-id"));

}


el.setAttribute("idom-node-id", el.getAttribute("idom-node-id") + "@linked@" + elem.getAttribute("idom-instance-id"));
} }
} }

} else { } else {


return; return;
Expand Down Expand Up @@ -1094,17 +1056,8 @@ Element.prototype.idom$isPopulated = Element.prototype.idom$isPopulated || funct


throw err.message + '\n' + err.stack; throw err.message + '\n' + err.stack;
} }

if (!this.children.length) {

var err = new Error;

err.message = "node is missing node prototype"

throw err.message + '\n' + err.stack;
}


if (this.innerHTML == idomDOM.cache[nid]) { if (this.innerHTML == idomDOM.cache[nid] || !this.children[0]) {


return false; return false;
} }
Expand All @@ -1113,15 +1066,15 @@ Element.prototype.idom$isPopulated = Element.prototype.idom$isPopulated || funct


}; };


// .idom$dePopulate // .idom$delete
// //
// format: document.querySelector('#someNode').idom$delete([settings]) // format: document.querySelector('#someNode').idom$delete([settings])
// settings: {'targetInstanceId': value} // settings: {'targetInstanceId': value}
// //
// targetInstanceId: settingal: for specifying instance(s) of Node Prototype to delete. If null, reset node's innerHTML to Node Prototype // targetInstanceId: settingal: for specifying instance(s) of Node Prototype to delete. If null, reset node's innerHTML to Node Prototype
// //


Element.prototype.idom$dePopulate = Element.prototype.idom$dePopulate || function() { Element.prototype.idom$delete = Element.prototype.idom$delete || function() {


if (!idomDOM.initDone) { if (!idomDOM.initDone) {


Expand All @@ -1143,21 +1096,6 @@ Element.prototype.idom$dePopulate = Element.prototype.idom$dePopulate || functio
throw err.message + '\n' + err.stack; throw err.message + '\n' + err.stack;
} }


if (!this.children.length) {

var err = new Error;

err.message = "node is missing node prototype"

throw err.message + '\n' + err.stack;
}


if (this.innerHTML == idomDOM.cache[nid]) {

// nothing to dePopulate
return;
}


// take settings, assuming simple JSON // take settings, assuming simple JSON
var settings = arguments[0]; var settings = arguments[0];
Expand Down Expand Up @@ -1203,44 +1141,53 @@ Element.prototype.idom$dePopulate = Element.prototype.idom$dePopulate || functio
var targetNodeList = []; var targetNodeList = [];


if (settings.targetInstanceId) { if (settings.targetInstanceId) {

if (this.innerHTML == idomDOM.cache[nid] || !this.children[0]) {

var err = new Error;

err.message = "node has not yet been populated (no matching instance)"

throw err.message + '\n' + err.stack;
}


if (settings.targetInstanceId) { for (var n = 0; n < this.children.length; n++) {


for (var n = 0; n < this.children.length; n++) { if (this.children[n].getAttribute("idom-instance-id") == settings.targetInstanceId) {


if (this.children[n].getAttribute("idom-instance-id") == settings.targetInstanceId) { targetNodeList.push(this.children[n])

targetNodeList.push(this.children[n])
}
} }
}

if (!targetNodeList) {


if (!targetNodeList) { var err = new Error;


var err = new Error; err.message = "Invalid setting: targetInstanceId (" + settings.targetInstanceId + ") does not match" +

"any idom-instance-id in any instance of the Node Prototype of the Node idom$() is invoked on\n" +
err.message = "Invalid setting: targetInstanceId (" + settings.targetInstanceId + ") does not match" + "outerHTML of node:\n" + this.outerHTML;
"any idom-instance-id in any instance of the Node Prototype of the Node idom$() is invoked on\n" +
"outerHTML of node:\n" + this.outerHTML; throw err.message + '\n' + err.stack;

}
throw err.message + '\n' + err.stack;
}

}




for (var n = 0; n < targetNodeList.length; n++) { for (var n = 0; n < targetNodeList.length; n++) {


this.removeChild(targetNodeList[n]); this.removeChild(targetNodeList[n]);
} }


if (!this.children.length) { } else {
this.innerHTML = idomDOM.cache[nid];
} var err = new Error;
}
err.message = "this method only takes targetInstanceId in settings"

throw err.message + '\n' + err.stack;
}


} else { } else {


this.innerHTML = idomDOM.cache[nid]; this.innerHTML = "";
} }
}; };


Expand Down

0 comments on commit ba77786

Please sign in to comment.