Skip to content

Commit

Permalink
Merge branch 'parser'
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Miles committed Jun 11, 2013
2 parents 4512913 + 2d5f89b commit 26e8b14
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 96 deletions.
2 changes: 1 addition & 1 deletion src/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* @method super
* @param {Array} Array of arguments.
*/
super: $super,
super: Polymer.$super,
/**
* True if this object is a Polymer element.
* @property isPolymerElement
Expand Down
92 changes: 20 additions & 72 deletions src/oop.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,7 @@
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
(function() {
// $class

function $class(inExtends, inProperties) {
// support optional inExtends (rare exception: allow two signatures)
if (arguments.length == 1) {
inProperties = inExtends;
inExtends = null;
}
// make sure we have a `constructor` property one way or another
// it's important to name the method for `super` to work
// the default constructor calls `super`
if (!inProperties || !inProperties.hasOwnProperty('constructor')) {
inProperties.constructor = function() {
this.super();
}
}
// use the supplied constructor or a stock version
var ctor = inProperties.constructor;
// base prototype is either supplied or stock
var basePrototype = inExtends && inExtends.prototype
|| Object.prototype;
// use `extend` primitive to build new prototype
ctor.prototype = extend(basePrototype, inProperties);
// install `super` functionality if needed
if (!('super' in ctor.prototype)) {
ctor.prototype.super = $super;
}
// return newly minted constructor
return ctor;
};

// extend

// return a prototype containing inProperties chained to inBasePrototype
function extend(inBasePrototype, inProperties) {
return Object.create(inBasePrototype,
getPropertyDescriptors(inProperties));
}

// copy property inName from inSource object to inTarget object
function getPropertyDescriptors(inObject) {
var descriptors = {};
for (var n in inObject) {
descriptors[n] = getPropertyDescriptor(inObject, n);
}
return descriptors;
}

function getPropertyDescriptor(inObject, inName) {
return inObject &&
Object.getOwnPropertyDescriptor(inObject, inName) ||
getPropertyDescriptor(Object.getPrototypeOf(inObject), inName);
}

(function(scope) {
// super

// TODO(sjmiles):
Expand All @@ -78,14 +24,12 @@
// find the caller (cannot be `strict` because of 'caller')
var caller = $super.caller;
// memoization for 'name of method'
var nom = caller._nom;
var nom = caller.nom;

This comment has been minimized.

Copy link
@sorvell

This comment has been minimized.

Copy link
@sjmiles

sjmiles Jun 12, 2013

Contributor

that ._nom at line 75 should be nom. I don't see how "remove the clause" is at all good ... ?

This comment has been minimized.

Copy link
@sorvell

sorvell via email Jun 12, 2013

Contributor

This comment has been minimized.

Copy link
@sjmiles

sjmiles Jun 12, 2013

Contributor

I see what you mean. I'm not sure what's best.

Fwiw, I notice from the comment that _super property on a method refers to the super-prototype, not the actual method itself. Seems like that name should be _superPrototype.

if (!nom) {
// once per call chain
nom = caller._nom = nameInThis.call(this, caller);
if (!nom) {
console.warn('called super() on a method not in "this"');
return;
}
nom = nameInThis.call(this, caller);

This comment has been minimized.

Copy link
@sorvell

sorvell Jun 12, 2013

Contributor

So we don't have to do this work again, shouldn't caller.nom be set here as well? (I realize we should almost never get here.)

This comment has been minimized.

Copy link
@sjmiles

sjmiles Jun 12, 2013

Contributor

I think we need to skip the whole 'nom' section if _super exists.

}
if (!nom) {
console.warn('called super() on a method not installed declaratively (has no .nom property)');
}
// super prototype is either cached or we have to find it
// by searching __proto__ (at the 'top')
Expand Down Expand Up @@ -133,20 +77,24 @@
};

function nameInThis(inValue) {
for (var n in this) {
var d = getPropertyDescriptor(this, n);
if (d.value == inValue) {
return n;
console.group('nameInThis');

This comment has been minimized.

Copy link
@sorvell

sorvell Jun 12, 2013

Contributor

remove logging

var p = this;
while (p && p !== HTMLElement.prototype) {
var n$ = Object.getOwnPropertyNames(p);
for (var i=0, l=n$.length, n; i<l && (n=n$[i]); i++) {
console.log(n);
var d = Object.getOwnPropertyDescriptor(p, n);
if (d.value == inValue) {
return n;
}
}
p = Object.getPrototypeOf(p);
}
console.groupEnd('nameInThis');
}

// exports

// `class` is a reserved word
window.$class = $class;
window.extend = extend;
// `super` is a reserved word
window.$super = $super;
scope.$super = $super;

})();
})(Polymer);
54 changes: 33 additions & 21 deletions src/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* license that can be found in the LICENSE file.
*/

