Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug fixes, more indirection around 'conventions' #32

Merged
merged 4 commits into from
Nov 5, 2012
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 41 additions & 91 deletions src/g-component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@
});
</script>
<script>
// conventional names have implicit bindings
// conventional names for automation
var conventions = {
ATTRIBUTES_ATTRIBUTE: "attributes",
DELEGATES_DIRECTIVE: "bind",
OBSERVE_DIRECTIVE: "observe",
PROPERTY_CHANGED_SUFFIX: "Changed",
CUSTOM_EVENT_PREFIX: "on-"
CUSTOM_EVENT_PREFIX: "on-",
BINDING_OUT_SUFFIX: "Output",
BINDING_IN_SUFFIX: "Input"
};

// polyfill for DOMTokenList features:
Expand Down Expand Up @@ -193,8 +198,9 @@
};

var establishNodeReferences = function(inRoot) {
// establish $ instance variable
this.$ = this.$ || {};
// search the LOCAL tree
// populate $ from nodes with ID from the LOCAL tree
if (inRoot) {
var nodes = ShadowDOM.localQueryAll(inRoot, "[id]");
Array.prototype.forEach.call(nodes, function(n) {
Expand All @@ -215,14 +221,21 @@
if (inDelegates) {
var node = this;
this.modelDelegate = function(inBinding) {
if (inDelegates[inBinding]) {
if (inBinding in inDelegates) {
var dependencies = inDelegates[inBinding] || [inBinding];
if (typeof dependencies == 'string') {
dependencies = [dependencies];
}
//console.log("bindDelegates:", inBinding, dependencies, node);
var inMethod = inBinding + conventions.BINDING_IN_SUFFIX;
var outMethod = inBinding + conventions.BINDING_OUT_SUFFIX;
return [
inDelegates[inBinding],
dependencies,
function(/*inValues*/) {
return delegateBinding(node, inBinding + "Out", arguments);
return delegateBinding(node, outMethod, arguments);
},
function(/*inValues*/) {
return delegateBinding(node, inBinding + "In", arguments);
return delegateBinding(node, inMethod, arguments);
}
];
}
Expand All @@ -231,8 +244,10 @@
};

var delegateBinding = function(inNode, inDelegate, inValues) {
// late binding to named delegate function
var fn = inNode[inDelegate];
var value = fn ? fn.apply(inNode, inValues) : undefined;
// whenever undefined, echo back first input value
if (value === undefined) {
value = inValues[0];
}
Expand All @@ -255,20 +270,6 @@
}
};

/*
var $$ = function(inSlctr) {
var s = this.shadow;
while(s){
var n = s.querySelector(inSlctr);
if (n) {
return n;
}
s = s.olderSubtree;
}
return s;
};
*/

// attribute mutations

var deserializeValue = function(inValue) {
Expand Down Expand Up @@ -349,12 +350,12 @@

// per-instance
var automate = function(inAttributes, inPublished, inDelegates) {
bindAttrs.call(this, inAttributes.attributes);
bindAttrs.call(this, inAttributes[conventions.ATTRIBUTES_ATTRIBUTE]);
// TODO(sjmiles): replace with on-* syntax
bindEvents.call(this, inAttributes.handlers);
bindProperties.call(this, inPublished);
bindDelegates.call(this, inDelegates);
};

};

// fireEvent impl

Expand All @@ -371,7 +372,7 @@
this[inMethod].apply(this, inArgs);
}.bind(this), 0);
};

// decorate HTMLElementElement with toolkit API

HTMLElementElement.prototype.component = function(inUber) {
Expand All @@ -383,7 +384,12 @@
created: function() {
//console.log("created", this);
this.controller = this;
automate.call(this, attributes, inUber.published, inUber.delegates);
automate.call(this,
attributes,
// TODO(sjmiles): remove backward-compatibility expressions
inUber[conventions.OBSERVE_DIRECTIVE] || inUber.published,
inUber[conventions.DELEGATES_DIRECTIVE] || inUber.bindings || inUber.delegates
);
takeAttributes.call(this);
if (inUber.created) {
inUber.created.call(this);
Expand All @@ -399,7 +405,6 @@
p.setPropertySilently = setPropertySilently;
p.fireEvent = fireEvent;
p.asyncMethod = asyncMethod;
//p.$$ = $$;
// install our prototype
this.generatedConstructor.prototype = p;
};
Expand Down Expand Up @@ -460,77 +465,22 @@
macroize: macroize,
findDistributedTarget: findDistributedTarget
};

/*
// code below provides a shim for declarative event handlers
// (aka 'x', as in onclick="x('click')")
// it's only really for evaluating syntax, and not
// a real solution

var nodeIterator = function(inNodes, inFn) {
if (inNodes) {
for (var i=0, n; (n=inNodes[i]); i++) {
var v = inFn(n);
if (v !== undefined) {
return v;
}
}
}
};

var inPublicTree = function(inNodes, inNode) {
return nodeIterator(inNodes, function(n) {
if (inNode == n || inPublicTree(n.lightDOM, inNode)) {
return true;
}
});
};

var findOwner = function(inNode) {
// find the root of the LOCAL tree that contains 'this'
//
// find a parent who is a component
// ask if we are in his LOCAL tree
// repeat
//
var t = inNode.parentNode;
while (t) {
if (t.__upgraded__) {
if (inPublicTree(t.childNodes, inNode)) {
return t;
};
}
t = t.parentNode;
}
};

// experimental event handler for mapping events to component instances
// publish handler globally, make name as small as possible since
// this is ideally an invisible helper API

x = function(inHandler) {
var owner = findOwner(event.currentTarget);
//console.log(inHandler, owner, event);
if (owner && owner[inHandler]) {
owner[inHandler](event);
}
};
*/

// newer experimental event handler

var findController = function(inNode) {
// find the nearest *containing* controller
var n = inNode.parentNode;
while (n) {
if (n.controller) {
return n.controller;
// find the shadow root that contains inNode
var n = inNode.changeling || inNode;
while (n.parentNode && n.tagName !== 'SHADOW-ROOT') {
n = n.parentNode;
if (n.changeling) {
n = n.changeling;
}
n = n.parentNode || n.host;
}
return n.host.controller;
};

_ = function(inHandlerName) {
var _ = function(inHandlerName) {
var controller = findController(event.currentTarget);
//console.log(inHandler, owner, event);
if (controller && controller[inHandlerName]) {
Expand All @@ -547,7 +497,7 @@
var bindCustomEvent = function(inNode, inEventName, inHandler) {
var h = inNode.__athandlers = inNode.__athandlers || {};
if (!h[inEventName]) {
console.log("bindCustomEvent:", inEventName, inHandler, inNode);
//console.log("bindCustomEvent:", inEventName, inHandler, inNode);
h[inEventName] = function() {
_(inHandler);
};
Expand Down