<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var api = scope.api;
  var isBase = scope.isBase;
  var extend = scope.extend;

  // prototype api

  var prototype = {
    register: function(name, extendee) {
      // build prototype combining extendee, Polymer base, and named api
      this.prototype = this.buildPrototype(name, extendee);
      // back reference declaration element
      // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
      this.prototype.element = this;
      // more declarative features
      this.desugar(name, extendee);
      // register our custom element with the platform
      this.registerPrototype(name, extendee);
      // reference constructor in a global named by 'constructor' attribute
      this.publishConstructor();
    },
    buildPrototype: function(name, extendee) {
      // get our custom prototype (before chaining)
      var prototype = scope.getRegisteredPrototype(name);
      // get basal prototype
      var base = this.generateBasePrototype(extendee);
      // transcribe `attributes` declarations onto own prototype's `publish`
      this.publishAttributes(prototype, base);
      // `publish` properties to the prototype and to attribute watch
      this.publishProperties(prototype, base);
      // infer observers for `observe` list based on method names
      this.inferObservers(prototype);
      // desugar compound observer syntax, e.g. 'a b c'
      this.explodeObservers(prototype);
      // chain various meta-data objects to inherited versions
      this.inheritMetaData(prototype, base);
      // chain custom api to inherited
      prototype = this.chainObject(prototype, base);
      // build side-chained lists to optimize iterations
      this.optimizePropertyMaps(prototype);
      // x-platform fixup
      ensurePrototypeTraversal(prototype);
      return prototype;
    },
    inheritMetaData: function(prototype, base) {
      // chain observe object to inherited
      this.inheritObject('observe', prototype, base);
      // chain publish object to inherited
      this.inheritObject('publish', prototype, base);
      // chain our lower-cased publish map to the inherited version
      this.inheritObject('_publishLC', prototype, base);
      // chain our instance attributes map to the inherited version
      this.inheritObject('_instanceAttributes', prototype, base);
      // chain our event delegates map to the inherited version
      this.inheritObject('eventDelegates', prototype, base);
    },
    // implement various declarative features
    desugar: function(name, extendee) {
      // install external stylesheets as if they are inline
      this.installSheets();
      // adjust any paths in dom from imports
      this.resolveElementPaths(this);
      // compile list of attributes to copy to instances
      this.accumulateInstanceAttributes();
      // parse on-* delegates declared on `this` element
      this.parseHostEvents();
      //
      // install a helper method this.resolvePath to aid in
      // setting resource urls. e.g.
      // this.$.image.src = this.resolvePath('images/foo.png')
      this.addResolvePathApi();
      // under ShadowDOMPolyfill, transforms to approximate missing CSS features
      if (window.ShadowDOMPolyfill) {
        Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);
      }
      // allow custom element access to the declarative context
      if (this.prototype.registerCallback) {
        this.prototype.registerCallback(this);
      }
    },
    // if a named constructor is requested in element, map a reference
    // to the constructor to the given symbol
    publishConstructor: function() {
      var symbol = this.getAttribute('constructor');
      if (symbol) {
        window[symbol] = this.ctor;
      }
    },
    // build prototype combining extendee, Polymer base, and named api
    generateBasePrototype: function(extnds) {
      var prototype = this.findBasePrototype(extnds);
      if (!prototype) {
        // create a prototype based on tag-name extension
        var prototype = HTMLElement.getPrototypeForTag(extnds);
        // insert base api in inheritance chain (if needed)
        prototype = this.ensureBaseApi(prototype);
        // memoize this base
        memoizedBases[extnds] = prototype;
      }
      return prototype;
    },
    findBasePrototype: function(name) {
      return memoizedBases[name];
    },
    // install Polymer instance api into prototype chain, as needed
    ensureBaseApi: function(prototype) {
      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.
      // To avoid re-entrancy problems, the special super method
      // installed is called `mixinSuper` and the mixin method
      // must use this method instead of the default `super`.
      this.mixinMethod(extended, prototype, api.instance.mdv, 'bind');
      // return buffed-up prototype
      return extended;
    },
    mixinMethod: function(extended, prototype, api, name) {
      var $super = function(args) {
        return prototype[name].apply(this, args);
      };
      extended[name] = function() {
        this.mixinSuper = $super;
        return api[name].apply(this, arguments);
      }
    },
    // ensure prototype[name] inherits from a prototype.prototype[name]
    inheritObject: function(name, prototype, base) {
      // require an object
      var source = prototype[name] || {};
      // chain inherited properties onto a new object
      prototype[name] = this.chainObject(source, base[name]);
    },
    // register 'prototype' to custom element 'name', store constructor
    registerPrototype: function(name, extendee) {
      var info = {
        prototype: this.prototype
      }
      // native element must be specified in extends
      var typeExtension = this.findTypeExtension(extendee);
      if (typeExtension) {
        info.extends = typeExtension;
      }
      // register the custom type
      this.ctor = document.registerElement(name, info);
      // constructor shenanigans
      this.prototype.constructor = this.ctor;
      // register the prototype with HTMLElement for name lookup
      HTMLElement.register(name, this.prototype);
    },
    findTypeExtension: function(name) {
      if (name && name.indexOf('-') < 0) {
        return name;
      } else {
        var p = this.findBasePrototype(name);
        if (p.element) {
          return this.findTypeExtension(p.element.extends);
        }
      }
    }
  };

  // implementation of 'chainObject' depends on support for __proto__
  if (Object.__proto__) {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        object.__proto__ = inherited;
      }
      return object;
    }
  } else {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        var chained = Object.create(inherited);
        object = extend(chained, object);
      }
      return object;
    }
  }

  // memoize base prototypes
  memoizedBases = {};

  // On platforms that do not support __proto__ (version of IE), the prototype
  // chain of a custom element is simulated via installation of __proto__.
  // Although custom elements manages this, we install it here so it's
  // available during desugaring.
  function ensurePrototypeTraversal(prototype) {
    if (!Object.__proto__) {
      var ancestor = Object.getPrototypeOf(prototype);
      prototype.__proto__ = ancestor;
      if (isBase(ancestor)) {
        ancestor.__proto__ = Object.getPrototypeOf(ancestor);
      }
    }
  }

  // exports

  api.declaration.prototype = prototype;

})(Polymer);
<commit_msg>refactoring for clarity<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var api = scope.api;
  var isBase = scope.isBase;
  var extend = scope.extend;

  // prototype api

  var prototype = {

    register: function(name, extendeeName) {
      // build prototype combining extendee, Polymer base, and named api
      this.buildPrototype(name, extendeeName);
      // register our custom element with the platform
      this.registerPrototype(name, extendeeName);
      // reference constructor in a global named by 'constructor' attribute
      this.publishConstructor();
    },

    buildPrototype: function(name, extendeeName) {
      // get our custom prototype (before chaining)
      var extension = scope.getRegisteredPrototype(name);
      if (typeof extension === 'function') {
        extension = withDependencies(extension, extension.dependencies);
      }
      // get basal prototype
      var base = this.generateBasePrototype(extendeeName);
      // implement declarative features
      this.desugarBeforeChaining(extension, base);
      // join prototypes
      this.prototype = this.chainPrototypes(extension, base);
      // more declarative features
      this.desugarAfterChaining(name, extendeeName);
    },

    desugarBeforeChaining: function(prototype, base) {
      // back reference declaration element
      // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
      prototype.element = this;
      // transcribe `attributes` declarations onto own prototype's `publish`
      this.publishAttributes(prototype, base);
      // `publish` properties to the prototype and to attribute watch
      this.publishProperties(prototype, base);
      // infer observers for `observe` list based on method names
      this.inferObservers(prototype);
      // desugar compound observer syntax, e.g. 'a b c'
      this.explodeObservers(prototype);
    },

    chainPrototypes: function(prototype, base) {
      // chain various meta-data objects to inherited versions
      this.inheritMetaData(prototype, base);
      // chain custom api to inherited
      var chained = this.chainObject(prototype, base);
      // x-platform fixup
      ensurePrototypeTraversal(chained);
      return chained;
    },

    inheritMetaData: function(prototype, base) {
      // chain observe object to inherited
      this.inheritObject('observe', prototype, base);
      // chain publish object to inherited
      this.inheritObject('publish', prototype, base);
      // chain our lower-cased publish map to the inherited version
      this.inheritObject('_publishLC', prototype, base);
      // chain our instance attributes map to the inherited version
      this.inheritObject('_instanceAttributes', prototype, base);
      // chain our event delegates map to the inherited version
      this.inheritObject('eventDelegates', prototype, base);
    },

    // implement various declarative features
    desugarAfterChaining: function(name, extendee) {
      // build side-chained lists to optimize iterations
      this.optimizePropertyMaps(this.prototype);
      // install external stylesheets as if they are inline
      this.installSheets();
      // adjust any paths in dom from imports
      this.resolveElementPaths(this);
      // compile list of attributes to copy to instances
      this.accumulateInstanceAttributes();
      // parse on-* delegates declared on `this` element
      this.parseHostEvents();
      //
      // install a helper method this.resolvePath to aid in
      // setting resource urls. e.g.
      // this.$.image.src = this.resolvePath('images/foo.png')
      this.addResolvePathApi();
      // under ShadowDOMPolyfill, transforms to approximate missing CSS features
      if (window.ShadowDOMPolyfill) {
        Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);
      }
      // allow custom element access to the declarative context
      if (this.prototype.registerCallback) {
        this.prototype.registerCallback(this);
      }
    },

    // if a named constructor is requested in element, map a reference
    // to the constructor to the given symbol
    publishConstructor: function() {
      var symbol = this.getAttribute('constructor');
      if (symbol) {
        window[symbol] = this.ctor;
      }
    },

    // build prototype combining extendee, Polymer base, and named api
    generateBasePrototype: function(extnds) {
      var prototype = this.findBasePrototype(extnds);
      if (!prototype) {
        // create a prototype based on tag-name extension
        var prototype = HTMLElement.getPrototypeForTag(extnds);
        // insert base api in inheritance chain (if needed)
        prototype = this.ensureBaseApi(prototype);
        // memoize this base
        memoizedBases[extnds] = prototype;
      }
      return prototype;
    },

    findBasePrototype: function(name) {
      return memoizedBases[name];
    },

    // install Polymer instance api into prototype chain, as needed
    ensureBaseApi: function(prototype) {
      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
      api.publish(api.instance, extended);
      // TODO(sjmiles): sharing methods across prototype chains is
      // not supported by '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.
      // To avoid re-entrancy problems, the special super method
      // installed is called `mixinSuper` and the mixin method
      // must use this method instead of the default `super`.
      this.mixinMethod(extended, prototype, api.instance.mdv, 'bind');
      // return buffed-up prototype
      return extended;
    },

    mixinMethod: function(extended, prototype, api, name) {
      var $super = function(args) {
        return prototype[name].apply(this, args);
      };
      extended[name] = function() {
        this.mixinSuper = $super;
        return api[name].apply(this, arguments);
      }
    },

    // ensure prototype[name] inherits from a prototype.prototype[name]
    inheritObject: function(name, prototype, base) {
      // require an object
      var source = prototype[name] || {};
      // chain inherited properties onto a new object
      prototype[name] = this.chainObject(source, base[name]);
    },

    // register 'prototype' to custom element 'name', store constructor
    registerPrototype: function(name, extendee) {
      var info = {
        prototype: this.prototype
      }
      // native element must be specified in extends
      var typeExtension = this.findTypeExtension(extendee);
      if (typeExtension) {
        info.extends = typeExtension;
      }
      // register the prototype with HTMLElement for name lookup
      HTMLElement.register(name, this.prototype);
      // register the custom type
      this.ctor = document.registerElement(name, info);
      // constructor shenanigans
      this.prototype.constructor = this.ctor;
    },

    findTypeExtension: function(name) {
      if (name && name.indexOf('-') < 0) {
        return name;
      } else {
        var p = this.findBasePrototype(name);
        if (p.element) {
          return this.findTypeExtension(p.element.extends);
        }
      }
    }

  };

  // memoize base prototypes
  var memoizedBases = {};

  // implementation of 'chainObject' depends on support for __proto__
  if (Object.__proto__) {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        object.__proto__ = inherited;
      }
      return object;
    }
  } else {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        var chained = Object.create(inherited);
        object = extend(chained, object);
      }
      return object;
    }
  }

  // On platforms that do not support __proto__ (versions of IE), the prototype
  // chain of a custom element is simulated via installation of __proto__.
  // Although custom elements manages this, we install it here so it's
  // available during desugaring.
  function ensurePrototypeTraversal(prototype) {
    if (!Object.__proto__) {
      var ancestor = Object.getPrototypeOf(prototype);
      prototype.__proto__ = ancestor;
      if (isBase(ancestor)) {
        ancestor.__proto__ = Object.getPrototypeOf(ancestor);
      }
    }
  }

  // exports

  api.declaration.prototype = prototype;

})(Polymer);
<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var api = scope.api;
  var isBase = scope.isBase;
  var extend = scope.extend;

  // prototype api

  var prototype = {
    register: function(name, extendee) {
      // build prototype combining extendee, Polymer base, and named api
      this.prototype = this.buildPrototype(name, extendee);
      // back reference declaration element
      // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
      this.prototype.element = this;
      // more declarative features
      this.desugar(name, extendee);
      // register our custom element with the platform
      this.registerPrototype(name, extendee);
      // reference constructor in a global named by 'constructor' attribute
      this.publishConstructor();
    },
    buildPrototype: function(name, extendee) {
      // get our custom prototype (before chaining)
      var prototype = scope.getRegisteredPrototype(name);
      // get basal prototype
      var base = this.generateBasePrototype(extendee);
      // transcribe `attributes` declarations onto own prototype's `publish`
      this.publishAttributes(prototype, base);
      // `publish` properties to the prototype and to attribute watch
      this.publishProperties(prototype, base);
      // infer observers for `observe` list based on method names
      this.inferObservers(prototype);
      // chain various meta-data objects to inherited versions
      this.inheritMetaData(prototype, base);
      // chain custom api to inherited
      prototype = this.chainObject(prototype, base);
      // build side-chained lists to optimize iterations
      this.optimizePropertyMaps(prototype);
      // x-platform fixup
      ensurePrototypeTraversal(prototype);
      return prototype;
    },
    inheritMetaData: function(prototype, base) {
      // chain observe object to inherited
      this.inheritObject('observe', prototype, base);
      // chain publish object to inherited
      this.inheritObject('publish', prototype, base);
      // chain our lower-cased publish map to the inherited version
      this.inheritObject('_publishLC', prototype, base);
      // chain our instance attributes map to the inherited version
      this.inheritObject('_instanceAttributes', prototype, base);
      // chain our event delegates map to the inherited version
      this.inheritObject('eventDelegates', prototype, base);
    },
    // implement various declarative features
    desugar: function(name, extendee) {
      // compile list of attributes to copy to instances
      this.accumulateInstanceAttributes();
      // parse on-* delegates declared on `this` element
      this.parseHostEvents();
      // install external stylesheets as if they are inline
      this.installSheets();
      // 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
      this.addResolvePathApi();
      // under ShadowDOMPolyfill, transforms to approximate missing CSS features
      if (window.ShadowDOMPolyfill) {
        Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);
      }
      // allow custom element access to the declarative context
      if (this.prototype.registerCallback) {
        this.prototype.registerCallback(this);
      }
    },
    // if a named constructor is requested in element, map a reference
    // to the constructor to the given symbol
    publishConstructor: function() {
      var symbol = this.getAttribute('constructor');
      if (symbol) {
        window[symbol] = this.ctor;
      }
    },
    // build prototype combining extendee, Polymer base, and named api
    generateBasePrototype: function(extnds) {
      var prototype = memoizedBases[extnds];
      if (!prototype) {
        // create a prototype based on tag-name extension
        var prototype = HTMLElement.getPrototypeForTag(extnds);
        // insert base api in inheritance chain (if needed)
        prototype = this.ensureBaseApi(prototype);
        // memoize this base
        memoizedBases[extnds] = prototype;
      }
      return prototype;
    },
    // 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]);
       }
      }
      // return buffed-up prototype
      return prototype;
    },
    // ensure prototype[name] inherits from a prototype.prototype[name]
    inheritObject: function(name, prototype, base) {
      // require an object
      var source = prototype[name] || {};
      // chain inherited properties onto a new object
      prototype[name] = this.chainObject(source, base[name]);
    },
    // register 'prototype' to custom element 'name', store constructor
    registerPrototype: function(name, extendee) {
      var info = {
        prototype: this.prototype
      }
      // native element must be specified in extends
      if (extendee && extendee.indexOf('-') < 0) {
        info.extends = extendee;
      }
      // register the custom type
      this.ctor = document.register(name, info);
      // constructor shenanigans
      this.prototype.constructor = this.ctor;
      // register the prototype with HTMLElement for name lookup
      HTMLElement.register(name, this.prototype);
    }
  };

  if (Object.__proto__) {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        object.__proto__ = inherited;
      }
      return object;
    }
  } else {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        var chained = Object.create(inherited);
        object = extend(chained, object);
      }
      return object;
    }
  }

  // memoize base prototypes
  memoizedBases = {};

  // On platforms that do not support __proto__ (version of IE), the prototype
  // chain of a custom element is simulated via installation of __proto__.
  // Although custom elements manages this, we install it here so it's
  // available during desugaring.
  function ensurePrototypeTraversal(prototype) {
    if (!Object.__proto__) {
      var ancestor = Object.getPrototypeOf(prototype);
      prototype.__proto__ = ancestor;
      if (isBase(ancestor)) {
        ancestor.__proto__ = Object.getPrototypeOf(ancestor);
      }
    }
  }

  // exports

  api.declaration.prototype = prototype;

})(Polymer);
<commit_msg>automatically convert <shadow></shadow> to <shadow><content></content></shadow> See spec bug for discussion: https://www.w3.org/Bugs/Public/show_bug.cgi?id=22460<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var api = scope.api;
  var isBase = scope.isBase;
  var extend = scope.extend;

  // prototype api

  var prototype = {
    register: function(name, extendee) {
      // build prototype combining extendee, Polymer base, and named api
      this.prototype = this.buildPrototype(name, extendee);
      // back reference declaration element
      // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
      this.prototype.element = this;
      // more declarative features
      this.desugar(name, extendee);
      // register our custom element with the platform
      this.registerPrototype(name, extendee);
      // reference constructor in a global named by 'constructor' attribute
      this.publishConstructor();
    },
    buildPrototype: function(name, extendee) {
      // get our custom prototype (before chaining)
      var prototype = scope.getRegisteredPrototype(name);
      // get basal prototype
      var base = this.generateBasePrototype(extendee);
      // transcribe `attributes` declarations onto own prototype's `publish`
      this.publishAttributes(prototype, base);
      // `publish` properties to the prototype and to attribute watch
      this.publishProperties(prototype, base);
      // infer observers for `observe` list based on method names
      this.inferObservers(prototype);
      // chain various meta-data objects to inherited versions
      this.inheritMetaData(prototype, base);
      // chain custom api to inherited
      prototype = this.chainObject(prototype, base);
      // build side-chained lists to optimize iterations
      this.optimizePropertyMaps(prototype);
      // x-platform fixup
      ensurePrototypeTraversal(prototype);
      return prototype;
    },
    inheritMetaData: function(prototype, base) {
      // chain observe object to inherited
      this.inheritObject('observe', prototype, base);
      // chain publish object to inherited
      this.inheritObject('publish', prototype, base);
      // chain our lower-cased publish map to the inherited version
      this.inheritObject('_publishLC', prototype, base);
      // chain our instance attributes map to the inherited version
      this.inheritObject('_instanceAttributes', prototype, base);
      // chain our event delegates map to the inherited version
      this.inheritObject('eventDelegates', prototype, base);
    },
    // implement various declarative features
    desugar: function(name, extendee) {
      // compile list of attributes to copy to instances
      this.accumulateInstanceAttributes();
      // parse on-* delegates declared on `this` element
      this.parseHostEvents();
      // install external stylesheets as if they are inline
      this.installSheets();
      //
      this.adjustShadowElement();
      //
      // 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
      this.addResolvePathApi();
      // under ShadowDOMPolyfill, transforms to approximate missing CSS features
      if (window.ShadowDOMPolyfill) {
        Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);
      }
      // allow custom element access to the declarative context
      if (this.prototype.registerCallback) {
        this.prototype.registerCallback(this);
      }
    },
    // TODO(sorvell): remove when spec addressed:
    // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22460
    // make <shadow></shadow> be <shadow><content></content></shadow>
    adjustShadowElement: function() {
      var content = this.templateContent();
      if (content) {
        var s$ = content.querySelectorAll('shadow');
        for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) {
          if (!s.children.length) {
            s.appendChild(document.createElement('content'));
          }
        }
      }
    },
    // if a named constructor is requested in element, map a reference
    // to the constructor to the given symbol
    publishConstructor: function() {
      var symbol = this.getAttribute('constructor');
      if (symbol) {
        window[symbol] = this.ctor;
      }
    },
    // build prototype combining extendee, Polymer base, and named api
    generateBasePrototype: function(extnds) {
      var prototype = memoizedBases[extnds];
      if (!prototype) {
        // create a prototype based on tag-name extension
        var prototype = HTMLElement.getPrototypeForTag(extnds);
        // insert base api in inheritance chain (if needed)
        prototype = this.ensureBaseApi(prototype);
        // memoize this base
        memoizedBases[extnds] = prototype;
      }
      return prototype;
    },
    // 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]);
       }
      }
      // return buffed-up prototype
      return prototype;
    },
    // ensure prototype[name] inherits from a prototype.prototype[name]
    inheritObject: function(name, prototype, base) {
      // require an object
      var source = prototype[name] || {};
      // chain inherited properties onto a new object
      prototype[name] = this.chainObject(source, base[name]);
    },
    // register 'prototype' to custom element 'name', store constructor
    registerPrototype: function(name, extendee) {
      var info = {
        prototype: this.prototype
      }
      // native element must be specified in extends
      if (extendee && extendee.indexOf('-') < 0) {
        info.extends = extendee;
      }
      // register the custom type
      this.ctor = document.register(name, info);
      // constructor shenanigans
      this.prototype.constructor = this.ctor;
      // register the prototype with HTMLElement for name lookup
      HTMLElement.register(name, this.prototype);
    }
  };

  if (Object.__proto__) {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        object.__proto__ = inherited;
      }
      return object;
    }
  } else {
    prototype.chainObject = function(object, inherited) {
      if (object && inherited && object !== inherited) {
        var chained = Object.create(inherited);
        object = extend(chained, object);
      }
      return object;
    }
  }

  // memoize base prototypes
  memoizedBases = {};

  // On platforms that do not support __proto__ (version of IE), the prototype
  // chain of a custom element is simulated via installation of __proto__.
  // Although custom elements manages this, we install it here so it's
  // available during desugaring.
  function ensurePrototypeTraversal(prototype) {
    if (!Object.__proto__) {
      var ancestor = Object.getPrototypeOf(prototype);
      prototype.__proto__ = ancestor;
      if (isBase(ancestor)) {
        ancestor.__proto__ = Object.getPrototypeOf(ancestor);
      }
    }
  }

  // exports

  api.declaration.prototype = prototype;

})(Polymer);
<|endoftext|>


