/* * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ (function(scope) { // super // `arrayOfArgs` is an optional array of args like one might pass // to `Function.apply` // TODO(sjmiles): // $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 // prototype chain i.e. we use the function object for memoizing) // perhaps we can bookkeep on the prototype itself instead function $super(arrayOfArgs) { // since we are thunking a method call, performance is important here: // memoize all lookups, once memoized the fast path calls no other // functions // // find the caller (cannot be `strict` because of 'caller') var caller = $super.caller; // memoized 'name of method' var nom = caller.nom; // memoized next implementation prototype var _super = caller._super; if (!_super) { if (!nom) { nom = caller.nom = nameInThis.call(this, caller); } 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') // invariant: because we cache _super on fn below, we never reach // here from inside a series of calls to super(), so it's ok to // start searching from the prototype of 'this' (at the 'top') // we must never memoize a null super for this reason _super = memoizeSuper(caller, nom, getPrototypeOf(this)); } // our super function var fn = _super[nom]; if (fn) { // memoize information so 'fn' can call 'super' if (!fn._super) { // must not memoize null, or we lose our invariant above memoizeSuper(fn, nom, _super); } // invoke the inherited method // if 'fn' is not function valued, this will throw return fn.apply(this, arrayOfArgs || []); } } function nameInThis(value) { var p = this.__proto__; while (p && p !== HTMLElement.prototype) { // TODO(sjmiles): getOwnPropertyNames is absurdly expensive var n$ = Object.getOwnPropertyNames(p); for (var i=0, l=n$.length, n; i