Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

Implementing customized built-in elements #42

Closed
Closed
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a7073c4
Remove test assumption that `customElements` exists.
bicknellr Dec 14, 2016
ee326ff
Use one-liner for forcing the polyfill.
bicknellr Dec 17, 2016
f0eb664
Update WCT and webcomponentsjs.
bicknellr Dec 17, 2016
8ffa12b
Update HTMLImports polyfill path.
bicknellr Dec 17, 2016
555e61e
Remove use of `String#endsWith`.
bicknellr Dec 19, 2016
e089691
Update WCT to 6.0.0-prerelease.3 for ES2015 compilation.
bicknellr Dec 19, 2016
0265c2d
Add bower dependency and installation.
bicknellr Dec 19, 2016
775b224
Add promise polyfill for tests.
bicknellr Dec 19, 2016
e6eddb5
Test for 'HTMLElement#constructor' writable / configurable flags that…
bicknellr Dec 19, 2016
0c82e24
Remove unnecessary `HTMLElement#constructor` descriptor test.
bicknellr Dec 19, 2016
4485b37
It's sort of working
joeldenning Jan 5, 2017
851fd1b
subclassing things
joeldenning Jan 9, 2017
c8f7e69
Merge branch 'fix-tests' into customized-builtin
joeldenning Jan 9, 2017
93d812a
Tests passing
joeldenning Jan 9, 2017
5e15bb8
Google closure type fixing
joeldenning Jan 9, 2017
270f834
Removing built files
joeldenning Jan 9, 2017
4259dda
Self review 1
joeldenning Jan 9, 2017
2a6a70d
Self review 2
joeldenning Jan 9, 2017
5dce865
Fixing bug where autonomous elements had is="" attribute
joeldenning Jan 9, 2017
2feec3e
Removing custom-elements.min.js changes
joeldenning Jan 10, 2017
c8c6627
Domenic's feedback - use node.localName instead of tagName
joeldenning Jan 10, 2017
7233ea6
Fixing closure compiler warnings
joeldenning Jan 12, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Self review 1
joeldenning committed Jan 9, 2017
commit 4259dda5a5d89a2f67f376b1dc153352ddc1977c
2 changes: 1 addition & 1 deletion DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ the other webcomponentsjs polyfills, and its build is not integrated into the de

To build run:

npm run build
gulp CustomElementsV1

This creates a CustomElementsV1.min.js file in dist/

50 changes: 21 additions & 29 deletions src/custom-elements.js
Original file line number Diff line number Diff line change
@@ -182,17 +182,11 @@ let Deferred;
throw new TypeError('constructor must be a Constructor');
}

// 2. If constructor is an interface object whose corresponding interface
// either is HTMLElement or has HTMLElement in its set of inherited
// interfaces, throw a TypeError and abort these steps.
//
// It doesn't appear possible to check this condition from script

// 3:
// 2:
const nameError = checkValidCustomElementName(name);
if (nameError) throw nameError;

// 4, 5:
// 3:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The numbering has changed in the spec for customElements.define, so I updated it.

// Note: we don't track being-defined names and constructors because
// define() isn't normally reentrant. The only time user code can run
// during define() is when getting callbacks off the prototype, which
@@ -201,41 +195,44 @@ let Deferred;
throw new Error(`An element with name '${name}' is already defined`);
}

// 6, 7:
// 4:
if (this._constructors.has(constructor)) {
throw new Error(`Definition failed for '${name}': ` +
`The constructor is already used.`);
}

// 8:
// 5:
/** @type {string} */
let localName = name;

// 9, 10
if (options && options.extends) {
// 7.1
// 6:
let extends = options && options.extends;

// 7:
if (extends) {
// 7.1:
const extendsNameError = checkValidCustomElementName(options.extends);
if (!extendsNameError) {
throw new Error(`Cannot extend '${options.extends}': A custom element cannot extend a custom element.`);
}

// 7.2
// 7.2:
const el = document.createElement(options.extends);
if (el instanceof window.HTMLUnknownElement) {
throw new Error(`Cannot extend '${options.extends}': is not a real HTMLElement`);
}

// 7.3
// 7.3:
localName = options.extends;
}

// 11, 12, 13: Our define() isn't rentrant-safe
// 8, 9: Our define() isn't rentrant-safe

// 14.1:
// 10.1:
/** @type {Object} */
const prototype = constructor.prototype;

// 14.2:
// 10.2:
if (typeof prototype !== 'object') {
throw new TypeError(`Definition failed for '${name}': ` +
`constructor.prototype must be an object`);
@@ -253,23 +250,18 @@ let Deferred;
return callback;
}

// 3, 4:
// 10.3, 10.4:
const connectedCallback = getCallback('connectedCallback');

// 5, 6:
const disconnectedCallback = getCallback('disconnectedCallback');

// Divergence from spec: we always throw if attributeChangedCallback is
// not a function.

// 7, 9.1:
const attributeChangedCallback = getCallback('attributeChangedCallback');

// 8, 9.2, 9.3:
// 10.5, 10.6:
const observedAttributes =
(attributeChangedCallback && constructor['observedAttributes']) || [];

// 15:
// 11:
/** @type {CustomElementDefinition} */
const definition = {
name: name,
@@ -281,14 +273,14 @@ let Deferred;
observedAttributes: observedAttributes,
};

// 16:
// 12:
this._definitions.set(name, definition);
this._constructors.set(constructor, definition);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above about how the _constructors map has changed


// 17, 18, 19:
// 13, 14, 15:
this._upgradeDoc();

// 20:
// 16:
/** @type {Deferred} **/
const deferred = this._whenDefinedMap.get(localName);
if (deferred) {