<commit_before>/* jshint maxparams: 7, -W003, -W030, -W110, -W101 */
/* global R, chai, describe, it, mocha, document, window */

'use strict';

var expect = chai.expect,
    F = {};

// could not try out jscheck here, need a proper cdn
// https://raw.githubusercontent.com/douglascrockford/JSCheck/master/jscheck.js

function start () {
    mocha.setup('bdd');
    defineCode();
    defineSuite();
    mocha.run();
}

function defineSuite() {
    describe('xrayScan summarize inheritance for an object', function () {
        describe('xrayDepth :: a → Number', function () {

            // Cool, curry a test case so we can cut out a lot of noise when testing
            var xrayDepth = R.curry(function (testIt, depth, name, value) {
                testIt('should be ' + depth + ' for ' + name, function () {
                    expect(F.xrayDepth(value)).to.be.equal(depth);
                });
            });

            describe('zero', function () {
                var check = xrayDepth(it, 0);

                check('null', null);
                check('undefined', void 0);
            });
            describe('one', function () {
                var check = xrayDepth(it, 1);

                check('Object.prototype', Object.prototype);
            });
            describe('two', function () {
                var check = xrayDepth(it, 2);

                check('{}', {});

                check('Boolean.prototype', Boolean.prototype);
                check('Number.prototype', Number.prototype);
                check('String.prototype', String.prototype);
                check('Function.prototype', Function.prototype);
                check('Array.prototype', Array.prototype);
                check('RegExp.prototype', RegExp.prototype);
                check('Error.prototype', Error.prototype);

            });
            describe('three', function () {
                var check = xrayDepth(it, 3),
                    obj = {name: 'fred', ref: ['referenced']};

                Object.setPrototypeOf(obj, { girth: 'huge' });

                check('[]', []);
                check('true', true);
                check('42', 42);
                check('NaN', NaN);
                check('Infinity', Infinity);
                check('string', 'string');
                check('/match/', /match/);
                check('function', function () {});

                check('Boolean(true)', Boolean(true));
                check('Number(12)', Number(12));
                check('String(string)', String('string'));
                check('RegExp(regex)', new RegExp('regex'));

                check('obj ---> obj', obj);

                check('[].constructor', [].constructor);
                check('{}.constructor', {}.constructor);

                check('Boolean.constructor', Boolean.constructor);
                check('Number.constructor', Number.constructor);
                check('String.constructor', String.constructor);
                check('Function.constructor', Function.constructor);
                check('Array.constructor', Array.constructor);
                check('RegExp.constructor', RegExp.constructor);
                check('Error.constructor', Error.constructor);
                check('Object.constructor', Object.constructor);
            });
            describe('four', function () {
                var check = xrayDepth(it, 4),
                    obj = {name: 'fred', ref: ['referenced']},
                    obj2 = { girth: 'huge'};

                Object.setPrototypeOf(obj, obj2);
                Object.setPrototypeOf(obj2, { top: 'daddy'});

                check('obj ---> obj', obj);
            });
        });

        describe('xray :: a → [String]', function () {
            var xray = R.curry(function (testIt, expected, explain, value) {
                    testIt('should ' + explain + ' for ' + value, function () {
                        expect(F.xray(value)).to.deep.equal(expected);
                    });
                }),
                check = xray(it),
                checkNumber = xray(it,['Number', 'Number.prototype', 'Object.prototype']),
                checkBoolean = xray(it,['Boolean', 'Boolean.prototype', 'Object.prototype']),
                checkString = xray(it,['String', 'String.prototype', 'Object.prototype']),
                checkRegExp = xray(it,['RegExp', 'RegExp.prototype', 'Object.prototype']),
                obj = {name: 'fred', ref: ['referenced']},
                obj2 = { girth: 'huge'};

            Object.setPrototypeOf(obj, obj2);
            Object.setPrototypeOf(obj2, { top: 'daddy'});

            check(
                ['Mouse', 'Mammal', 'Object.prototype'],
                'answer with _inherits property if present',
                {_inherits: ['Mouse', 'Mammal']}
            );
            check(
                [],
                'handle undefined',
                void 0
            );
            check(
                ['Object'],
                'identify the null object',
                null
            );

            checkNumber('identify as Number', NaN);
            checkNumber('identify as Number', Infinity);
            checkNumber('identify as Number', -Infinity);

            checkBoolean('identify as Boolean', false);
            checkBoolean('identify as Boolean', true);

            checkNumber('identify as Number', 0);
            checkNumber('identify as Number', 12);
            checkString('identify as String', '');
            checkString('identify as String', 'a');

            checkRegExp('identify as RegExp', /this/);
            checkBoolean('identify as Boolean object Boolean(true)', Boolean(true));
            checkNumber('identify as Number Number(2)', Number(2));
            checkString('identify as String String(3)', String('3'));
            checkRegExp('identify as RegExp object', new RegExp('this', 'g'));

            it('should identify an anonymous function', function () {
                expect(F.xray(function () {}))
                    .to.deep.equal(['Function', 'Function', 'Object']);
            });
            it('should identify a named function', function () {
                expect(F.xray(function namedFn () {}))
                    .to.deep.equal(['Function namedFn', 'Function', 'Object']);
            });
            it('should identify an array', function () {
                expect(F.xray([])).to.deep.equal(['Array', 'Object']);
            });
            it('should identify an object', function () {
                expect(F.xray({})).to.deep.equal(['Object']);
            });
            it('should identify an inherited object', function () {
                expect(F.xray(obj2)).to.deep.equal(['Object', 'Object']);
            });
            it('should identify the Window object', function () {
                expect(F.xray(window)).to.deep.equal(['Window', 'EventTarget', 'Object']);
            });
            it.only('should identify the document object', function () {
                expect(F.xray(document))
                    .to.deep.equal(["HTMLDocument", "HTMLDocument", "Document", "Node", "EventTarget", "Object.prototype"]);
            });
            it('should identify the Boolean prototype', function () {
                expect(F.xray(Boolean.prototype))
                    .to.deep.equal(['Boolean.prototype', 'Object.prototype']);
            });
            it('should identify the Boolean constructor', function () {
                expect(F.xray(Boolean))
                    .to.deep.equal(['Function Boolean', 'Function.prototype', 'Object.prototype']);
            });
        });

    }); // describe
} // defineSuite