(function() {
(function(scope) {

// imports

Expand All @@ -29,29 +29,34 @@
// element chain, which is inefficient and has ramifications for 'super'
// also, we don't yet support intermediate prototypes in calls to
// HTMLElementElement.prototype.register, so we have to use mixin
var prototype = Platform.mixin({}, Polymer.base, inPrototype);
var prototype = Platform.mixin({}, scope.base, inPrototype);
// capture defining element
prototype.elementElement = inElement;
// TODO(sorvell): install a helper method this.resolvePath to aid in
// setting resource paths. e.g.
// this.$.image.src = this.resolvePath('images/foo.png')
// Potentially remove when spec bug is addressed.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
Polymer.addResolvePath(prototype, inElement);
scope.addResolvePath(prototype, inElement);
// install instance method that closes over 'inElement'
prototype.installTemplate = function() {
this.super();
staticInstallTemplate.call(this, inElement);
};
// hint the supercall mechanism
// TODO(sjmiles): make prototype extension api that does this
prototype.installTemplate.nom = 'installTemplate';
// install readyCallback
prototype.readyCallback = readyCallback;
// hint super call engine by tagging methods with names
hintSuper(prototype);
// parse declared on-* delegates into imperative form
Polymer.parseHostEvents(inElement.attributes, prototype);
scope.parseHostEvents(inElement.attributes, prototype);
// parse attribute-attributes
Polymer.publishAttributes(inElement, prototype);
scope.publishAttributes(inElement, prototype);
// install external stylesheets as if they are inline
Polymer.installSheets(inElement);
Polymer.shimStyling(inElement);
scope.installSheets(inElement);
scope.shimStyling(inElement);
// invoke element.register
inElement.register({prototype: prototype});
// logging
Expand Down Expand Up @@ -97,10 +102,10 @@
CustomElements.takeRecords();
// parse and apply MDV bindings
// locate nodes with id and store references to them in this.$ hash
Polymer.marshalNodeReferences.call(this, inRoot);
scope.marshalNodeReferences.call(this, inRoot);
// add local events of interest...
var rootEvents = Polymer.accumulateEvents(inRoot);
Polymer.bindAccumulatedLocalEvents.call(this, inRoot, rootEvents);
var rootEvents = scope.accumulateEvents(inRoot);
scope.bindAccumulatedLocalEvents.call(this, inRoot, rootEvents);
// set up gestures
PointerGestures.register(inRoot);
PointerEventsPolyfill.setTouchAction(inRoot,
Expand All @@ -110,20 +115,29 @@
function instanceReady(inElement) {
// install property observation side effects
// do this first so we can observe changes during initialization
Polymer.observeProperties.call(this);
scope.observeProperties.call(this);
// install boilerplate attributes
Polymer.installInstanceAttributes.call(this);
scope.installInstanceAttributes.call(this);
// process input attributes
Polymer.takeAttributes.call(this);
scope.takeAttributes.call(this);
// add host-events...
var hostEvents = Polymer.accumulateHostEvents.call(this);
Polymer.bindAccumulatedHostEvents.call(this, hostEvents);
var hostEvents = scope.accumulateHostEvents.call(this);
scope.bindAccumulatedHostEvents.call(this, hostEvents);
// invoke user 'ready'
if (this.ready) {
this.ready();
}
};

function hintSuper(prototype) {
Object.getOwnPropertyNames(prototype).forEach(function(n) {
var d = Object.getOwnPropertyDescriptor(prototype, n);
if (typeof d.value == 'function') {
d.value.nom = n;
}
});
}

// user utility

function findDistributedTarget(inTarget, inNodes) {
Expand All @@ -141,10 +155,8 @@

// exports

window.Polymer = {
register: register,
findDistributedTarget: findDistributedTarget,
instanceReady: instanceReady
};
scope.register = register;
scope.findDistributedTarget = findDistributedTarget;
scope.instanceReady = instanceReady;

})();
})(Polymer);
14 changes: 12 additions & 2 deletions test/js/oop.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
suite('oop', function() {
var assert = chai.assert;

/*
test('extend', function() {
var Base = function() {};
Base.prototype = {
Expand All @@ -22,11 +23,12 @@ suite('oop', function() {
subSub.sayHello();
assert(subSub.value, 'hello');
});

*/

test('super', function() {
var Base = function() {};
Base.prototype = {
super: $super,
super: Polymer.$super,
msg: '',
log: function(inMsg) {
this.msg += inMsg;
Expand All @@ -35,23 +37,29 @@ suite('oop', function() {
this.log('base');
}
};
//
var Sub = function() {};
Sub.prototype = Object.create(Base.prototype);
Sub.prototype.say = function() {
this.super();
this.log(' sub');
};
Sub.prototype.say.nom = 'say';
//
var SubSub = function() {};
SubSub.prototype = Object.create(Sub.prototype);
SubSub.prototype.say = function() {
this.super();
this.log(' subsub');
};
SubSub.prototype.say.nom = 'say';
//
var subSub = new SubSub();
subSub.say();
assert.equal(subSub.msg, 'base sub subsub');
});

/*
test('class', function() {
var Base = $class({
constructor: function() {
Expand Down Expand Up @@ -92,4 +100,6 @@ suite('oop', function() {
subSub.sayGoodbye();
assert(subSub.value, 'goodbye');
});
*/

});

0 comments on commit 26e8b14

Please sign in to comment.