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

Commit

Permalink
Merge pull request #54 from Polymer/master
Browse files Browse the repository at this point in the history
8/15 master -> stable
  • Loading branch information
dfreedm committed Aug 15, 2013
2 parents 3e50d85 + 173bbf6 commit 284aa7f
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 520 deletions.
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

0 comments on commit 284aa7f

Please sign in to comment.