function defineCode() {

    // impure trace :: String → a → a
    F.trace = R.curry(function (message, thing) {
        console.log(message, thing);
        return thing;
    });

    // xrayDepth :: a → Number
    // report how long the prototype chain is.
    F.xrayDepth = function (obj) {
        var depth = 0;
        while (obj !== null && typeof obj !== 'undefined') {
            depth += 1;
            obj = Object.getPrototypeOf(obj);
        }
        return depth;
    };

    // xray :: a → [String]
    // return the inherits chain from an xrayScan
    F.xray = function (obj) {
        return F.xrayScan(obj)._inherits;
    };

    // xrayScan :: a → b → b
    // identify what an object is and what it inherits from
    // if _inherits array exists, that is used, otherwise tries to be smart
    F.xrayScan = function (obj, ancestry) {
        /* jshint maxcomplexity: 12, maxdepth: 4 */
        ancestry = ancestry || { _inherits: [], path: '', objects: [], found: {} };

        var proto,
            typeOf = typeof obj,
            nameProperties = ['nodeName', 'id', 'cid', 'name', 'title'],
            outIf = function (check, obj, type) {
                if (check) {
                    if (type) {
                        type = type[0].toUpperCase() + type.slice(1);
                        inherit(type, obj);
                    }
                    throw new Error(type);
                }
            },
            inheritIfMatch = function (obj, type, regex, prefix) {
                prefix = prefix || '';
                var match = type.match(regex);
                if (match) {
                    type = prefix + match[1];
                    inherit(type, obj);
                    throw new Error(type);
                }
            },
            inherit = function (type, obj) {
                var typeName = type;
                /*
                 if ((type === 'Boolean' && obj !== Boolean) ||
                 (type === 'Number' && obj !== Number) ||
                 (type === 'String' && obj !== String) ||
                 (type === 'RegExp' && obj !== RegExp) ||
                 (type === 'Function' && obj !== Function) ||
                 (type === 'Array' && obj !== Array) ||
                 (type === 'Object' && obj !== Object)
                 ) {
                 typeName = 'a ' + typeName;
                 }
                 */
                if ((type === 'Boolean' && obj === Boolean.prototype) ||
                    (type === 'Number' && obj === Number.prototype) ||
                    (type === 'String' && obj === String.prototype) ||
                    (type === 'RegExp' && obj === RegExp.prototype) ||
                    (type === 'Function' && obj === Function.prototype) ||
                    (type === 'Array' && obj === Array.prototype) ||
                    (type === 'Object' && obj === Object.prototype)
                ) {
                    typeName = type + '.prototype';
                }

                if (obj) {
                    for (var idx = 0; idx < nameProperties.length; idx += 1) {
                        var prop = nameProperties[idx];
                        try {
                            if (obj[prop] &&
                                typeof obj[prop] !== 'function' &&
                                typeof obj[prop] !== 'object') {

                                typeName += ' ' + obj[prop];
                                idx = nameProperties.length;
                            }
                        }
                        catch (err) {
                            void err;
                        }
                    }
                }

                ancestry.found[typeName] = true;
                ancestry._inherits.push(typeName);
                ancestry.objects.push(obj);
            };

        try {
            outIf(obj === undefined, obj);
            outIf(obj === null, obj, 'Object');
            proto = Object.getPrototypeOf && Object.getPrototypeOf(obj);

            outIf(!/^(object|function)$/.test(typeOf), obj, typeOf);
            if (typeOf === 'function') {
                inheritIfMatch(obj, obj.toString(), /^function ([^\(]+)\(/, 'Function ');
                outIf(true, obj, 'Function');
            }
            if ('_inherits' in obj) {
                for (var idx = 0; idx < obj._inherits.length; idx += 1) {
                    ancestry._inherits.push(obj._inherits[idx]);
                }
                throw new Error('_inherits');
            }
            if (obj.constructor && obj.constructor.toString) {
                inheritIfMatch(obj, obj.constructor.toString(), /^function ([^\(]+)\(/);
            }
            if ('toString' in obj) {
                inheritIfMatch(obj, obj.toString(), /\[object (.+)\]/);
            }
        }
        catch (error) {
            if (proto) {
                F.xrayScan(proto, ancestry);
            }
        }
        finally {
            ancestry.path = ancestry._inherits.join(' → ');
            console.log(ancestry.path, ancestry);
            return ancestry;
        }
    }; // xrayScan
} // defineCode

start();<commit_msg>xray-codepen completed all tests passing<commit_after>/* jshint maxparams: 7, -W003, -W030, -W110, -W101 */
/* global R, chai, describe, it, mocha, document, window */

'use strict';

var expect = chai.expect,
    F = {};

// could not try out jscheck here, need a proper cdn
// https://raw.githubusercontent.com/douglascrockford/JSCheck/master/jscheck.js

function start () {
    mocha.setup('bdd');
    defineCode();
    defineSuite();
    mocha.run();
}

function defineSuite() {
    describe('xray summarize inheritance for an object', function () {
        describe('xray :: a → [String]', function () {
            var xray = R.curry(function (testIt, expected, explain, value) {
                    testIt('should ' + explain + ' for ' + value, function () {
                        expect(F.xray(value)).to.deep.equal(expected);
                    });
                }),
                check = xray(it),
                checkNumber = xray(it,['Number', 'Number.prototype', 'Object.prototype']),
                checkBoolean = xray(it,['Boolean', 'Boolean.prototype', 'Object.prototype']),
                checkString = xray(it,['String', 'String.prototype', 'Object.prototype']),
                checkRegExp = xray(it,['RegExp', 'RegExp.prototype', 'Object.prototype']),
                obj = {name: 'fred', ref: ['referenced']},
                obj2 = { girth: 'huge', id: '192'};

            Object.setPrototypeOf(obj, obj2);
            Object.setPrototypeOf(obj2, { top: 'daddy', cid: 'c45'});

            check(
                ['Mouse', 'Mammal', 'Object.prototype'],
                'answer with _inherits property if present',
                {_inherits: ['Mouse', 'Mammal']}
            );
            check(
                [],
                'handle undefined',
                void 0
            );
            check(
                ['Object'],
                'identify the null object',
                null
            );

            checkNumber('identify as Number', NaN);
            checkNumber('identify as Number', Infinity);
            checkNumber('identify as Number', -Infinity);

            checkBoolean('identify as Boolean', false);
            checkBoolean('identify as Boolean', true);

            checkNumber('identify as Number', 0);
            checkNumber('identify as Number', 12);
            checkString('identify as String', '');
            checkString('identify as String', 'a');

            checkRegExp('identify as RegExp', /this/);
            checkBoolean('identify as Boolean object Boolean(true)', Boolean(true));
            checkNumber('identify as Number Number(2)', Number(2));
            checkString('identify as String String(3)', String('3'));
            checkRegExp('identify as RegExp object', new RegExp('this', 'g'));

            it('should identify an anonymous function', function () {
                expect(F.xray(function () {}))
                    .to.deep.equal(['Function', 'Function.prototype', 'Object.prototype']);
            });
            it('should identify a named function', function () {
                expect(F.xray(function namedFn () {}))
                    .to.deep.equal(['Function namedFn', 'Function.prototype', 'Object.prototype']);
            });
            it('should identify an array', function () {
                expect(F.xray([])).to.deep.equal(['Array', 'Array.prototype', 'Object.prototype']);
            });
            it('should identify an object', function () {
                expect(F.xray({})).to.deep.equal(['Object', 'Object.prototype']);
            });
            it('should identify an double inherited object', function () {
                expect(F.xray(obj)).to.deep.equal(['Object fred', 'Object 192', 'Object c45', 'Object.prototype']);
            });
            it('should identify an inherited object', function () {
                expect(F.xray(obj2)).to.deep.equal(['Object 192', 'Object c45', 'Object.prototype']);
            });
            it('should identify the Window object', function () {
                expect(F.xray(window)).to.deep.equal(['Window CodePen', 'Window', 'EventTarget', 'Object.prototype']);
            });
            it('should identify the document object', function () {
                expect(F.xray(document))
                    .to.deep.equal(["HTMLDocument #document", "HTMLDocument", "Document", "Node", "EventTarget", "Object.prototype"]);
            });
            it('should identify the Boolean prototype', function () {
                expect(F.xray(Boolean.prototype))
                    .to.deep.equal(['Boolean.prototype', 'Object.prototype']);
            });
            it('should identify the Boolean constructor', function () {
                expect(F.xray(Boolean))
                    .to.deep.equal(['Function Boolean', 'Function.prototype', 'Object.prototype']);
            });
        });

    }); // xray test

    describe('xrayDepth :: a → Number', function () {

        // Cool, curry a test case so we can cut out a lot of noise when testing
        var xrayDepth = R.curry(function (testIt, depth, name, value) {
            testIt('should be ' + depth + ' for ' + name, function () {
                expect(F.xrayDepth(value)).to.be.equal(depth);
            });
        });

        describe('zero', function () {
            var check = xrayDepth(it, 0);

            check('null', null);
            check('undefined', void 0);
        });
        describe('one', function () {
            var check = xrayDepth(it, 1);

            check('Object.prototype', Object.prototype);
        });
        describe('two', function () {
            var check = xrayDepth(it, 2);

            check('{}', {});

            check('Boolean.prototype', Boolean.prototype);
            check('Number.prototype', Number.prototype);
            check('String.prototype', String.prototype);
            check('Function.prototype', Function.prototype);
            check('Array.prototype', Array.prototype);
            check('RegExp.prototype', RegExp.prototype);
            check('Error.prototype', Error.prototype);

        });
        describe('three', function () {
            var check = xrayDepth(it, 3),
                obj = {name: 'fred', ref: ['referenced']};

            Object.setPrototypeOf(obj, { girth: 'huge' });

            check('[]', []);
            check('true', true);
            check('42', 42);
            check('NaN', NaN);
            check('Infinity', Infinity);
            check('string', 'string');
            check('/match/', /match/);
            check('function', function () {});

            check('Boolean(true)', Boolean(true));
            check('Number(12)', Number(12));
            check('String(string)', String('string'));
            check('RegExp(regex)', new RegExp('regex'));

            check('obj ---> obj', obj);

            check('[].constructor', [].constructor);
            check('{}.constructor', {}.constructor);

            check('Boolean.constructor', Boolean.constructor);
            check('Number.constructor', Number.constructor);
            check('String.constructor', String.constructor);
            check('Function.constructor', Function.constructor);
            check('Array.constructor', Array.constructor);
            check('RegExp.constructor', RegExp.constructor);
            check('Error.constructor', Error.constructor);
            check('Object.constructor', Object.constructor);
        });
        describe('four', function () {
            var check = xrayDepth(it, 4),
                obj = {name: 'fred', ref: ['referenced']},
                obj2 = { girth: 'huge'};

            Object.setPrototypeOf(obj, obj2);
            Object.setPrototypeOf(obj2, { top: 'daddy'});

            check('obj ---> obj', obj);
        });
    }); // xrayDepth test

} // defineSuite

function defineCode() {

    // impure trace :: String → a → a
    F.trace = R.curry(function (message, thing) {
        console.log(message, thing);
        return thing;
    });

    // xrayDepth :: a → Number
    // report how long the prototype chain is.
    F.xrayDepth = function (obj) {
        var depth = 0;
        while (obj !== null && typeof obj !== 'undefined') {
            depth += 1;
            obj = Object.getPrototypeOf(obj);
        }
        return depth;
    };

    // xray :: a → [String]
    // return the inherits chain from an xrayScan
    F.xray = function (obj) {
        return F.xrayScan(obj)._inherits;
    };

    // xrayScan :: a → b → b
    // identify what an object is and what it inherits from
    // if _inherits array exists, that is used, otherwise tries to be smart
    F.xrayScan = function (obj, ancestry) {
        /* jshint maxcomplexity: 19, maxdepth: 6 */
        ancestry = ancestry || { _inherits: [], path: '', objects: [], found: {} };

        var proto,
            typeOf = typeof obj,
            nameProperties = ['nodeName', 'id', 'cid', 'name', 'title'],
            outIf = function (check, obj, type) {
                if (check) {
                    if (type) {
                        type = type[0].toUpperCase() + type.slice(1);
                        inherit(type, obj);
                    }
                    throw new Error(type);
                }
            },
            inheritIfMatch = function (obj, type, regex, prefix) {
                prefix = prefix || '';
                var match = type.match(regex);
                if (match) {
                    type = prefix + match[1];
                    inherit(type, obj);
                    throw new Error(type);
                }
            },
            inherit = function (type, obj) {
                var typeName = type;
                /*
                 if ((type === 'Boolean' && obj !== Boolean) ||
                 (type === 'Number' && obj !== Number) ||
                 (type === 'String' && obj !== String) ||
                 (type === 'RegExp' && obj !== RegExp) ||
                 (type === 'Function' && obj !== Function) ||
                 (type === 'Array' && obj !== Array) ||
                 (type === 'Object' && obj !== Object)
                 ) {
                 typeName = 'a ' + typeName;
                 }
                 */
                if ((type === 'Boolean' && obj === Boolean.prototype) ||
                    (type === 'Number' && obj === Number.prototype) ||
                    (type === 'String' && obj === String.prototype) ||
                    (type === 'RegExp' && obj === RegExp.prototype) ||
                    (type === 'Function' && obj === Function.prototype) ||
                    (type === 'Array' && obj === Array.prototype) ||
                    (type === 'Object' && obj === Object.prototype)
                ) {
                    typeName = type + '.prototype';
                }

                if (obj && !/ /.test(typeName)) {
                    var prop, idx, named = null;
                    // first try with hasOwnProperty but some native objects will fail
                    for (idx = 0; idx < nameProperties.length; idx += 1) {
                        prop = nameProperties[idx];
                        try {
                            if (obj.hasOwnProperty(prop) &&
                                typeof obj[prop] !== 'function' &&
                                typeof obj[prop] !== 'object') {

                                named = '' + obj[prop];
                                if (named.trim().length) {
                                    idx = nameProperties.length;
                                }
                                else {
                                    named = null;
                                }
                            }
                        }
                        catch (err) {
                            void err;
                        }
                    }

                    // fall back to a normal property lookup if still no name found
                    if (named === null) {
                        for (idx = 0; idx < nameProperties.length; idx += 1) {
                            prop = nameProperties[idx];
                            try {
                                if (obj[prop] &&
                                    typeof obj[prop] !== 'function' &&
                                    typeof obj[prop] !== 'object') {

                                    named = '' + obj[prop];
                                    if (named.trim().length) {
                                        idx = nameProperties.length;
                                    }
                                    else {
                                        named = null;
                                    }
                                }
                            }
                            catch (err) {
                                void err;
                            }
                        }
                    }

                    if (named !== null) {
                        typeName += ' ' + named;
                    }
                }

                ancestry.found[typeName] = true;
                ancestry._inherits.push(typeName);
                ancestry.objects.push(obj);
            };

        try {
            outIf(obj === undefined, obj);
            outIf(obj === null, obj, 'Object');
            proto = Object.getPrototypeOf && Object.getPrototypeOf(obj);

            outIf(!/^(object|function)$/.test(typeOf), obj, typeOf);
            if (typeOf === 'function') {
                inheritIfMatch(obj, obj.toString(), /^function ([^\(]+)\(/, 'Function ');
                outIf(true, obj, 'Function');
            }
            if ('_inherits' in obj) {
                for (var idx = 0; idx < obj._inherits.length; idx += 1) {
                    ancestry._inherits.push(obj._inherits[idx]);
                }
                throw new Error('_inherits');
            }
            if (obj.constructor && obj.constructor.toString) {
                inheritIfMatch(obj, obj.constructor.toString(), /^function ([^\(]+)\(/);
            }
            if ('toString' in obj) {
                inheritIfMatch(obj, obj.toString(), /\[object (.+)\]/);
            }
        }
        catch (error) {
            if (proto) {
                F.xrayScan(proto, ancestry);
            }
        }
        finally {
            ancestry.path = ancestry._inherits.join(' → ');
            console.log(ancestry.path, ancestry);
            return ancestry;
        }
    }; // xrayScan
} // defineCode

start();<|endoftext|>


<commit_before>/*
 * grunt-scaffold
 * https://github.com/alex-seville/scaffold.js
 *
 * Copyright (c) 2013 alex-seville
 * Licensed under the MIT license.
 */

'use strict';

var publicjs = require("public.js");
var _ = require("underscore");

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('public-js', 'Your task description goes here.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({

    });

    if (!options.type){
      grunt.log.warn('You must provide a task type.');
      return false;
    }

    if (options.type === 'scaffold'){
      scaffolds.call(this,options,this.files);
    }else if (options.type === 'lint'){
      lint.call(this,options,this.files);
    }

  });

  function scaffolds(options,files){
    if (!options.template){
      grunt.log.warn('You must provide a template.');
      return false;
    }

    // Iterate over all specified file groups.
    files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      });

      var output;

      if (src.length === 1 && !options.source ){
        output = publicjs.getPublic(src[0],{
          tree:true
        });
      }else{
        if (!options.source){
          grunt.log.warn('You must provide a configuration option for the main source file.');
          return false;
        }
        output = publicjs.getPublic(grunt.file.read(options.source),{
            dependencies: src,
            tree:true
          });
      }

      var template = grunt.file.read(options.template);
      var unitTest = _.template(template);
      var testStr = unitTest({data: output});
      grunt.file.write(f.dest,testStr);
      // Print a success message.
      grunt.log.writeln('Created test scaffolds');
    });
  }

  function lint(options,files){
    var errors=[];
    // Iterate over all specified file groups.
    files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      });

      var output, dest = grunt.file.read(f.dest);

      var errorCallback = function(name,details){
        errors.push({ k: name, v: details, f:f.dest });
      };

        if (src.length > 0 ){
          output = publicjs.getPublic(dest,{
            dependencies: src,
            errorCallback: errorCallback,
            tree:true
          });
        }else{
          output = publicjs.getPublic(dest,{
            errorCallback: errorCallback,
            tree:true
          });
        }
    });
    if (errors.length > 0){
        grunt.log.warn("Public-lint error"+(errors.length > 1 ? "s" : "") + ": ");
        errors.forEach(function(e){
          grunt.log.warn("Error when accessing "+e.v+"."+e.k+" in "+ e.f);
        })
        grunt.fatal("Public-lint failed.");
      }
      grunt.log.writeln('Public-lint completed successfully.');
  }

};
<commit_msg>Update grunt-public.js<commit_after>/*
 * grunt-scaffold
 * https://github.com/alex-seville/scaffold.js
 *
 * Copyright (c) 2013 alex-seville
 * Licensed under the MIT license.
 */

