mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Add Polymer.instanceof & isInstance. Fixes #2083.
This commit is contained in:
parent
fab2ed7832
commit
7954f9336f
@ -31,8 +31,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
this._prepAttributes();
|
this._prepAttributes();
|
||||||
// shared behaviors
|
// shared behaviors
|
||||||
this._prepBehaviors();
|
this._prepBehaviors();
|
||||||
// inheritance
|
|
||||||
this._prepExtends();
|
|
||||||
// factory
|
// factory
|
||||||
this._prepConstructor();
|
this._prepConstructor();
|
||||||
},
|
},
|
||||||
|
@ -28,9 +28,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
this._prepAttributes();
|
this._prepAttributes();
|
||||||
// shared behaviors
|
// shared behaviors
|
||||||
this._prepBehaviors();
|
this._prepBehaviors();
|
||||||
// inheritance
|
// factory
|
||||||
this._prepExtends();
|
|
||||||
// factory
|
|
||||||
this._prepConstructor();
|
this._prepConstructor();
|
||||||
// template
|
// template
|
||||||
this._prepTemplate();
|
this._prepTemplate();
|
||||||
|
@ -30,8 +30,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
this._prepIs();
|
this._prepIs();
|
||||||
// attributes
|
// attributes
|
||||||
this._prepAttributes();
|
this._prepAttributes();
|
||||||
// inheritance
|
|
||||||
this._prepExtends();
|
|
||||||
// factory
|
// factory
|
||||||
this._prepConstructor();
|
this._prepConstructor();
|
||||||
// template
|
// template
|
||||||
|
@ -11,6 +11,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
Polymer.Base = {
|
Polymer.Base = {
|
||||||
|
|
||||||
|
// Used for `isInstance` type checking; cannot use `instanceof` because
|
||||||
|
// there is no common Polymer.Base in the prototype chain between type
|
||||||
|
// extensions and normal custom elements
|
||||||
|
__isPolymerInstance__: true,
|
||||||
|
|
||||||
// pluggable features
|
// pluggable features
|
||||||
// `this` context is a prototype, not an instance
|
// `this` context is a prototype, not an instance
|
||||||
_addFeature: function(feature) {
|
_addFeature: function(feature) {
|
||||||
@ -118,6 +123,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype);
|
Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype);
|
||||||
|
|
||||||
|
if (window.CustomElements) {
|
||||||
|
Polymer.instanceof = CustomElements.instanceof;
|
||||||
|
} else {
|
||||||
|
Polymer.instanceof = function(obj, ctor) {
|
||||||
|
return obj instanceof ctor;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Polymer.isInstance = function(obj) {
|
||||||
|
return Boolean(obj && obj.__isPolymerInstance__);
|
||||||
|
};
|
||||||
|
|
||||||
// TODO(sjmiles): ad hoc telemetry
|
// TODO(sjmiles): ad hoc telemetry
|
||||||
Polymer.telemetry.instanceCount = 0;
|
Polymer.telemetry.instanceCount = 0;
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
var fragContent = (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) &&
|
var fragContent = (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) &&
|
||||||
!node.__noContent && Polymer.dom(node).querySelector(CONTENT);
|
!node.__noContent && Polymer.dom(node).querySelector(CONTENT);
|
||||||
var wrappedContent = fragContent &&
|
var wrappedContent = fragContent &&
|
||||||
(Polymer.dom(fragContent).parentNode.nodeType !==
|
(Polymer.dom(fragContent).parentNode.nodeType !==
|
||||||
Node.DOCUMENT_FRAGMENT_NODE);
|
Node.DOCUMENT_FRAGMENT_NODE);
|
||||||
var hasContent = fragContent || (node.localName === CONTENT);
|
var hasContent = fragContent || (node.localName === CONTENT);
|
||||||
// There are 2 possible cases where a distribution may need to occur:
|
// There are 2 possible cases where a distribution may need to occur:
|
||||||
@ -231,8 +231,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
|
return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
|
||||||
},
|
},
|
||||||
|
|
||||||
// NOTE: if `ensureComposedRemoval` is true then the node should be
|
// NOTE: if `ensureComposedRemoval` is true then the node should be
|
||||||
// removed from its composed parent.
|
// removed from its composed parent.
|
||||||
_removeNodeFromHost: function(node, ensureComposedRemoval) {
|
_removeNodeFromHost: function(node, ensureComposedRemoval) {
|
||||||
var hostNeedsDist;
|
var hostNeedsDist;
|
||||||
var root;
|
var root;
|
||||||
@ -459,7 +459,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
importNode: function(externalNode, deep) {
|
importNode: function(externalNode, deep) {
|
||||||
// for convenience use this node's ownerDoc if the node isn't a document
|
// for convenience use this node's ownerDoc if the node isn't a document
|
||||||
var doc = this.node instanceof HTMLDocument ? this.node :
|
var doc = this.node instanceof Document ? this.node :
|
||||||
this.node.ownerDocument;
|
this.node.ownerDocument;
|
||||||
var n = nativeImportNode.call(doc, externalNode, false);
|
var n = nativeImportNode.call(doc, externalNode, false);
|
||||||
if (deep) {
|
if (deep) {
|
||||||
@ -506,7 +506,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
this.domApi._distributeParent();
|
this.domApi._distributeParent();
|
||||||
},
|
},
|
||||||
contains: function() {
|
contains: function() {
|
||||||
return this.node.classList.contains.apply(this.node.classList,
|
return this.node.classList.contains.apply(this.node.classList,
|
||||||
arguments);
|
arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -682,7 +682,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
}
|
}
|
||||||
|
|
||||||
DomApi.prototype.importNode = function(externalNode, deep) {
|
DomApi.prototype.importNode = function(externalNode, deep) {
|
||||||
var doc = this.node instanceof HTMLDocument ? this.node :
|
var doc = this.node instanceof Document ? this.node :
|
||||||
this.node.ownerDocument;
|
this.node.ownerDocument;
|
||||||
return doc.importNode(externalNode, deep);
|
return doc.importNode(externalNode, deep);
|
||||||
}
|
}
|
||||||
@ -776,8 +776,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
function getLightChildren(node) {
|
function getLightChildren(node) {
|
||||||
var children = node._lightChildren;
|
var children = node._lightChildren;
|
||||||
// TODO(sorvell): it's more correct to use _composedChildren instead of
|
// TODO(sorvell): it's more correct to use _composedChildren instead of
|
||||||
// childNodes here but any trivial failure to use Polymer.dom
|
// childNodes here but any trivial failure to use Polymer.dom
|
||||||
// will result in an error so we avoid using _composedChildren
|
// will result in an error so we avoid using _composedChildren
|
||||||
return children ? children : node.childNodes;
|
return children ? children : node.childNodes;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
};
|
};
|
||||||
|
|
||||||
var desugar = function(prototype) {
|
var desugar = function(prototype) {
|
||||||
prototype = Polymer.Base.chainObject(prototype, Polymer.Base);
|
// Note: need to chain user prorotype with the correct type-extended
|
||||||
|
// version of Polymer.Base; this is especially important when you can't
|
||||||
|
// prototype swizzle (e.g. IE10), since CustomElemets uses getPrototypeOf
|
||||||
|
var base = Polymer.Base;
|
||||||
|
if (prototype.extends) {
|
||||||
|
base = Polymer.Base._getExtendedPrototype(prototype.extends);
|
||||||
|
}
|
||||||
|
prototype = Polymer.Base.chainObject(prototype, base);
|
||||||
prototype.registerCallback();
|
prototype.registerCallback();
|
||||||
return prototype.constructor;
|
return prototype.constructor;
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,6 @@ elements to the template itself as the binding scope.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_registerFeatures: function() {
|
_registerFeatures: function() {
|
||||||
this._prepExtends();
|
|
||||||
this._prepConstructor();
|
this._prepConstructor();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -47,12 +47,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
Polymer.Base._addFeature({
|
Polymer.Base._addFeature({
|
||||||
|
|
||||||
_prepExtends: function() {
|
|
||||||
if (this.extends) {
|
|
||||||
this.__proto__ = this._getExtendedPrototype(this.extends);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getExtendedPrototype: function(tag) {
|
_getExtendedPrototype: function(tag) {
|
||||||
return this._getExtendedNativePrototype(tag);
|
return this._getExtendedNativePrototype(tag);
|
||||||
},
|
},
|
||||||
|
@ -55,7 +55,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
_findStyleHost: function() {
|
_findStyleHost: function() {
|
||||||
var e = this, root;
|
var e = this, root;
|
||||||
while (root = Polymer.dom(e).getOwnerRoot()) {
|
while (root = Polymer.dom(e).getOwnerRoot()) {
|
||||||
if (root.host && root.host._computeStyleProperties) {
|
if (Polymer.isInstance(root.host)) {
|
||||||
return root.host;
|
return root.host;
|
||||||
}
|
}
|
||||||
e = root.host;
|
e = root.host;
|
||||||
@ -174,8 +174,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
serializeValueToAttribute: function(value, attribute, node) {
|
serializeValueToAttribute: function(value, attribute, node) {
|
||||||
// override to ensure whenever classes are set, we need to shim them.
|
// override to ensure whenever classes are set, we need to shim them.
|
||||||
node = node || this;
|
node = node || this;
|
||||||
if (attribute === 'class') {
|
if (attribute === 'class' && !nativeShadow) {
|
||||||
// host needed to scope styling.
|
// host needed to scope styling.
|
||||||
|
// Under Shady DOM, domHost is safe to use here because we know it
|
||||||
|
// is a Polymer element
|
||||||
var host = node === this ? (this.domHost || this.dataHost) : this;
|
var host = node === this ? (this.domHost || this.dataHost) : this;
|
||||||
if (host) {
|
if (host) {
|
||||||
value = host._scopeElementClass(node, value);
|
value = host._scopeElementClass(node, value);
|
||||||
@ -206,7 +208,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
* been made that affect the values of custom properties.
|
* been made that affect the values of custom properties.
|
||||||
*
|
*
|
||||||
* @method updateStyles
|
* @method updateStyles
|
||||||
* @param {Object=} properties Properties object which is mixed into
|
* @param {Object=} properties Properties object which is mixed into
|
||||||
* the element's `customStyle` property. This argument provides a shortcut
|
* the element's `customStyle` property. This argument provides a shortcut
|
||||||
* for setting `customStyle` and then calling `updateStyles`.
|
* for setting `customStyle` and then calling `updateStyles`.
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +42,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
suite('constructor', function() {
|
suite('type checking & constructor', function() {
|
||||||
|
|
||||||
|
test('Polymer.isInstance for non-instance', function() {
|
||||||
|
var el = document.createElement('div');
|
||||||
|
assert.isTrue(Polymer.instanceof(el, HTMLElement));
|
||||||
|
assert.isTrue(Polymer.instanceof(el, HTMLDivElement));
|
||||||
|
assert.isFalse(Polymer.isInstance(el));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('document.createElement', function() {
|
||||||
|
var MyElement = Polymer({is: 'my-basic'});
|
||||||
|
var el = document.createElement('my-basic');
|
||||||
|
assert.isTrue(Polymer.instanceof(el, HTMLElement));
|
||||||
|
assert.isTrue(Polymer.instanceof(el, MyElement));
|
||||||
|
assert.isTrue(Polymer.isInstance(el));
|
||||||
|
});
|
||||||
|
|
||||||
test('normal constructor', function() {
|
test('normal constructor', function() {
|
||||||
var MyElement = Polymer({is: 'my-element'});
|
var MyElement = Polymer({is: 'my-element'});
|
||||||
@ -53,6 +68,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
assert.instanceOf(el, MyElement, 'Instance of MyElement');
|
assert.instanceOf(el, MyElement, 'Instance of MyElement');
|
||||||
}
|
}
|
||||||
assert.instanceOf(el, HTMLElement, 'Instance of HTMLElement');
|
assert.instanceOf(el, HTMLElement, 'Instance of HTMLElement');
|
||||||
|
assert.isTrue(Polymer.instanceof(el, HTMLElement));
|
||||||
|
assert.isTrue(Polymer.instanceof(el, MyElement));
|
||||||
|
assert.isTrue(Polymer.isInstance(el));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('type-extension constructor', function() {
|
test('type-extension constructor', function() {
|
||||||
@ -62,8 +80,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
if (Object.__proto__) {
|
if (Object.__proto__) {
|
||||||
// instanceof Constructor only supported where proto swizzling is possible
|
// instanceof Constructor only supported where proto swizzling is possible
|
||||||
assert.instanceOf(el, MyInput, 'Instance of MyInput');
|
assert.instanceOf(el, MyInput, 'Instance of MyInput');
|
||||||
|
assert.instanceOf(el, HTMLElement, 'Instance of HTMLInputElement');
|
||||||
}
|
}
|
||||||
assert.instanceOf(el, HTMLElement, 'Instance of HTMLInputElement');
|
assert.isTrue(Polymer.instanceof(el, HTMLInputElement));
|
||||||
|
assert.isTrue(Polymer.instanceof(el, HTMLElement));
|
||||||
|
assert.isTrue(Polymer.instanceof(el, MyInput));
|
||||||
|
assert.isTrue(Polymer.isInstance(el));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('custom constructor', function() {
|
test('custom constructor', function() {
|
||||||
@ -81,6 +103,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
assert.instanceOf(el, HTMLElement, 'Instance of HTMLElement');
|
assert.instanceOf(el, HTMLElement, 'Instance of HTMLElement');
|
||||||
}
|
}
|
||||||
assert.equal(el.title, 'my title', 'Argument passed to constructor');
|
assert.equal(el.title, 'my title', 'Argument passed to constructor');
|
||||||
|
assert.isTrue(Polymer.instanceof(el, HTMLElement));
|
||||||
|
assert.isTrue(Polymer.instanceof(el, MyElement2));
|
||||||
|
assert.isTrue(Polymer.isInstance(el));
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -531,7 +531,7 @@ suite('Polymer.dom', function() {
|
|||||||
test('Polymer.dom importNode shallow', function() {
|
test('Polymer.dom importNode shallow', function() {
|
||||||
var a = document.createElement('div');
|
var a = document.createElement('div');
|
||||||
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
|
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
|
||||||
var b = Polymer.dom(document).importNode(Polymer.dom(a).firstElementChild);
|
var b = Polymer.dom(wrap(document)).importNode(Polymer.dom(a).firstElementChild);
|
||||||
Polymer.dom(document.body).appendChild(b);
|
Polymer.dom(document.body).appendChild(b);
|
||||||
assert.equal(Polymer.dom(b).childNodes.length, 0, 'shallow import has incorrect children');
|
assert.equal(Polymer.dom(b).childNodes.length, 0, 'shallow import has incorrect children');
|
||||||
if (b.shadyRoot) {
|
if (b.shadyRoot) {
|
||||||
@ -542,7 +542,7 @@ suite('Polymer.dom', function() {
|
|||||||
test('Polymer.dom importNode deep', function() {
|
test('Polymer.dom importNode deep', function() {
|
||||||
var a = document.createElement('div');
|
var a = document.createElement('div');
|
||||||
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
|
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
|
||||||
var b = Polymer.dom(document).importNode(a, true);
|
var b = Polymer.dom(wrap(document)).importNode(a, true);
|
||||||
Polymer.dom(document.body).appendChild(b);
|
Polymer.dom(document.body).appendChild(b);
|
||||||
assert.equal(Polymer.dom(b.firstElementChild).childNodes.length, 2, 'deep copy has incorrect children');
|
assert.equal(Polymer.dom(b.firstElementChild).childNodes.length, 2, 'deep copy has incorrect children');
|
||||||
if (b.shadyRoot) {
|
if (b.shadyRoot) {
|
||||||
|
Loading…
Reference in New Issue
Block a user