| Index: pkg/custom_element/lib/custom-elements.debug.js
|
| diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
|
| index 400730bea18f9f5335e2fc5d818fb82ccaa94d43..be0a36032bbe1c5743357070633f9280a8a1d192 100644
|
| --- a/pkg/custom_element/lib/custom-elements.debug.js
|
| +++ b/pkg/custom_element/lib/custom-elements.debug.js
|
| @@ -1045,23 +1045,23 @@ if (useNative) {
|
| *
|
| * When a registered element is created, a `readyCallback` method is called
|
| * in the scope of the element. The `readyCallback` method can be specified on
|
| - * either `inOptions.prototype` or `inOptions.lifecycle` with the latter taking
|
| + * either `options.prototype` or `options.lifecycle` with the latter taking
|
| * precedence.
|
| *
|
| * @method register
|
| - * @param {String} inName The tag name to register. Must include a dash ('-'),
|
| + * @param {String} name The tag name to register. Must include a dash ('-'),
|
| * for example 'x-component'.
|
| - * @param {Object} inOptions
|
| - * @param {String} [inOptions.extends]
|
| + * @param {Object} options
|
| + * @param {String} [options.extends]
|
| * (_off spec_) Tag name of an element to extend (or blank for a new
|
| * element). This parameter is not part of the specification, but instead
|
| * is a hint for the polyfill because the extendee is difficult to infer.
|
| * Remember that the input prototype must chain to the extended element's
|
| * prototype (or HTMLElement.prototype) regardless of the value of
|
| * `extends`.
|
| - * @param {Object} inOptions.prototype The prototype to use for the new
|
| + * @param {Object} options.prototype The prototype to use for the new
|
| * element. The prototype must inherit from HTMLElement.
|
| - * @param {Object} [inOptions.lifecycle]
|
| + * @param {Object} [options.lifecycle]
|
| * Callbacks that fire at important phases in the life of the custom
|
| * element.
|
| *
|
| @@ -1078,18 +1078,23 @@ if (useNative) {
|
| * });
|
| * @return {Function} Constructor for the newly registered type.
|
| */
|
| - function register(inName, inOptions) {
|
| - //console.warn('document.register("' + inName + '", ', inOptions, ')');
|
| + function register(name, options) {
|
| + //console.warn('document.register("' + name + '", ', options, ')');
|
| // construct a defintion out of options
|
| - // TODO(sjmiles): probably should clone inOptions instead of mutating it
|
| - var definition = inOptions || {};
|
| - if (!inName) {
|
| + // TODO(sjmiles): probably should clone options instead of mutating it
|
| + var definition = options || {};
|
| + if (!name) {
|
| // TODO(sjmiles): replace with more appropriate error (EricB can probably
|
| // offer guidance)
|
| - throw new Error('Name argument must not be empty');
|
| + throw new Error('document.register: first argument `name` must not be empty');
|
| + }
|
| + if (name.indexOf('-') < 0) {
|
| + // TODO(sjmiles): replace with more appropriate error (EricB can probably
|
| + // offer guidance)
|
| + throw new Error('document.register: first argument `name` must contain a dash (\'-\'). Argument was \'' + String(name) + '\'.');
|
| }
|
| // record name
|
| - definition.name = inName;
|
| + definition.name = name;
|
| // must have a prototype, default to an extension of HTMLElement
|
| // TODO(sjmiles): probably should throw if no prototype, check spec
|
| if (!definition.prototype) {
|
| @@ -1112,7 +1117,7 @@ if (useNative) {
|
| // overrides to implement attributeChanged callback
|
| overrideAttributeApi(definition.prototype);
|
| // 7.1.5: Register the DEFINITION with DOCUMENT
|
| - registerDefinition(inName, definition);
|
| + registerDefinition(name, definition);
|
| // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE
|
| // 7.1.8. Return the output of the previous step.
|
| definition.ctor = generateConstructor(definition);
|
| @@ -1127,40 +1132,40 @@ if (useNative) {
|
| return definition.ctor;
|
| }
|
|
|
| - function ancestry(inExtends) {
|
| - var extendee = registry[inExtends];
|
| + function ancestry(extnds) {
|
| + var extendee = registry[extnds];
|
| if (extendee) {
|
| return ancestry(extendee.extends).concat([extendee]);
|
| }
|
| return [];
|
| }
|
|
|
| - function resolveTagName(inDefinition) {
|
| + function resolveTagName(definition) {
|
| // if we are explicitly extending something, that thing is our
|
| // baseTag, unless it represents a custom component
|
| - var baseTag = inDefinition.extends;
|
| + var baseTag = definition.extends;
|
| // if our ancestry includes custom components, we only have a
|
| // baseTag if one of them does
|
| - for (var i=0, a; (a=inDefinition.ancestry[i]); i++) {
|
| + for (var i=0, a; (a=definition.ancestry[i]); i++) {
|
| baseTag = a.is && a.tag;
|
| }
|
| // our tag is our baseTag, if it exists, and otherwise just our name
|
| - inDefinition.tag = baseTag || inDefinition.name;
|
| + definition.tag = baseTag || definition.name;
|
| if (baseTag) {
|
| // if there is a base tag, use secondary 'is' specifier
|
| - inDefinition.is = inDefinition.name;
|
| + definition.is = definition.name;
|
| }
|
| }
|
|
|
| - function resolvePrototypeChain(inDefinition) {
|
| + function resolvePrototypeChain(definition) {
|
| // if we don't support __proto__ we need to locate the native level
|
| // prototype for precise mixing in
|
| if (!Object.__proto__) {
|
| // default prototype
|
| var native = HTMLElement.prototype;
|
| // work out prototype when using type-extension
|
| - if (inDefinition.is) {
|
| - var inst = document.createElement(inDefinition.tag);
|
| + if (definition.is) {
|
| + var inst = document.createElement(definition.tag);
|
| native = Object.getPrototypeOf(inst);
|
| }
|
| // ensure __proto__ reference is installed at each point on the prototype
|
| @@ -1168,7 +1173,7 @@ if (useNative) {
|
| // NOTE: On platforms without __proto__, a mixin strategy is used instead
|
| // of prototype swizzling. In this case, this generated __proto__ provides
|
| // limited support for prototype traversal.
|
| - var proto = inDefinition.prototype, ancestor;
|
| + var proto = definition.prototype, ancestor;
|
| while (proto && (proto !== native)) {
|
| var ancestor = Object.getPrototypeOf(proto);
|
| proto.__proto__ = ancestor;
|
| @@ -1176,49 +1181,49 @@ if (useNative) {
|
| }
|
| }
|
| // cache this in case of mixin
|
| - inDefinition.native = native;
|
| + definition.native = native;
|
| }
|
|
|
| // SECTION 4
|
|
|
| - function instantiate(inDefinition) {
|
| + function instantiate(definition) {
|
| // 4.a.1. Create a new object that implements PROTOTYPE
|
| // 4.a.2. Let ELEMENT by this new object
|
| //
|
| // the custom element instantiation algorithm must also ensure that the
|
| // output is a valid DOM element with the proper wrapper in place.
|
| //
|
| - return upgrade(domCreateElement(inDefinition.tag), inDefinition);
|
| + return upgrade(domCreateElement(definition.tag), definition);
|
| }
|
|
|
| - function upgrade(inElement, inDefinition) {
|
| + function upgrade(element, definition) {
|
| // some definitions specify an 'is' attribute
|
| - if (inDefinition.is) {
|
| - inElement.setAttribute('is', inDefinition.is);
|
| + if (definition.is) {
|
| + element.setAttribute('is', definition.is);
|
| }
|
| - // make 'element' implement inDefinition.prototype
|
| - implement(inElement, inDefinition);
|
| + // make 'element' implement definition.prototype
|
| + implement(element, definition);
|
| // flag as upgraded
|
| - inElement.__upgraded__ = true;
|
| - // there should never be a shadow root on inElement at this point
|
| + element.__upgraded__ = true;
|
| + // there should never be a shadow root on element at this point
|
| // we require child nodes be upgraded before `created`
|
| - scope.upgradeSubtree(inElement);
|
| + scope.upgradeSubtree(element);
|
| // lifecycle management
|
| - created(inElement);
|
| + created(element);
|
| // OUTPUT
|
| - return inElement;
|
| + return element;
|
| }
|
|
|
| - function implement(inElement, inDefinition) {
|
| + function implement(element, definition) {
|
| // prototype swizzling is best
|
| if (Object.__proto__) {
|
| - inElement.__proto__ = inDefinition.prototype;
|
| + element.__proto__ = definition.prototype;
|
| } else {
|
| // where above we can re-acquire inPrototype via
|
| // getPrototypeOf(Element), we cannot do so when
|
| // we use mixin, so we install a magic reference
|
| - customMixin(inElement, inDefinition.prototype, inDefinition.native);
|
| - inElement.__proto__ = inDefinition.prototype;
|
| + customMixin(element, definition.prototype, definition.native);
|
| + element.__proto__ = definition.prototype;
|
| }
|
| }
|
|
|
| @@ -1246,10 +1251,10 @@ if (useNative) {
|
| }
|
| }
|
|
|
| - function created(inElement) {
|
| + function created(element) {
|
| // invoke createdCallback
|
| - if (inElement.createdCallback) {
|
| - inElement.createdCallback();
|
| + if (element.createdCallback) {
|
| + element.createdCallback();
|
| }
|
| }
|
|
|
| @@ -1282,34 +1287,55 @@ if (useNative) {
|
|
|
| var registry = {};
|
|
|
| - function registerDefinition(inName, inDefinition) {
|
| - if (registry[inName]) {
|
| - throw new Error('Cannot register a tag more than once');
|
| + function registerDefinition(name, definition) {
|
| + if (registry[name]) {
|
| + throw new Error('a type with that name is already registered.');
|
| }
|
| - registry[inName] = inDefinition;
|
| + registry[name] = definition;
|
| }
|
|
|
| - function generateConstructor(inDefinition) {
|
| + function generateConstructor(definition) {
|
| return function() {
|
| - return instantiate(inDefinition);
|
| + return instantiate(definition);
|
| };
|
| }
|
|
|
| function createElement(tag, typeExtension) {
|
| - // TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could
|
| - // error check it, or perhaps there should only ever be one argument
|
| var definition = registry[typeExtension || tag];
|
| if (definition) {
|
| - return new definition.ctor();
|
| + if (tag == definition.tag && typeExtension == definition.is) {
|
| + return new definition.ctor();
|
| + }
|
| + // Handle empty string for type extension.
|
| + if (!typeExtension && !definition.is) {
|
| + return new definition.ctor();
|
| + }
|
| }
|
| - return domCreateElement(tag);
|
| +
|
| + if (typeExtension) {
|
| + var element = createElement(tag);
|
| + element.setAttribute('is', typeExtension);
|
| + return element;
|
| + }
|
| + var element = domCreateElement(tag);
|
| + // Custom tags should be HTMLElements even if not upgraded.
|
| + if (tag.indexOf('-') >= 0) {
|
| + implement(element, HTMLElement);
|
| + }
|
| + return element;
|
| }
|
|
|
| - function upgradeElement(inElement) {
|
| - if (!inElement.__upgraded__ && (inElement.nodeType === Node.ELEMENT_NODE)) {
|
| - var type = inElement.getAttribute('is') || inElement.localName;
|
| - var definition = registry[type];
|
| - return definition && upgrade(inElement, definition);
|
| + function upgradeElement(element) {
|
| + if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) {
|
| + var is = element.getAttribute('is');
|
| + var definition = registry[is || element.localName];
|
| + if (definition) {
|
| + if (is && definition.tag == element.localName) {
|
| + return upgrade(element, definition);
|
| + } else if (!is && !definition.extends) {
|
| + return upgrade(element, definition);
|
| + }
|
| + }
|
| }
|
| }
|
|
|
| @@ -1345,7 +1371,7 @@ if (useNative) {
|
| * if it matches no registered custom tag name.
|
| *
|
| * @method ugprade
|
| - * @param {Element} inElement The element to upgrade.
|
| + * @param {Element} element The element to upgrade.
|
| * @return {Element} The upgraded element.
|
| */
|
| scope.upgrade = upgradeElement;
|
|
|