'use strict';

var publicjs = require("public.js");
var _ = require("underscore");

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('public-js', 'Your task description goes here.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      lintOptions: {}
    });

    if (!options.type){
      grunt.log.warn('You must provide a task type.');
      return false;
    }

    if (options.type === 'scaffold'){
      scaffolds.call(this,options,this.files);
    }else if (options.type === 'lint'){
      lint.call(this,options,this.files);
    }

  });

  function scaffolds(options,files){
    if (!options.template){
      grunt.log.warn('You must provide a template.');
      return false;
    }

    // Iterate over all specified file groups.
    files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      });

      var output;

      if (src.length === 1 && !options.source ){
        output = publicjs.getPublic(src[0],{
          tree:true
        });
      }else{
        if (!options.source){
          grunt.log.warn('You must provide a configuration option for the main source file.');
          return false;
        }
        output = publicjs.getPublic(grunt.file.read(options.source),{
            dependencies: src,
            tree:true
          });
      }

      var template = grunt.file.read(options.template);
      var unitTest = _.template(template);
      var testStr = unitTest({data: output});
      grunt.file.write(f.dest,testStr);
      // Print a success message.
      grunt.log.writeln('Created test scaffolds');
    });
  }

  function lint(options,files){
    var errors=[];
    // Iterate over all specified file groups.
    files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      });

      var output, dest = grunt.file.read(f.dest);

      var errorCallback = function(name,details){
        errors.push("Error when accessing "+details+"."+name+" in "+ f.dest);
      };

        if (src.length > 0 ){
          output = publicjs.getPublic(dest,{
            dependencies: src,
            errorCallback: errorCallback,
            tree:true
          });
        }else{
          output = publicjs.getPublic(dest,{
            errorCallback: errorCallback,
            tree:true
          });
        }
    });
    //check exportOnly
    if (options.lintOptions.exportOnly){
      if (options.lintOptions.exportOnly.length === 0 && output.length !== 0){
        errors.push("Expected nothing to be exported, but saw: "+output.map(function(o){ return o.name; }));
      }else if (options.lintOptions.exportOnly.length > 0 && output.length === 0){
        errors.push("Nothing was exported.");
      }
    }

    //display result
    if (errors.length > 0){
        grunt.log.warn("Public-lint error"+(errors.length > 1 ? "s" : "") + ": ");
        errors.forEach(function(e){
          grunt.log.warn(e);
        })
        grunt.fatal("Public-lint failed.");
      }
      grunt.log.writeln('Public-lint completed successfully.');
  }

};
<|endoftext|>


