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

Merge mdv-syntax branch #168

Merged
merged 5 commits into from
May 30, 2013
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = function(grunt) {
'src/base.js',
'src/bindProperties.js',
'src/bindMDV.js',
'src/polymerSyntaxMDV.js',
'src/attrs.js',
'src/marshal.js',
'src/events.js',
Expand Down
1 change: 1 addition & 0 deletions polymer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var modules = [
'src/base.js',
'src/bindProperties.js',
'src/bindMDV.js',
'src/polymerSyntaxMDV.js',
'src/attrs.js',
'src/marshal.js',
'src/events.js',
Expand Down
39 changes: 35 additions & 4 deletions src/attrs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
var attrProps$ = 'publish';
//var attrProps$ = 'attributeDefaults';

var publishAttributes = function(inElement, inPrototype) {
function publishAttributes(element, prototype) {
publishAttributesAttributes(element, prototype);
publishInstanceAttributes(element, prototype);
}

function publishAttributesAttributes(inElement, inPrototype) {
var published = {};
// merge attribute names from 'attributes' attribute
var attributes = inElement.getAttribute(attributes$);
Expand Down Expand Up @@ -57,7 +62,32 @@
inherited[published$],
published
);
};
}

function publishInstanceAttributes(element, prototype) {
// our suffix prototype chain (prototype is 'own')
var inherited = element.options.prototype, attributes = element.attributes;
var a$ = prototype.instanceAttributes = Object.create(inherited.instanceAttributes || null);
for (var i=0, l=attributes.length, a; (i<l) && (a=attributes[i]); i++) {
switch (a.name) {
case 'name':
case 'extends':
case attributes$:
break;
default:
if (a.name.slice(0, 3) !== 'on-') {
a$[a.name] = a.value;
}
}
}
}

function installInstanceAttributes() {
var a$ = this.instanceAttributes;
Object.keys(a$).forEach(function(name) {
this.setAttribute(name, a$[name]);
}, this);
}

function takeAttributes() {
// for each attribute
Expand All @@ -83,15 +113,15 @@
}
}
}, this);
};
}

// return the published property matching name, or undefined
function propertyForAttribute(name) {
// matchable properties must be published
var properties = Object.keys(this[published$]);
// search for a matchable property
return properties[properties.map(lowerCase).indexOf(name.toLowerCase())];
};
}

