Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

8/15 master -> stable #54

Merged
merged 10 commits into from
Aug 15, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ The `<element>` tag provides a mechanism to encapsulate HTML, CSS, and JavaScrip
// Has built-in 'window' protection.
this.register({
prototype: {
readyCallback: function() {
createdCallback: function() {
this.innerHTML = section.innerHTML;
},
foo: function() {
Expand Down Expand Up @@ -69,7 +69,7 @@ As before, custom elements built this way work just like standard elements.
Here's the imperative version of the previous example:

var XFooPrototype = Object.create(HTMLElement.prototype);
XFooPrototype.readyCallback = function() {
XFooPrototype.createdCallback = function() {
this.textContent = "I'm an x-foo!";
};
XFooPrototype.foo = function() {
Expand All @@ -90,7 +90,7 @@ declare the type using the `extends` option when calling `document.register()`:
Example extending `button`:

var XFooButtonPrototype = Object.create(HTMLButtonElement.prototype);
XFooButtonPrototype.readyCallback = function() {
XFooButtonPrototype.createdCallback = function() {
this.textContent = "I'm an x-foo button!";
};

Expand Down Expand Up @@ -121,7 +121,7 @@ This can also be used to create an instance:
xFooButton.foo(); // "foo() called"

Browser limitations require that we supply the constructor while you supply the `prototype`.
Use the `readyCallback` to do initialization work that might otherwise be in a constructor.
Use the `createdCallback` to do initialization work that might otherwise be in a constructor.

## Polyfill details

Expand Down Expand Up @@ -152,12 +152,12 @@ Example:

The Custom Elements specification is still under discussion. The polyfill implements certain features in advance of the specification. In particular, there are several notification callback methods that are used if implemented on the element prototype.

* `readyCallback()` is called when a custom element is created.
* `insertedCallback()` is called when a custom element is inserted into a DOM subtree.
* `removedCallback()` is called when a custom element is removed from a DOM subtree.
* `createdCallback()` is called when a custom element is created.
* `enteredDocumentCallback()` is called when a custom element is inserted into a DOM subtree.
* `leftDocumentCallback()` is called when a custom element is removed from a DOM subtree.
* `attributeChangedCallback(attributeName)` is called when a custom element's attribute value has changed

`readyCallback` is invoked _synchronously_ with element instantiation, the other callbacks are called _asyncronously_. The asynchronous callbacks generally use the MutationObserver timing model, which means they are called before layouts, paints, or other triggered events, so the developer need not worry about flashing content or other bad things happening before the callback has a chance to react to changes.
`createdCallback` is invoked _synchronously_ with element instantiation, the other callbacks are called _asyncronously_. The asynchronous callbacks generally use the MutationObserver timing model, which means they are called before layouts, paints, or other triggered events, so the developer need not worry about flashing content or other bad things happening before the callback has a chance to react to changes.

The `extends` option to `document.register()` (discussed above) is exclusive to this polyfill.

Expand Down
1 change: 0 additions & 1 deletion build.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"src/MutationObserver.js",
"src/Observer.js",
"src/CustomElements.js",
"src/HTMLElementElement.js",
"src/Parser.js",
"src/boot.js"
]
5 changes: 2 additions & 3 deletions custom-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ var modules = [
'src/MutationObserver.js',
'src/Observer.js',
'src/CustomElements.js',
'src/HTMLElementElement.js',
'src/Parser.js',
'src/boot.js'
];
Expand All @@ -32,10 +31,10 @@ var script = document.querySelector('script[src*="' + thisFile + '"]');
var src = script.attributes.src.value;
var basePath = src.slice(0, src.indexOf(thisFile));

if (!window.Loader) {
if (!window.PolymerLoader) {
var path = basePath + 'tools/loader/loader.js';
document.write('<script src="' + path + '"></script>');
}
document.write('<script>Loader.load("' + scopeName + '")</script>');
document.write('<script>PolymerLoader.load("' + scopeName + '")</script>');

})();
21 changes: 12 additions & 9 deletions src/CustomElements.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ if (useNative) {

scope.watchShadow = nop;
scope.watchAllShadows = nop;
scope.upgrade = nop;
scope.upgradeAll = nop;
scope.upgradeSubtree = nop;
scope.observeDocument = nop;
Expand Down Expand Up @@ -211,10 +212,10 @@ if (useNative) {
// flag as upgraded
inElement.__upgraded__ = true;
// there should never be a shadow root on inElement at this point
// we require child nodes be upgraded before ready
// we require child nodes be upgraded before `created`
scope.upgradeSubtree(inElement);
// lifecycle management
ready(inElement);
created(inElement);
// OUTPUT
return inElement;
}
Expand Down Expand Up @@ -256,10 +257,10 @@ if (useNative) {
}
}

function ready(inElement) {
// invoke readyCallback
if (inElement.readyCallback) {
inElement.readyCallback();
function created(inElement) {
// invoke createdCallback
if (inElement.createdCallback) {
inElement.createdCallback();
}
}

Expand Down Expand Up @@ -302,12 +303,14 @@ if (useNative) {
};
}

function createElement(inTag) {
var definition = registry[inTag];
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();
}
return domCreateElement(inTag);
return domCreateElement(tag, typeExtension);
}

function upgradeElement(inElement) {
Expand Down
134 changes: 0 additions & 134 deletions src/HTMLElementElement.js

This file was deleted.

12 changes: 6 additions & 6 deletions src/Observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function inserted(element) {
// TODO(sjmiles): when logging, do work on all custom elements so we can
// track behavior even when callbacks not defined
//console.log('inserted: ', element.localName);
if (element.insertedCallback || (element.__upgraded__ && logFlags.dom)) {
if (element.enteredDocumentCallback || (element.__upgraded__ && logFlags.dom)) {
logFlags.dom && console.group('inserted:', element.localName);
if (inDocument(element)) {
element.__inserted = (element.__inserted || 0) + 1;
Expand All @@ -130,9 +130,9 @@ function inserted(element) {
if (element.__inserted > 1) {
logFlags.dom && console.warn('inserted:', element.localName,
'insert/remove count:', element.__inserted)
} else if (element.insertedCallback) {
} else if (element.enteredDocumentCallback) {
logFlags.dom && console.log('inserted:', element.localName);
element.insertedCallback();
element.enteredDocumentCallback();
}
}
logFlags.dom && console.groupEnd();
Expand All @@ -149,7 +149,7 @@ function removedNode(node) {
function removed(element) {
// TODO(sjmiles): temporary: do work on all custom elements so we can track
// behavior even when callbacks not defined
if (element.removedCallback || (element.__upgraded__ && logFlags.dom)) {
if (element.leftDocumentCallback || (element.__upgraded__ && logFlags.dom)) {
logFlags.dom && console.log('removed:', element.localName);
if (!inDocument(element)) {
element.__inserted = (element.__inserted || 0) - 1;
Expand All @@ -161,8 +161,8 @@ function removed(element) {
if (element.__inserted < 0) {
logFlags.dom && console.warn('removed:', element.localName,
'insert/remove count:', element.__inserted)
} else if (element.removedCallback) {
element.removedCallback();
} else if (element.leftDocumentCallback) {
element.leftDocumentCallback();
}
}
}
Expand Down
9 changes: 2 additions & 7 deletions src/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none

var parser = {
selectors: [
'link[rel=' + IMPORT_LINK_TYPE + ']',
'element'
'link[rel=' + IMPORT_LINK_TYPE + ']'
],
map: {
link: 'parseLink',
element: 'parseElement'
link: 'parseLink'
},
parse: function(inDocument) {
if (!inDocument.__parsed) {
Expand Down Expand Up @@ -48,9 +46,6 @@ var parser = {
if (linkElt.content) {
parser.parse(linkElt.content);
}
},
parseElement: function(inElementElt) {
new HTMLElementElement(inElementElt);
}
};

Expand Down
39 changes: 17 additions & 22 deletions test/html/attributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,24 @@
<script src="../../custom-elements.js"></script>
</head>
<body>
<element name="x-foo">
<script>
(this !== window) && this.register({
prototype: {
removeAttributeOk: false,
setAttributeOk: false,
attributeChangedOk: false,
removeAttribute: function(name) {
this.removeAttributeOk = true;
return HTMLElement.prototype.removeAttribute.call(this, name);
},
setAttribute: function(name, value) {
this.setAttributeOk = true;
HTMLElement.prototype.setAttribute.call(this, name, value);
},
attributeChangedCallback: function(name) {
this.attributeChangedOk = (name == 'squid');
}
}
});
</script>
</element>
<script>
var prototype = Object.create(HTMLElement.prototype);
prototype.removeAttributeOk = false;
prototype.setAttributeOk = false;
prototype.attributeChangedOk = false;
prototype.removeAttribute = function(name) {
this.removeAttributeOk = true;
return HTMLElement.prototype.removeAttribute.call(this, name);
};
prototype.setAttribute = function(name, value) {
this.setAttributeOk = true;
HTMLElement.prototype.setAttribute.call(this, name, value);
};
prototype.attributeChangedCallback = function(name) {
this.attributeChangedOk = (name == 'squid');
};
document.register('x-foo', {prototype: prototype});

addEventListener('WebComponentsReady', function() {
var xfoo = document.createElement('x-foo');
chai.assert.isFalse(xfoo.removeAttributeOk);
Expand Down
Loading