<commit_before>'use strict'

/*
The goal of this is to remove all secrets/passwords from source control, and
so that configs can be overridden using environment variables,

@TODO: Look into extending konphyg with env vars

env:
  ("HOST" is not set)
  PORT=80
  HOME=/Users/sample

defaults:
  {
    HOST: 'localhost',
    PORT: 3000
  }

expected results:
  nconf.get('HOST') === 'localhost'
  nconf.get('PORT') === 80
  nconf.get('HOME') === undefined

*/

const _ = require('lodash')
const nconf = require('nconf')
const konphyg = require('konphyg')

module.exports = function (appName, options) {
  options = options || {}
  var path = options.path || './configs'
  var separator = options.separator || '__'

  // Let konphyg grab the default config for the current NODE_ENV
  const defaults = konphyg(path, options.environment)(appName)
  const whitelist = []

  // Convert all keys to flat ENV_const format
  // {A: 1, FOO: {BAR: 2}} ==> A=1, FOO__BAR=2
  // (Assuming just one level deep)
  for (let key in defaults) {
    const value = defaults[key]
    if (typeof value === 'object') {
      for (let subkey in value) {
        whitelist.push([key, separator, subkey].join(''))
      }
    } else {
      whitelist.push(key)
    }
  }

  // Load ’em up in nconf
  nconf
    .env({
      whitelist: whitelist,
      separator: separator
    })
    .defaults(defaults)

  nconf.isTrue = function isTrue (key) {
    const value = nconf.get(key)
    if (_.isNil(value)) {
      return false
    }
    if (_.isString(value)) {
      return value.toLowerCase() === 'true'
    }
    if (_.isBoolean(value)) {
      return value
    }
    throw new Error('Unexpected value type for nconf.isTrue')
  }

  nconf.asInt = function asInt (key) {
    return parseInt(nconf.get(key))
  }

  nconf.asFloat = function asFloat (key) {
    return parseFloat(nconf.get(key))
  }

  return nconf
}
<commit_msg>feat(config): add isDev and isProd fields to the config object<commit_after>'use strict'

