mirror of
https://github.com/jlengrand/webcomponentsjs.git
synced 2026-03-10 08:51:22 +00:00
Add sync setAttribute, removeAttribute, and importNode
This commit is contained in:
@@ -402,7 +402,7 @@ var Deferred;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {!NodeList<!Node>} nodeList
|
||||
* @param {!(NodeList<!Node>|Array<!Node>)} nodeList
|
||||
* @param {?Set<Node>=} visitedNodes
|
||||
* @private
|
||||
*/
|
||||
@@ -556,8 +556,8 @@ var Deferred;
|
||||
element.__proto__ = prototype;
|
||||
if (callConstructor) {
|
||||
this._setNewInstance(element);
|
||||
element.__upgraded = true;
|
||||
new (definition.constructor)();
|
||||
element.__upgraded = true;
|
||||
console.assert(this._newInstance == null);
|
||||
}
|
||||
|
||||
@@ -597,8 +597,11 @@ var Deferred;
|
||||
var name = /** @type {!string} */(mutation.attributeName);
|
||||
var oldValue = mutation.oldValue;
|
||||
var newValue = target.getAttribute(name);
|
||||
var namespace = mutation.attributeNamespace;
|
||||
definition.attributeChangedCallback.call(target, name, oldValue, newValue, namespace);
|
||||
// Skip changes that were handled synchronously by setAttribute
|
||||
if (newValue !== oldValue) {
|
||||
var namespace = mutation.attributeNamespace;
|
||||
definition.attributeChangedCallback.call(target, name, oldValue, newValue, namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -780,6 +783,50 @@ var Deferred;
|
||||
});
|
||||
}
|
||||
|
||||
// patch doc.importNode
|
||||
|
||||
var rawImportNode = doc.importNode;
|
||||
doc.importNode = function(node, deep) {
|
||||
var clone = rawImportNode.call(doc, node, deep);
|
||||
var customElements = win['customElements'];
|
||||
/** @type {CustomElementsRegistry} */(window['customElements'])._addNodes(isElement(clone) ? [clone] : clone.childNodes);
|
||||
return clone;
|
||||
};
|
||||
|
||||
// patch Element.setAttribute & removeAttribute
|
||||
|
||||
var _origSetAttribute = Element.prototype.setAttribute;
|
||||
Element.prototype['setAttribute'] = function(name, value) {
|
||||
changeAttribute(this, name, value, _origSetAttribute);
|
||||
};
|
||||
var _origRemoveAttribute = Element.prototype.removeAttribute;
|
||||
Element.prototype['removeAttribute'] = function(name) {
|
||||
changeAttribute(this, name, null, _origRemoveAttribute);
|
||||
};
|
||||
|
||||
function changeAttribute(element, name, value, operation) {
|
||||
name = name.toLowerCase();
|
||||
var oldValue = element.getAttribute(name);
|
||||
operation.call(element, name, value);
|
||||
// Bail if this wasn't a fully upgraded custom element
|
||||
if (element.__upgraded == true) {
|
||||
var definition = window['customElements']._definitions.get(element.localName);
|
||||
if (definition.observedAttributes.indexOf(name) >= 0) {
|
||||
var newValue = element.getAttribute(name);
|
||||
if (newValue !== oldValue) {
|
||||
element.attributeChangedCallback(name, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {CustomElementsRegistry} */
|
||||
window['customElements'] = new CustomElementsRegistry();
|
||||
|
||||
// // TODO(justinfagnani): Remove. Temporary for backward-compatibility
|
||||
window['CustomElements'] = {
|
||||
takeRecords() {
|
||||
if (window['customElements'].flush) window['customElements'].flush();
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -375,20 +375,7 @@ suite('Custom Element Reactions', function() {
|
||||
|
||||
suite('clone/import/adopt', function() {
|
||||
|
||||
test('cloned custom elements are not customized', function() {
|
||||
class XCloned extends HTMLElement {}
|
||||
customElements.define('x-cloned', XCloned);
|
||||
|
||||
var original = document.createElement('x-cloned');
|
||||
customElements.flush();
|
||||
assert.instanceOf(original, XCloned);
|
||||
|
||||
var imported = document.importNode(original, true);
|
||||
customElements.flush();
|
||||
assert.notInstanceOf(imported, XCloned);
|
||||
});
|
||||
|
||||
test('imported custom elements are not customized', function() {
|
||||
test('imported custom elements are customized', function() {
|
||||
class XImported extends HTMLElement {}
|
||||
customElements.define('x-imported', XImported);
|
||||
|
||||
@@ -400,10 +387,23 @@ suite('Custom Element Reactions', function() {
|
||||
|
||||
var imported = document.importNode(original, true);
|
||||
customElements.flush();
|
||||
assert.notInstanceOf(imported, XImported);
|
||||
assert.instanceOf(imported, XImported);
|
||||
});
|
||||
|
||||
test('adopted custom elements are not customized', function() {
|
||||
test.skip('cloned custom elements are customized', function() {
|
||||
class XCloned extends HTMLElement {}
|
||||
customElements.define('x-cloned', XCloned);
|
||||
|
||||
var original = document.createElement('x-cloned');
|
||||
customElements.flush();
|
||||
assert.instanceOf(original, XCloned);
|
||||
|
||||
var imported = original.cloneNode(true);
|
||||
customElements.flush();
|
||||
assert.instanceOf(imported, XCloned);
|
||||
});
|
||||
|
||||
test.skip('adopted custom elements are customized', function() {
|
||||
class XAdopted extends HTMLElement {}
|
||||
customElements.define('x-adopted', XAdopted);
|
||||
|
||||
@@ -413,7 +413,7 @@ suite('Custom Element Reactions', function() {
|
||||
// x-adopted is not defined in its document
|
||||
assert.notInstanceOf(original, XAdopted);
|
||||
|
||||
var imported = document.importNode(original, true);
|
||||
var imported = document.adoptNode(original);
|
||||
customElements.flush();
|
||||
assert.notInstanceOf(imported, XAdopted);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user