var lowerCase = String.prototype.toLowerCase.call.bind(
String.prototype.toLowerCase);
Expand Down Expand Up @@ -131,5 +161,6 @@
Polymer.takeAttributes = takeAttributes;
Polymer.publishAttributes = publishAttributes;
Polymer.propertyForAttribute = propertyForAttribute;
Polymer.installInstanceAttributes = installInstanceAttributes;

})();
9 changes: 7 additions & 2 deletions src/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
},
asyncMethod: function(inMethod, inArgs, inTimeout) {
var args = (inArgs && inArgs.length) ? inArgs : [inArgs];
return window.setTimeout(function() {
var method = function() {
(this[inMethod] || inMethod).apply(this, args);
}.bind(this), inTimeout || 0);
}.bind(this);
if (inTimeout) {
return window.setTimeout(method, inTimeout);
} else {
return requestAnimationFrame(method);
}
},
dispatch: function(inMethodName, inArguments) {
if (this[inMethodName]) {
Expand Down
2 changes: 1 addition & 1 deletion src/bindMDV.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
function bindModel(inRoot) {
log.bind && console.group("[%s] bindModel", this.localName);
// TODO(sjmiles): allow 'this' to supply a 'delegate'
HTMLTemplateElement.bindAllMustachesFrom_(inRoot, this)
HTMLTemplateElement.bindAllMustachesFrom_(inRoot, this, HTMLTemplateElement.syntax.Polymer);
log.bind && console.groupEnd();
}

Expand Down
2 changes: 1 addition & 1 deletion src/bindProperties.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// capture A's value if B's value is null or undefined,
// otherwise use B's value
var v = PathObserver.getValueAtPath(inB, inPath);
if (v == null || v === undefined) {
if (v === null || v === undefined) {
PathObserver.setValueAtPath(inB, inPath, inA[inProperty]);
}
// redefine A's property as an accessor on path in B
Expand Down
8 changes: 5 additions & 3 deletions src/boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ document.write('<meta name="viewport" content="initial-scale=1.0, maximum-scale=

// FOUC prevention tactic
document.write('<!-- injected FOUC prevention -->\n');
document.write('<style>body {opacity: 0;}</style>');
document.write('<style>body {opacity: 0;};</style>');

// done with write
document.write('<!-- end Polymer injections -->\n');

window.addEventListener('WebComponentsReady', function() {
document.body.style.webkitTransition = 'opacity 0.3s';
document.body.style.opacity = 1;
setTimeout(function() {
document.body.style.webkitTransition = 'opacity 0.3s';
document.body.style.opacity = 1;
}, 400);
});

})();
75 changes: 75 additions & 0 deletions src/polymerSyntaxMDV.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
(function(global) {
'use strict';

function Scope() {}

var bindPattern = /([\w\.\$]*)[\s]*as[\s]*([\w]*)/;
var repeatPattern = /([\w]*)[\s]*in[\s]*([\w\.\$]*)/;

function createBindRepeatBinding(model, path, name, node) {
var binding = new CompoundBinding(function(values) {
return values['value'];
});

var scopeName, scopePath;
var match = path.match(repeatPattern);
if (match) {
scopeName = match[1];
scopePath = match[2];
} else {
match = path.match(bindPattern);
if (match) {
scopeName = match[2];
scopePath = match[1];
} else {
return;
}
}

binding.bind('value', model, scopePath);
templateScopeTable.set(node, { model: model, scope: scopeName });
return binding;
}

function createStringIfTruthyBinding(model, className, path) {
var binding = new CompoundBinding(function(values) {
return values['value'] ? className : '';
});

binding.bind('value', model, path);
return binding;
}

var templateScopeTable = new SideTable;

HTMLTemplateElement.syntax['Polymer'] = {
getBinding: function(model, path, name, node) {
if (node.nodeType === Node.ELEMENT_NODE &&
(name === 'bind' || name === 'repeat') &&
node.tagName === 'TEMPLATE') {
return createBindRepeatBinding(model, path, name, node);
}

// {{ string: path }}
var match = path.match(/([\w]+):[\W]*([\w\.\$]*)/);
if (match)
return createStringIfTruthyBinding(model, match[1], match[2]);
},

getInstanceModel: function(template, model) {
var scopeInfo = templateScopeTable.get(template);
if (!scopeInfo)
return model;

var scope;
if (scopeInfo.model) { // instanceof Scope) {
scope = Object.create(scopeInfo.model);
} else {
scope = new Scope();
}

scope[scopeInfo.scope] = model;
return scope;
}
};
})(this);
7 changes: 7 additions & 0 deletions src/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
function staticInstallTemplate(inElement) {
var template = inElement.querySelector('template');
if (template) {
// apply our MDV strategy
// TODO(sjmiles): we have to apply this strategy directly for the root template
// in bindMDV.js, but we also need the attribute here so sub-templates can see it
template.setAttribute('syntax', 'Polymer');
// make a shadow root
var root = this.webkitCreateShadowRoot();
// TODO(sjmiles): must be settable ex post facto
root.applyAuthorStyles = this.applyAuthorStyles;
Expand Down Expand Up @@ -108,6 +113,8 @@
// install property observation side effects
// do this first so we can observe changes during initialization
Polymer.observeProperties.call(this);
// install boilerplate attributes
Polymer.installInstanceAttributes.call(this);
// process input attributes
Polymer.takeAttributes.call(this);
// add host-events...
Expand Down
1 change: 1 addition & 0 deletions src/shimStyling.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ var stylizer = {
stylizer.shimPolyfillDirectives(element.styles, name);
// find styles and apply shimming...
stylizer.applyShimming(stylizer.stylesForElement(element), name);
stylizer.apply();
}
},
// Shim styles to be placed inside a shadowRoot.
Expand Down