/*
The goal of this is to remove all secrets/passwords from source control, and
so that configs can be overridden using environment variables,

@TODO: Look into extending konphyg with env vars

env:
  ("HOST" is not set)
  PORT=80
  HOME=/Users/sample

defaults:
  {
    HOST: 'localhost',
    PORT: 3000
  }

expected results:
  nconf.get('HOST') === 'localhost'
  nconf.get('PORT') === 80
  nconf.get('HOME') === undefined

*/

const _ = require('lodash')
const nconf = require('nconf')
const konphyg = require('konphyg')

module.exports = function (appName, options) {
  options = options || {}
  var path = options.path || './configs'
  var separator = options.separator || '__'

  // Let konphyg grab the default config for the current NODE_ENV
  const defaults = konphyg(path, options.environment)(appName)
  const whitelist = []

  // Convert all keys to flat ENV_const format
  // {A: 1, FOO: {BAR: 2}} ==> A=1, FOO__BAR=2
  // (Assuming just one level deep)
  for (let key in defaults) {
    const value = defaults[key]
    if (typeof value === 'object') {
      for (let subkey in value) {
        whitelist.push([key, separator, subkey].join(''))
      }
    } else {
      whitelist.push(key)
    }
  }

  // Load ’em up in nconf
  nconf
    .env({
      whitelist: whitelist,
      separator: separator
    })
    .defaults(defaults)

  nconf.isTrue = function isTrue (key) {
    const value = nconf.get(key)
    if (_.isNil(value)) {
      return false
    }
    if (_.isString(value)) {
      return value.toLowerCase() === 'true'
    }
    if (_.isBoolean(value)) {
      return value
    }
    throw new Error('Unexpected value type for nconf.isTrue')
  }

  nconf.asInt = function asInt (key) {
    return parseInt(nconf.get(key))
  }

  nconf.asFloat = function asFloat (key) {
    return parseFloat(nconf.get(key))
  }

  nconf.isDev = process.env.NODE_ENV === 'development' || _.isEmpty(process.env.NODE_ENV)
  nconf.isProd = process.env.NODE_ENV === 'production'

  return nconf
}
<|endoftext|>


