Skip to content
Browse files

Add Polymer.instanceof & isInstance. Fixes #2083.

  • Loading branch information...
1 parent fab2ed7 commit 7954f9336fe2b9c972331f54ffcd825f573ca95f @kevinpschaaf kevinpschaaf committed
View
2 polymer-micro.html
@@ -31,8 +31,6 @@
this._prepAttributes();
// shared behaviors
this._prepBehaviors();
- // inheritance
- this._prepExtends();
// factory
this._prepConstructor();
},
View
4 polymer-mini.html
@@ -28,9 +28,7 @@
this._prepAttributes();
// shared behaviors
this._prepBehaviors();
- // inheritance
- this._prepExtends();
- // factory
+ // factory
this._prepConstructor();
// template
this._prepTemplate();
View
2 polymer.html
@@ -30,8 +30,6 @@
this._prepIs();
// attributes
this._prepAttributes();
- // inheritance
- this._prepExtends();
// factory
this._prepConstructor();
// template
View
17 src/lib/base.html
@@ -11,6 +11,11 @@
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
// `this` context is a prototype, not an instance
_addFeature: function(feature) {
@@ -118,6 +123,18 @@
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
Polymer.telemetry.instanceCount = 0;
View
16 src/lib/dom-api.html
@@ -177,7 +177,7 @@
var fragContent = (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) &&
!node.__noContent && Polymer.dom(node).querySelector(CONTENT);
var wrappedContent = fragContent &&
- (Polymer.dom(fragContent).parentNode.nodeType !==
+ (Polymer.dom(fragContent).parentNode.nodeType !==
Node.DOCUMENT_FRAGMENT_NODE);
var hasContent = fragContent || (node.localName === CONTENT);
// There are 2 possible cases where a distribution may need to occur:
@@ -231,8 +231,8 @@
return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
},
- // NOTE: if `ensureComposedRemoval` is true then the node should be
- // removed from its composed parent.
+ // NOTE: if `ensureComposedRemoval` is true then the node should be
+ // removed from its composed parent.
_removeNodeFromHost: function(node, ensureComposedRemoval) {
var hostNeedsDist;
var root;
@@ -459,7 +459,7 @@
importNode: function(externalNode, deep) {
// 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;
var n = nativeImportNode.call(doc, externalNode, false);
if (deep) {
@@ -506,7 +506,7 @@
this.domApi._distributeParent();
},
contains: function() {
- return this.node.classList.contains.apply(this.node.classList,
+ return this.node.classList.contains.apply(this.node.classList,
arguments);
}
}
@@ -682,7 +682,7 @@
}
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;
return doc.importNode(externalNode, deep);
}
@@ -776,8 +776,8 @@
function getLightChildren(node) {
var children = node._lightChildren;
- // TODO(sorvell): it's more correct to use _composedChildren instead of
- // childNodes here but any trivial failure to use Polymer.dom
+ // TODO(sorvell): it's more correct to use _composedChildren instead of
+ // childNodes here but any trivial failure to use Polymer.dom
// will result in an error so we avoid using _composedChildren
return children ? children : node.childNodes;
}
View
9 src/lib/polymer-bootstrap.html
@@ -38,7 +38,14 @@
};
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();
return prototype.constructor;
};
View
1 src/lib/template/dom-bind.html
@@ -72,7 +72,6 @@
},
_registerFeatures: function() {
- this._prepExtends();
this._prepConstructor();
},
View
6 src/micro/extends.html
@@ -47,12 +47,6 @@
Polymer.Base._addFeature({
- _prepExtends: function() {
- if (this.extends) {
- this.__proto__ = this._getExtendedPrototype(this.extends);
- }
- },
-
_getExtendedPrototype: function(tag) {
return this._getExtendedNativePrototype(tag);
},
View
8 src/standard/x-styling.html
@@ -55,7 +55,7 @@
_findStyleHost: function() {
var e = this, root;
while (root = Polymer.dom(e).getOwnerRoot()) {
- if (root.host && root.host._computeStyleProperties) {
+ if (Polymer.isInstance(root.host)) {
return root.host;
}
e = root.host;
@@ -174,8 +174,10 @@
serializeValueToAttribute: function(value, attribute, node) {
// override to ensure whenever classes are set, we need to shim them.
node = node || this;
- if (attribute === 'class') {
+ if (attribute === 'class' && !nativeShadow) {
// 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;
if (host) {
value = host._scopeElementClass(node, value);
@@ -206,7 +208,7 @@
* been made that affect the values of custom properties.
*
* @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
* for setting `customStyle` and then calling `updateStyles`.
*/
View
29 test/unit/micro.html
@@ -42,7 +42,22 @@
});
- 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() {
var MyElement = Polymer({is: 'my-element'});
@@ -53,6 +68,9 @@
assert.instanceOf(el, MyElement, 'Instance of MyElement');
}
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() {
@@ -62,8 +80,12 @@
if (Object.__proto__) {
// instanceof Constructor only supported where proto swizzling is possible
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() {
@@ -81,6 +103,9 @@
assert.instanceOf(el, HTMLElement, 'Instance of HTMLElement');
}
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));
});
});
View
4 test/unit/polymer-dom.js
@@ -531,7 +531,7 @@ suite('Polymer.dom', function() {
test('Polymer.dom importNode shallow', function() {
var a = document.createElement('div');
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);
assert.equal(Polymer.dom(b).childNodes.length, 0, 'shallow import has incorrect children');
if (b.shadyRoot) {
@@ -542,7 +542,7 @@ suite('Polymer.dom', function() {
test('Polymer.dom importNode deep', function() {
var a = document.createElement('div');
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);
assert.equal(Polymer.dom(b.firstElementChild).childNodes.length, 2, 'deep copy has incorrect children');
if (b.shadyRoot) {

0 comments on commit 7954f93

Please sign in to comment.
Something went wrong with that request. Please try again.