diff --git a/src/declaration/prototype.js b/src/declaration/prototype.js index 8d5b4e7..6840637 100644 --- a/src/declaration/prototype.js +++ b/src/declaration/prototype.js @@ -130,18 +130,39 @@ }, // install Polymer instance api into prototype chain, as needed ensureBaseApi: function(prototype) { - if (!prototype.PolymerBase) { - prototype = Object.create(prototype); - // we need a unique copy of base api for each base prototype - // therefore we 'extend' here instead of simply chaining - // we could memoize instead, especially for the common cases, - // in particular, for base === HTMLElement.prototype - for (var n in api.instance) { - extend(prototype, api.instance[n]); - } + if (prototype.PolymerBase) { + return prototype; } + var extended = Object.create(prototype); + // we need a unique copy of base api for each base prototype + // therefore we 'extend' here instead of simply chaining + // we could memoize instead, especially for the common cases, + // in particular, for base === HTMLElement.prototype + for (var n in api.instance) { + extend(extended, api.instance[n]); + } + // TODO(sjmiles): sharing methods across prototype chains is + // not supported by our 'super' implementation which optimizes + // by memoizing prototype relationships. + // Probably we should have a version of 'extend' that is + // share-aware: it could study the text of each function, + // look for usage of 'super', and wrap those functions in + // closures. + // As of now, there is only one problematic method, so + // we just patch it manually. + this.mixinMethod(extended, prototype, api.instance.mdv, 'bind'); // return buffed-up prototype - return prototype; + return extended; + }, + mixinMethod: function(extended, prototype, api, name) { + var $super = function(args) { + prototype[name].apply(this, args); + }; + extended[name] = function() { + this.super = $super; + api[name].apply(this, arguments); + this.super = extended.super; + } }, // ensure prototype[name] inherits from a prototype.prototype[name] inheritObject: function(name, prototype, base) { diff --git a/src/instance/utils.js b/src/instance/utils.js index a735d13..617ea5e 100644 --- a/src/instance/utils.js +++ b/src/instance/utils.js @@ -71,6 +71,11 @@ } }; + // no-operation function for handy stubs + var nop = function() {}; + // null-object for handy stubs + var nob = {}; + // deprecated utils.asyncMethod = utils.async; @@ -78,5 +83,7 @@ // exports scope.api.instance.utils = utils; + scope.nop = nop; + scope.nob = nob; })(Polymer); diff --git a/src/lib/super.js b/src/lib/super.js index 49d3c94..c5bc60e 100644 --- a/src/lib/super.js +++ b/src/lib/super.js @@ -13,7 +13,7 @@ // $super must be installed on an instance or prototype chain // as `super`, and invoked via `this`, e.g. // `this.super();` - + // will not work if function objects are not unique, for example, // when using mixins. // The memoization strategy assumes each function exists on only one