<commit_before>
// This file sets up boxing of javascript native objects into squeak objects
// All relevant classes are enhanced by that functionality and there are
// Several global functions to box or unbox objects.

// Some objects are boxing primitive js-values. Unboxing these values is polymorphic.
// The real version of this method is below. This could alternatively throw an error,
// but we try to be tolerant.
_Object._addInstanceMethods({
	_unbox: function() {
		return this;
	},
	// This never gets called, we just need a true-ish slot in each box-instance
	_isBoxedObject: function() { throw "just access this slot without calling."; }
});

// Class, that will wrap native javascript-objects to implement the Object-interface.
// Additionally, it adds accessor-methods for all fields to provide a squeak-API to
// set slots on javascript-objects.
Class("_Box", { superclass: _Object });

// Functions to bootstrap primitive values and wrap them into 'squeak'-objects
// Most functions are used in translated code directly, to avoid switch-statement in _boxObject()
// (Instead of bool(), compiled code uses _true/_false directly. bool() is used in kernel_primitives.js etc.)
var bool = function(aBool) { if (aBool) { return _true; } else { return _false; } }
var character = function(aString) { return Character._wrapping(aString); }
var string = function(aString) { return ByteString._wrapping(aString); }
var number = function(aNumber) { return Float._wrapping(aNumber); }
var array = function(anArray) { return _Array._wrapping(anArray); }
var object = function(anObject) { return _Box._wrapping(anObject); }
// if we box a javascript function into a smalltalk block we must bind it on creation
// Non-local-return handling is not required here
var boundBlock = function(func, that) {
	var b = BlockClosure._newInstance();
	// This block is unboxed to func, but additional things happen on evaluation
	b.original$ = func;
	b.evaluated$ = function() {
		var unboxedArguments = [];
		for (index in arguments) {
			unboxedArguments.push(arguments[index].unbox());
		}
		return _boxObject(func.apply(that, unboxedArguments));
	}
	return b;
}

// There are multiple js-'classes', that will be wrapped into a Squeak-Array
var arrayConstructors = [Array, NodeList];
var isArrayObject = function(anObject) {
	var constructor = anObject.constructor;
	for (index in arrayConstructors) {
		if (arrayConstructors[index] == constructor) {
			return true;
		}
	}
	return false;
};

// This static unboxing-function is added to avoid adding an _unbox method to native js-objects
var _unboxObject = function(anyObject) {
	if (anyObject._isBoxedObject) {
		return anyObject._unbox();
	}
	return anyObject;
};
var _boxObject = function(nativeObject, that) { // The 'that' parameter is optional and will be undefined otherwise
	if (!nativeObject._isBoxedObject) {
		switch( typeof(nativeObject) ) {
			case "number": return number(nativeObject); break;
			case "string": return string(nativeObject); break;
			case "boolean": return bool(nativeObject); break;
			case "function": return boundBlock(nativeObject, that); break;
			case "undefined": return nil; break;
			case "object":
				if (nativeObject == null) {
					return nil;
				} else if (isArrayObject(nativeObject)) {
					return array(nativeObject);
				} else {
					return object(nativeObject);
				}
				break;
			default:
				alert("Could not box creepy object: " + nativeObject);
		}
    }
	// nativeObject is already boxed!
	return nativeObject;
};

// These boxing classes box fixed, immutable values
False._addInstanceMethods( { _unbox: function() { return false; } } );
True._addInstanceMethods( { _unbox: function() { return true; } } );
UndefinedObject._addInstanceMethods( { _unbox: function() { return null; } } );

// These boxing classes box variable values and are all added the same functionality.
var boxingClasses = [_Box, ByteString, _Number, Character, BlockClosure, _Array, OrderedCollection];
for (index in boxingClasses) {
	var aClass = boxingClasses[index];
	aClass._addClassMethods({
		_wrapping: function(originalObject) {
			var result = this._newInstance(); // Polymorphic for different kinds of boxes
			result.original$ = originalObject;
			return result;
		}
	});
	aClass._addInstanceMethods({
		doesNotUnderstand_: function(aMessage) {
			var methodName = _unboxObject(aMessage.selector());
			if (methodName[methodName.length-1] == '_') {
				// setter. Set the unboxed, native-js, value.
				var value = aMessage.arguments().first();
				this.original$[methodName.substring(0, methodName.length - 1)] = _unboxObject(value);
				return value;
			} else {
				// getter
				return _boxObject(this.original$[methodName]);
			}
		},
		_unbox: function() {
			return this.original$;
		}
	});
}
<commit_msg>fixed wrong unboxing of arguments of blocks<commit_after>
// This file sets up boxing of javascript native objects into squeak objects
// All relevant classes are enhanced by that functionality and there are
// Several global functions to box or unbox objects.

// Some objects are boxing primitive js-values. Unboxing these values is polymorphic.
// The real version of this method is below. This could alternatively throw an error,
// but we try to be tolerant.
_Object._addInstanceMethods({
	_unbox: function() {
		return this;
	},
	// This never gets called, we just need a true-ish slot in each box-instance
	_isBoxedObject: function() { throw "just access this slot without calling."; }
});

// Class, that will wrap native javascript-objects to implement the Object-interface.
// Additionally, it adds accessor-methods for all fields to provide a squeak-API to
// set slots on javascript-objects.
Class("_Box", { superclass: _Object });

// Functions to bootstrap primitive values and wrap them into 'squeak'-objects
// Most functions are used in translated code directly, to avoid switch-statement in _boxObject()
// (Instead of bool(), compiled code uses _true/_false directly. bool() is used in kernel_primitives.js etc.)
var bool = function(aBool) { if (aBool) { return _true; } else { return _false; } }
var character = function(aString) { return Character._wrapping(aString); }
var string = function(aString) { return ByteString._wrapping(aString); }
var number = function(aNumber) { return Float._wrapping(aNumber); }
var array = function(anArray) { return _Array._wrapping(anArray); }
var object = function(anObject) { return _Box._wrapping(anObject); }
// if we box a javascript function into a smalltalk block we must bind it on creation
// Non-local-return handling is not required here
var boundBlock = function(func, that) {
	var b = BlockClosure._newInstance();
	// This block is unboxed to func, but additional things happen on evaluation
	b.original$ = func;
	b.evaluated$ = function() {
		var unboxedArguments = [];
		for (index in arguments) {
			unboxedArguments.push(_unboxObject(arguments[index]));
		}
		return _boxObject(func.apply(that, unboxedArguments));
	}
	return b;
}

// There are multiple js-'classes', that will be wrapped into a Squeak-Array
var arrayConstructors = [Array, NodeList];
var isArrayObject = function(anObject) {
	var constructor = anObject.constructor;
	for (index in arrayConstructors) {
		if (arrayConstructors[index] == constructor) {
			return true;
		}
	}
	return false;
};

// This static unboxing-function is added to avoid adding an _unbox method to native js-objects
var _unboxObject = function(anyObject) {
	if (anyObject._isBoxedObject) {
		return anyObject._unbox();
	}
	return anyObject;
};
var _boxObject = function(nativeObject, that) { // The 'that' parameter is optional and will be undefined otherwise
	if (!nativeObject._isBoxedObject) {
		switch( typeof(nativeObject) ) {
			case "number": return number(nativeObject); break;
			case "string": return string(nativeObject); break;
			case "boolean": return bool(nativeObject); break;
			case "function": return boundBlock(nativeObject, that); break;
			case "undefined": return nil; break;
			case "object":
				if (nativeObject == null) {
					return nil;
				} else if (isArrayObject(nativeObject)) {
					return array(nativeObject);
				} else {
					return object(nativeObject);
				}
				break;
			default:
				alert("Could not box creepy object: " + nativeObject);
		}
    }
	// nativeObject is already boxed!
	return nativeObject;
};

// These boxing classes box fixed, immutable values
False._addInstanceMethods( { _unbox: function() { return false; } } );
True._addInstanceMethods( { _unbox: function() { return true; } } );
UndefinedObject._addInstanceMethods( { _unbox: function() { return null; } } );

// These boxing classes box variable values and are all added the same functionality.
var boxingClasses = [_Box, ByteString, _Number, Character, BlockClosure, _Array, OrderedCollection];
for (index in boxingClasses) {
	var aClass = boxingClasses[index];
	aClass._addClassMethods({
		_wrapping: function(originalObject) {
			var result = this._newInstance(); // Polymorphic for different kinds of boxes
			result.original$ = originalObject;
			return result;
		}
	});
	aClass._addInstanceMethods({
		doesNotUnderstand_: function(aMessage) {
			var methodName = _unboxObject(aMessage.selector());
			if (methodName[methodName.length-1] == '_') {
				// setter. Set the unboxed, native-js, value.
				var value = aMessage.arguments().first();
				this.original$[methodName.substring(0, methodName.length - 1)] = _unboxObject(value);
				return value;
			} else {
				// getter
				return _boxObject(this.original$[methodName]);
			}
		},
		_unbox: function() {
			return this.original$;
		}
	});
}
<|endoftext|>


<commit_before>process.exit(

    0.00 // budget.js - keeping the books for @brooklyn_js
         // by @jedschmidt and @brianloveswords

         // cat budget.js | node -p | xargs -0 printf 'balance = %s'

         // BrooklynJS #1, 2013-11-14T19:00Z at @61Local
         // featuring @nakajima, @jandet, @SaraJChipps, and @jeresig

+ 360.00 // ticket sales  @peatix
+ 350.00 // sponsorship   @github

- 360.00 // bar tab       @61local
-  81.00 // tickets       @peatix
-  51.00 // banners       @BuildASign
-  50.00 // venue         @61local
-  32.00 // VGA adapter   @amazon
-  21.00 // nametags      @staples
-  14.00 // domain        @namecheap

-  50.50 // donation      @GirlsWhoCode
-  50.50 // donation      @ScriptEdnyc

         // BrooklynJS #2, 2013-12-16T19:00Z at @61Local
         // featuring @tbuchok, @vinceallenvince, @buritica, @benjamn, and @reconbot
         // with a surprise appearance by @jedschmidt's barbershop quartet

+ 665.00 // ticket sales  @peatix
+ 450.00 // sponsorship   @crushlovely

- 644.38 // bar tab       @61local
- 107.00 // tickets       @peatix
-  65.18 // stickers      @diginate
-  50.00 // venue         @61local
-  29.55 // VGA cable     @amazon
-   7.49 // paper tickets @amazon

- 105.70 // donation      @GirlsWhoCode
- 105.70 // donation      @ScriptEdnyc

)
<commit_msg>add link to travis<commit_after>process.exit(

    0.00 // budget.js - keeping the books for @brooklyn_js
         // by @jedschmidt and @brianloveswords

         // for details, see our accountant:
         // https://travis-ci.org/brooklynjs/brooklynjs.github.io

         // BrooklynJS #1, 2013-11-14T19:00Z at @61Local
         // featuring @nakajima, @jandet, @SaraJChipps, and @jeresig

+ 360.00 // ticket sales  @peatix
+ 350.00 // sponsorship   @github

- 360.00 // bar tab       @61local
-  81.00 // tickets       @peatix
-  51.00 // banners       @BuildASign
-  50.00 // venue         @61local
-  32.00 // VGA adapter   @amazon
-  21.00 // nametags      @staples
-  14.00 // domain        @namecheap

-  50.50 // donation      @GirlsWhoCode
-  50.50 // donation      @ScriptEdnyc

         // BrooklynJS #2, 2013-12-16T19:00Z at @61Local
         // featuring @tbuchok, @vinceallenvince, @buritica, @benjamn, and @reconbot
         // with a surprise appearance by @jedschmidt's barbershop quartet

+ 665.00 // ticket sales  @peatix
+ 450.00 // sponsorship   @crushlovely

- 644.38 // bar tab       @61local
- 107.00 // tickets       @peatix
-  65.18 // stickers      @diginate
-  50.00 // venue         @61local
-  29.55 // VGA cable     @amazon
-   7.49 // paper tickets @amazon

- 105.70 // donation      @GirlsWhoCode
- 105.70 // donation      @ScriptEdnyc

)
<|endoftext|>