diff --git a/src/ShadowRenderer.js b/src/ShadowRenderer.js
index 42732b6..1c9079e 100644
--- a/src/ShadowRenderer.js
+++ b/src/ShadowRenderer.js
@@ -14,6 +14,7 @@
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var oneOf = scope.oneOf;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
@@ -484,7 +485,7 @@
},
associateNode: function(node) {
- node.impl.polymerShadowRenderer_ = this;
+ unsafeUnwrap(node).polymerShadowRenderer_ = this;
}
};
@@ -607,7 +608,7 @@
* This gets called when a node was added or removed to it.
*/
Node.prototype.invalidateShadowRenderer = function(force) {
- var renderer = this.impl.polymerShadowRenderer_;
+ var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
if (renderer) {
renderer.invalidate();
return true;
@@ -638,7 +639,7 @@
var renderer;
if (shadowRoot)
renderer = getRendererForShadowRoot(shadowRoot);
- this.impl.polymerShadowRenderer_ = renderer;
+ unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
if (renderer)
renderer.invalidate();
};
diff --git a/src/querySelector.js b/src/querySelector.js
index 96bf2ec..b6b97cb 100644
--- a/src/querySelector.js
+++ b/src/querySelector.js
@@ -8,6 +8,7 @@
var HTMLCollection = scope.wrappers.HTMLCollection;
var NodeList = scope.wrappers.NodeList;
var getTreeScope = scope.getTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var originalDocumentQuerySelector = document.querySelector;
@@ -37,7 +38,7 @@
}
result[index++] = wrappedItem;
}
-
+
return index;
}
@@ -98,7 +99,7 @@
// http://www.w3.org/TR/css3-selectors/#simple-selectors
function querySelectorAllFiltered (p, index, result, selector) {
- var target = this.impl;
+ var target = unsafeUnwrap(this);
var list;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
@@ -120,7 +121,7 @@
var SelectorsInterface = {
querySelector: function(selector) {
- var target = this.impl;
+ var target = unsafeUnwrap(this);
var wrappedItem;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
@@ -165,7 +166,7 @@
};
function getElementsByTagNameFiltered (p, index, result, localName, lowercase) {
- var target = this.impl;
+ var target = unsafeUnwrap(this);
var list;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
@@ -186,7 +187,7 @@
}
function getElementsByTagNameNSFiltered (p, index, result, ns, localName) {
- var target = this.impl;
+ var target = unsafeUnwrap(this);
var list;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
diff --git a/src/wrappers.js b/src/wrappers.js
index 527cdb5..0e5bc15 100644
--- a/src/wrappers.js
+++ b/src/wrappers.js
@@ -136,23 +136,31 @@ window.ShadowDOMPolyfill = {};
return /^\w[a-zA-Z_0-9]*$/.test(name);
}
+ // The name of the implementation property is intentionally hard to
+ // remember. Unfortunately, browsers are slower doing obj[expr] than
+ // obj.foo so we resort to repeat this ugly name. This ugly name is never
+ // used outside of this file though.
+
function getGetter(name) {
return hasEval && isIdentifierName(name) ?
- new Function('return this.impl.' + name) :
- function() { return this.impl[name]; };
+ new Function('return this.__impl4cf1e782hg__.' + name) :
+ function() { return this.__impl4cf1e782hg__[name]; };
}
function getSetter(name) {
return hasEval && isIdentifierName(name) ?
- new Function('v', 'this.impl.' + name + ' = v') :
- function(v) { this.impl[name] = v; };
+ new Function('v', 'this.__impl4cf1e782hg__.' + name + ' = v') :
+ function(v) { this.__impl4cf1e782hg__[name] = v; };
}
function getMethod(name) {
return hasEval && isIdentifierName(name) ?
- new Function('return this.impl.' + name +
- '.apply(this.impl, arguments)') :
- function() { return this.impl[name].apply(this.impl, arguments); };
+ new Function('return this.__impl4cf1e782hg__.' + name +
+ '.apply(this.__impl4cf1e782hg__, arguments)') :
+ function() {
+ return this.__impl4cf1e782hg__[name].apply(
+ this.__impl4cf1e782hg__, arguments);
+ };
}
function getDescriptor(source, name) {
@@ -273,41 +281,12 @@ window.ShadowDOMPolyfill = {};
return GeneratedWrapper;
}
- var OriginalDOMImplementation = window.DOMImplementation;
- var OriginalEventTarget = window.EventTarget;
- var OriginalEvent = window.Event;
- var OriginalNode = window.Node;
- var OriginalWindow = window.Window;
- var OriginalRange = window.Range;
- var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
- var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
- var OriginalSVGElementInstance = window.SVGElementInstance;
- var OriginalFormData = window.FormData;
-
function isWrapper(object) {
- return object instanceof wrappers.EventTarget ||
- object instanceof wrappers.Event ||
- object instanceof wrappers.Range ||
- object instanceof wrappers.DOMImplementation ||
- object instanceof wrappers.CanvasRenderingContext2D ||
- object instanceof wrappers.FormData ||
- wrappers.WebGLRenderingContext &&
- object instanceof wrappers.WebGLRenderingContext;
+ return object && object.__impl4cf1e782hg__;
}
function isNative(object) {
- return OriginalEventTarget && object instanceof OriginalEventTarget ||
- object instanceof OriginalNode ||
- object instanceof OriginalEvent ||
- object instanceof OriginalWindow ||
- object instanceof OriginalRange ||
- object instanceof OriginalDOMImplementation ||
- object instanceof OriginalCanvasRenderingContext2D ||
- object instanceof OriginalFormData ||
- OriginalWebGLRenderingContext &&
- object instanceof OriginalWebGLRenderingContext ||
- OriginalSVGElementInstance &&
- object instanceof OriginalSVGElementInstance;
+ return !isWrapper(object);
}
/**
@@ -321,8 +300,8 @@ window.ShadowDOMPolyfill = {};
return null;
assert(isNative(impl));
- return impl.polymerWrapper_ ||
- (impl.polymerWrapper_ = new (getWrapperConstructor(impl))(impl));
+ return impl.__wrapper8e3dd93a60__ ||
+ (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
}
/**
@@ -334,7 +313,16 @@ window.ShadowDOMPolyfill = {};
if (wrapper === null)
return null;
assert(isWrapper(wrapper));
- return wrapper.impl;
+ return wrapper.__impl4cf1e782hg__;
+ }
+
+ function unsafeUnwrap(wrapper) {
+ return wrapper.__impl4cf1e782hg__;
+ }
+
+ function setWrapper(impl, wrapper) {
+ wrapper.__impl4cf1e782hg__ = impl;
+ impl.__wrapper8e3dd93a60__ = wrapper;
}
/**
@@ -366,7 +354,7 @@ window.ShadowDOMPolyfill = {};
return;
assert(isNative(node));
assert(wrapper === undefined || isWrapper(wrapper));
- node.polymerWrapper_ = wrapper;
+ node.__wrapper8e3dd93a60__ = wrapper;
}
var getterDescriptor = {
@@ -382,7 +370,7 @@ window.ShadowDOMPolyfill = {};
function defineWrapGetter(constructor, name) {
defineGetter(constructor, name, function() {
- return wrap(this.impl[name]);
+ return wrap(this.__impl4cf1e782hg__[name]);
});
}
@@ -417,6 +405,8 @@ window.ShadowDOMPolyfill = {};
scope.registerObject = registerObject;
scope.registerWrapper = register;
scope.rewrap = rewrap;
+ scope.setWrapper = setWrapper;
+ scope.unsafeUnwrap = unsafeUnwrap;
scope.unwrap = unwrap;
scope.unwrapIfNeeded = unwrapIfNeeded;
scope.wrap = wrap;
diff --git a/src/wrappers/CanvasRenderingContext2D.js b/src/wrappers/CanvasRenderingContext2D.js
index 5d600d6..dcbfef6 100644
--- a/src/wrappers/CanvasRenderingContext2D.js
+++ b/src/wrappers/CanvasRenderingContext2D.js
@@ -7,6 +7,8 @@
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -14,22 +16,22 @@
var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
function CanvasRenderingContext2D(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
mixin(CanvasRenderingContext2D.prototype, {
get canvas() {
- return wrap(this.impl.canvas);
+ return wrap(unsafeUnwrap(this).canvas);
},
drawImage: function() {
arguments[0] = unwrapIfNeeded(arguments[0]);
- this.impl.drawImage.apply(this.impl, arguments);
+ unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
},
createPattern: function() {
arguments[0] = unwrap(arguments[0]);
- return this.impl.createPattern.apply(this.impl, arguments);
+ return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
}
});
diff --git a/src/wrappers/CharacterData.js b/src/wrappers/CharacterData.js
index e2655ff..061da86 100644
--- a/src/wrappers/CharacterData.js
+++ b/src/wrappers/CharacterData.js
@@ -10,6 +10,7 @@
var enqueueMutation = scope.enqueueMutation;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var OriginalCharacterData = window.CharacterData;
@@ -25,14 +26,14 @@
this.data = value;
},
get data() {
- return this.impl.data;
+ return unsafeUnwrap(this).data;
},
set data(value) {
- var oldValue = this.impl.data;
+ var oldValue = unsafeUnwrap(this).data;
enqueueMutation(this, 'characterData', {
oldValue: oldValue
});
- this.impl.data = value;
+ unsafeUnwrap(this).data = value;
}
});
diff --git a/src/wrappers/DOMTokenList.js b/src/wrappers/DOMTokenList.js
index d9e4381..84b62e2 100644
--- a/src/wrappers/DOMTokenList.js
+++ b/src/wrappers/DOMTokenList.js
@@ -5,40 +5,43 @@
(function(scope) {
'use strict';
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+
function invalidateClass(el) {
scope.invalidateRendererBasedOnAttribute(el, 'class');
}
function DOMTokenList(impl, ownerElement) {
- this.impl = impl;
+ setWrapper(impl, this);
this.ownerElement_ = ownerElement;
}
DOMTokenList.prototype = {
get length() {
- return this.impl.length;
+ return unsafeUnwrap(this).length;
},
item: function(index) {
- return this.impl.item(index);
+ return unsafeUnwrap(this).item(index);
},
contains: function(token) {
- return this.impl.contains(token);
+ return unsafeUnwrap(this).contains(token);
},
add: function() {
- this.impl.add.apply(this.impl, arguments);
+ unsafeUnwrap(this).add.apply(unsafeUnwrap(this), arguments);
invalidateClass(this.ownerElement_);
},
remove: function() {
- this.impl.remove.apply(this.impl, arguments);
+ unsafeUnwrap(this).remove.apply(unsafeUnwrap(this), arguments);
invalidateClass(this.ownerElement_);
},
toggle: function(token) {
- var rv = this.impl.toggle.apply(this.impl, arguments);
+ var rv = unsafeUnwrap(this).toggle.apply(unsafeUnwrap(this), arguments);
invalidateClass(this.ownerElement_);
return rv;
},
toString: function() {
- return this.impl.toString();
+ return unsafeUnwrap(this).toString();
}
};
diff --git a/src/wrappers/Document.js b/src/wrappers/Document.js
index 8769773..6f0b5d6 100644
--- a/src/wrappers/Document.js
+++ b/src/wrappers/Document.js
@@ -21,6 +21,8 @@
var registerWrapper = scope.registerWrapper;
var renderAllPending = scope.renderAllPending;
var rewrap = scope.rewrap;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrapEventTargetMethods = scope.wrapEventTargetMethods;
@@ -47,7 +49,7 @@
function wrapMethod(name) {
var original = document[name];
Document.prototype[name] = function() {
- return wrap(original.apply(this.impl, arguments));
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
};
}
@@ -66,7 +68,7 @@
var originalAdoptNode = document.adoptNode;
function adoptNodeNoRemove(node, doc) {
- originalAdoptNode.call(doc.impl, unwrap(node));
+ originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
adoptSubtree(node, doc);
}
@@ -99,7 +101,7 @@
return elementFromPoint(this, this, x, y);
},
importNode: function(node, deep) {
- return cloneNode(node, deep, this.impl);
+ return cloneNode(node, deep, unsafeUnwrap(this));
},
getSelection: function() {
renderAllPending();
@@ -194,7 +196,7 @@
return document.createElement(tagName);
}
}
- this.impl = node;
+ setWrapper(node, this);
}
CustomElementConstructor.prototype = prototype;
CustomElementConstructor.prototype.constructor = CustomElementConstructor;
@@ -291,20 +293,20 @@
]);
function DOMImplementation(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
function wrapImplMethod(constructor, name) {
var original = document.implementation[name];
constructor.prototype[name] = function() {
- return wrap(original.apply(this.impl, arguments));
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
};
}
function forwardImplMethod(constructor, name) {
var original = document.implementation[name];
constructor.prototype[name] = function() {
- return original.apply(this.impl, arguments);
+ return original.apply(unsafeUnwrap(this), arguments);
};
}
diff --git a/src/wrappers/Element.js b/src/wrappers/Element.js
index c4c9398..4a199b4 100644
--- a/src/wrappers/Element.js
+++ b/src/wrappers/Element.js
@@ -16,7 +16,7 @@
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrappers = scope.wrappers;
var OriginalElement = window.Element;
@@ -65,7 +65,7 @@
mixin(Element.prototype, {
createShadowRoot: function() {
var newShadowRoot = new wrappers.ShadowRoot(this);
- this.impl.polymerShadowRoot_ = newShadowRoot;
+ unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
var renderer = scope.getRendererForHost(this);
renderer.invalidate();
@@ -74,40 +74,40 @@
},
get shadowRoot() {
- return this.impl.polymerShadowRoot_ || null;
+ return unsafeUnwrap(this).polymerShadowRoot_ || null;
},
// getDestinationInsertionPoints added in ShadowRenderer.js
setAttribute: function(name, value) {
- var oldValue = this.impl.getAttribute(name);
- this.impl.setAttribute(name, value);
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).setAttribute(name, value);
enqueAttributeChange(this, name, oldValue);
invalidateRendererBasedOnAttribute(this, name);
},
removeAttribute: function(name) {
- var oldValue = this.impl.getAttribute(name);
- this.impl.removeAttribute(name);
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).removeAttribute(name);
enqueAttributeChange(this, name, oldValue);
invalidateRendererBasedOnAttribute(this, name);
},
matches: function(selector) {
- return originalMatches.call(this.impl, selector);
+ return originalMatches.call(unsafeUnwrap(this), selector);
},
get classList() {
var list = classListTable.get(this);
if (!list) {
classListTable.set(this,
- list = new DOMTokenList(unwrap(this).classList, this));
+ list = new DOMTokenList(unsafeUnwrap(this).classList, this));
}
return list;
},
get className() {
- return unwrap(this).className;
+ return unsafeUnwrap(this).className;
},
set className(v) {
@@ -115,7 +115,7 @@
},
get id() {
- return unwrap(this).id;
+ return unsafeUnwrap(this).id;
},
set id(v) {
diff --git a/src/wrappers/FormData.js b/src/wrappers/FormData.js
index 9f2c54e..d283c3c 100644
--- a/src/wrappers/FormData.js
+++ b/src/wrappers/FormData.js
@@ -8,15 +8,19 @@
'use strict';
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
var unwrap = scope.unwrap;
var OriginalFormData = window.FormData;
function FormData(formElement) {
- if (formElement instanceof OriginalFormData)
- this.impl = formElement;
- else
- this.impl = new OriginalFormData(formElement && unwrap(formElement));
+ var impl;
+ if (formElement instanceof OriginalFormData) {
+ impl = formElement;
+ } else {
+ impl = new OriginalFormData(formElement && unwrap(formElement));
+ }
+ setWrapper(impl, this);
}
registerWrapper(OriginalFormData, FormData, new OriginalFormData());
diff --git a/src/wrappers/HTMLCanvasElement.js b/src/wrappers/HTMLCanvasElement.js
index 63e3556..7162bf1 100644
--- a/src/wrappers/HTMLCanvasElement.js
+++ b/src/wrappers/HTMLCanvasElement.js
@@ -8,6 +8,7 @@
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
@@ -19,7 +20,7 @@
mixin(HTMLCanvasElement.prototype, {
getContext: function() {
- var context = this.impl.getContext.apply(this.impl, arguments);
+ var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
return context && wrap(context);
}
});
diff --git a/src/wrappers/HTMLElement.js b/src/wrappers/HTMLElement.js
index fdc6b62..b88b710 100644
--- a/src/wrappers/HTMLElement.js
+++ b/src/wrappers/HTMLElement.js
@@ -13,6 +13,7 @@
var nodesWereRemoved = scope.nodesWereRemoved;
var registerWrapper = scope.registerWrapper;
var snapshotNodeList = scope.snapshotNodeList;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrappers = scope.wrappers;
@@ -179,7 +180,7 @@
this instanceof wrappers.HTMLTemplateElement) {
setInnerHTML(this.content, value);
} else {
- this.impl.innerHTML = value;
+ unsafeUnwrap(this).innerHTML = value;
}
var addedNodes = snapshotNodeList(this.childNodes);
@@ -259,7 +260,7 @@
function getter(name) {
return function() {
scope.renderAllPending();
- return this.impl[name];
+ return unsafeUnwrap(this)[name];
};
}
@@ -285,7 +286,7 @@
get: getter(name),
set: function(v) {
scope.renderAllPending();
- this.impl[name] = v;
+ unsafeUnwrap(this)[name] = v;
},
configurable: true,
enumerable: true
@@ -301,7 +302,7 @@
Object.defineProperty(HTMLElement.prototype, name, {
value: function() {
scope.renderAllPending();
- return this.impl[name].apply(this.impl, arguments);
+ return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
},
configurable: true,
enumerable: true
diff --git a/src/wrappers/HTMLTemplateElement.js b/src/wrappers/HTMLTemplateElement.js
index 10ef039..cb13f08 100644
--- a/src/wrappers/HTMLTemplateElement.js
+++ b/src/wrappers/HTMLTemplateElement.js
@@ -8,6 +8,7 @@
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
@@ -56,7 +57,7 @@
mixin(HTMLTemplateElement.prototype, {
get content() {
if (OriginalHTMLTemplateElement)
- return wrap(this.impl.content);
+ return wrap(unsafeUnwrap(this).content);
return contentTable.get(this);
},
diff --git a/src/wrappers/Node.js b/src/wrappers/Node.js
index 64cae73..b52facc 100644
--- a/src/wrappers/Node.js
+++ b/src/wrappers/Node.js
@@ -19,6 +19,7 @@
var registerTransientObservers = scope.registerTransientObservers;
var registerWrapper = scope.registerWrapper;
var setTreeScope = scope.setTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -252,9 +253,9 @@
function cloneNode(node, deep, opt_doc) {
var clone;
if (opt_doc)
- clone = wrap(originalImportNode.call(opt_doc, node.impl, false));
+ clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false));
else
- clone = wrap(originalCloneNode.call(node.impl, false));
+ clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
if (deep) {
for (var child = node.firstChild; child; child = child.nextSibling) {
@@ -397,7 +398,7 @@
if (useNative) {
ensureSameOwnerDocument(this, childWrapper);
clearChildNodes(this);
- originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);
+ originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
} else {
if (!previousNode)
this.firstChild_ = nodes[0];
@@ -407,7 +408,7 @@
this.firstChild_ = this.firstChild;
}
- var parentNode = refNode ? refNode.parentNode : this.impl;
+ var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
// insertBefore refWrapper no matter what the parent is?
if (parentNode) {
@@ -478,7 +479,7 @@
childWrapper.parentNode_ = undefined;
} else {
clearChildNodes(this);
- removeChildOriginalHelper(this.impl, childNode);
+ removeChildOriginalHelper(unsafeUnwrap(this), childNode);
}
if (!surpressMutations) {
@@ -544,7 +545,7 @@
} else {
ensureSameOwnerDocument(this, newChildWrapper);
clearChildNodes(this);
- originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
+ originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper),
oldChildNode);
}
@@ -580,31 +581,31 @@
get parentNode() {
// If the parentNode has not been overridden, use the original parentNode.
return this.parentNode_ !== undefined ?
- this.parentNode_ : wrap(this.impl.parentNode);
+ this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
},
/** @type {Node} */
get firstChild() {
return this.firstChild_ !== undefined ?
- this.firstChild_ : wrap(this.impl.firstChild);
+ this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
},
/** @type {Node} */
get lastChild() {
return this.lastChild_ !== undefined ?
- this.lastChild_ : wrap(this.impl.lastChild);
+ this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
},
/** @type {Node} */
get nextSibling() {
return this.nextSibling_ !== undefined ?
- this.nextSibling_ : wrap(this.impl.nextSibling);
+ this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
},
/** @type {Node} */
get previousSibling() {
return this.previousSibling_ !== undefined ?
- this.previousSibling_ : wrap(this.impl.previousSibling);
+ this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
},
get parentElement() {
@@ -616,7 +617,7 @@
},
get textContent() {
- // TODO(arv): This should fallback to this.impl.textContent if there
+ // TODO(arv): This should fallback to unsafeUnwrap(this).textContent if there
// are no shadow trees below or above the context node.
var s = '';
for (var child = this.firstChild; child; child = child.nextSibling) {
@@ -632,12 +633,12 @@
if (this.invalidateShadowRenderer()) {
removeAllChildNodes(this);
if (textContent !== '') {
- var textNode = this.impl.ownerDocument.createTextNode(textContent);
+ var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
this.appendChild(textNode);
}
} else {
clearChildNodes(this);
- this.impl.textContent = textContent;
+ unsafeUnwrap(this).textContent = textContent;
}
var addedNodes = snapshotNodeList(this.childNodes);
@@ -672,7 +673,7 @@
compareDocumentPosition: function(otherNode) {
// This only wraps, it therefore only operates on the composed DOM and not
// the logical DOM.
- return originalCompareDocumentPosition.call(this.impl,
+ return originalCompareDocumentPosition.call(unsafeUnwrap(this),
unwrapIfNeeded(otherNode));
},
diff --git a/src/wrappers/NodeList.js b/src/wrappers/NodeList.js
index 5004f7e..8c5322a 100644
--- a/src/wrappers/NodeList.js
+++ b/src/wrappers/NodeList.js
@@ -5,6 +5,7 @@
(function(scope) {
'use strict';
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var nonEnumDescriptor = {enumerable: false};
@@ -37,7 +38,8 @@
function addWrapNodeListMethod(wrapperConstructor, name) {
wrapperConstructor.prototype[name] = function() {
- return wrapNodeList(this.impl[name].apply(this.impl, arguments));
+ return wrapNodeList(
+ unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
};
}
diff --git a/src/wrappers/Range.js b/src/wrappers/Range.js
index 7e85aeb..7af9c21 100644
--- a/src/wrappers/Range.js
+++ b/src/wrappers/Range.js
@@ -6,6 +6,8 @@
'use strict';
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -13,78 +15,78 @@
var OriginalRange = window.Range;
function Range(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
Range.prototype = {
get startContainer() {
- return wrap(this.impl.startContainer);
+ return wrap(unsafeUnwrap(this).startContainer);
},
get endContainer() {
- return wrap(this.impl.endContainer);
+ return wrap(unsafeUnwrap(this).endContainer);
},
get commonAncestorContainer() {
- return wrap(this.impl.commonAncestorContainer);
+ return wrap(unsafeUnwrap(this).commonAncestorContainer);
},
setStart: function(refNode,offset) {
- this.impl.setStart(unwrapIfNeeded(refNode), offset);
+ unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
},
setEnd: function(refNode,offset) {
- this.impl.setEnd(unwrapIfNeeded(refNode), offset);
+ unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
},
setStartBefore: function(refNode) {
- this.impl.setStartBefore(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
},
setStartAfter: function(refNode) {
- this.impl.setStartAfter(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
},
setEndBefore: function(refNode) {
- this.impl.setEndBefore(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
},
setEndAfter: function(refNode) {
- this.impl.setEndAfter(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
},
selectNode: function(refNode) {
- this.impl.selectNode(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
},
selectNodeContents: function(refNode) {
- this.impl.selectNodeContents(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
},
compareBoundaryPoints: function(how, sourceRange) {
- return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));
+ return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
},
extractContents: function() {
- return wrap(this.impl.extractContents());
+ return wrap(unsafeUnwrap(this).extractContents());
},
cloneContents: function() {
- return wrap(this.impl.cloneContents());
+ return wrap(unsafeUnwrap(this).cloneContents());
},
insertNode: function(node) {
- this.impl.insertNode(unwrapIfNeeded(node));
+ unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
},
surroundContents: function(newParent) {
- this.impl.surroundContents(unwrapIfNeeded(newParent));
+ unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
},
cloneRange: function() {
- return wrap(this.impl.cloneRange());
+ return wrap(unsafeUnwrap(this).cloneRange());
},
isPointInRange: function(node, offset) {
- return this.impl.isPointInRange(unwrapIfNeeded(node), offset);
+ return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
},
comparePoint: function(node, offset) {
- return this.impl.comparePoint(unwrapIfNeeded(node), offset);
+ return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
},
intersectsNode: function(node) {
- return this.impl.intersectsNode(unwrapIfNeeded(node));
+ return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
},
toString: function() {
- return this.impl.toString();
+ return unsafeUnwrap(this).toString();
}
};
// IE9 does not have createContextualFragment.
if (OriginalRange.prototype.createContextualFragment) {
Range.prototype.createContextualFragment = function(html) {
- return wrap(this.impl.createContextualFragment(html));
+ return wrap(unsafeUnwrap(this).createContextualFragment(html));
};
}
diff --git a/src/wrappers/SVGElementInstance.js b/src/wrappers/SVGElementInstance.js
index bca4719..75598a4 100644
--- a/src/wrappers/SVGElementInstance.js
+++ b/src/wrappers/SVGElementInstance.js
@@ -8,6 +8,7 @@
var EventTarget = scope.wrappers.EventTarget;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var OriginalSVGElementInstance = window.SVGElementInstance;
@@ -22,17 +23,17 @@
mixin(SVGElementInstance.prototype, {
/** @type {SVGElement} */
get correspondingElement() {
- return wrap(this.impl.correspondingElement);
+ return wrap(unsafeUnwrap(this).correspondingElement);
},
/** @type {SVGUseElement} */
get correspondingUseElement() {
- return wrap(this.impl.correspondingUseElement);
+ return wrap(unsafeUnwrap(this).correspondingUseElement);
},
/** @type {SVGElementInstance} */
get parentNode() {
- return wrap(this.impl.parentNode);
+ return wrap(unsafeUnwrap(this).parentNode);
},
/** @type {SVGElementInstanceList} */
@@ -42,22 +43,22 @@
/** @type {SVGElementInstance} */
get firstChild() {
- return wrap(this.impl.firstChild);
+ return wrap(unsafeUnwrap(this).firstChild);
},
/** @type {SVGElementInstance} */
get lastChild() {
- return wrap(this.impl.lastChild);
+ return wrap(unsafeUnwrap(this).lastChild);
},
/** @type {SVGElementInstance} */
get previousSibling() {
- return wrap(this.impl.previousSibling);
+ return wrap(unsafeUnwrap(this).previousSibling);
},
/** @type {SVGElementInstance} */
get nextSibling() {
- return wrap(this.impl.nextSibling);
+ return wrap(unsafeUnwrap(this).nextSibling);
}
});
diff --git a/src/wrappers/Selection.js b/src/wrappers/Selection.js
index 44c337c..e35c437 100644
--- a/src/wrappers/Selection.js
+++ b/src/wrappers/Selection.js
@@ -6,6 +6,8 @@
'use strict';
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -13,38 +15,38 @@
var OriginalSelection = window.Selection;
function Selection(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
Selection.prototype = {
get anchorNode() {
- return wrap(this.impl.anchorNode);
+ return wrap(unsafeUnwrap(this).anchorNode);
},
get focusNode() {
- return wrap(this.impl.focusNode);
+ return wrap(unsafeUnwrap(this).focusNode);
},
addRange: function(range) {
- this.impl.addRange(unwrap(range));
+ unsafeUnwrap(this).addRange(unwrap(range));
},
collapse: function(node, index) {
- this.impl.collapse(unwrapIfNeeded(node), index);
+ unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
},
containsNode: function(node, allowPartial) {
- return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);
+ return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
},
extend: function(node, offset) {
- this.impl.extend(unwrapIfNeeded(node), offset);
+ unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
},
getRangeAt: function(index) {
- return wrap(this.impl.getRangeAt(index));
+ return wrap(unsafeUnwrap(this).getRangeAt(index));
},
removeRange: function(range) {
- this.impl.removeRange(unwrap(range));
+ unsafeUnwrap(this).removeRange(unwrap(range));
},
selectAllChildren: function(node) {
- this.impl.selectAllChildren(unwrapIfNeeded(node));
+ unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
},
toString: function() {
- return this.impl.toString();
+ return unsafeUnwrap(this).toString();
}
};
diff --git a/src/wrappers/ShadowRoot.js b/src/wrappers/ShadowRoot.js
index 3e3c8cf..329850d 100644
--- a/src/wrappers/ShadowRoot.js
+++ b/src/wrappers/ShadowRoot.js
@@ -13,6 +13,7 @@
var mixin = scope.mixin;
var rewrap = scope.rewrap;
var setInnerHTML = scope.setInnerHTML;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var shadowHostTable = new WeakMap();
@@ -21,7 +22,7 @@
var spaceCharRe = /[ \t\n\r\f]/;
function ShadowRoot(hostWrapper) {
- var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());
+ var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
DocumentFragment.call(this, node);
// createDocumentFragment associates the node with a wrapper
diff --git a/src/wrappers/TouchEvent.js b/src/wrappers/TouchEvent.js
index b751d22..f3a4552 100644
--- a/src/wrappers/TouchEvent.js
+++ b/src/wrappers/TouchEvent.js
@@ -10,7 +10,8 @@
var UIEvent = scope.wrappers.UIEvent;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
// TouchEvent is WebKit/Blink only.
@@ -34,12 +35,12 @@
}
function Touch(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
Touch.prototype = {
get target() {
- return wrap(this.impl.target);
+ return wrap(unsafeUnwrap(this).target);
}
};
@@ -63,7 +64,7 @@
'webkitForce'
].forEach(function(name) {
descr.get = function() {
- return this.impl[name];
+ return unsafeUnwrap(this)[name];
};
Object.defineProperty(Touch.prototype, name, descr);
});
@@ -96,15 +97,15 @@
mixin(TouchEvent.prototype, {
get touches() {
- return wrapTouchList(unwrap(this).touches);
+ return wrapTouchList(unsafeUnwrap(this).touches);
},
get targetTouches() {
- return wrapTouchList(unwrap(this).targetTouches);
+ return wrapTouchList(unsafeUnwrap(this).targetTouches);
},
get changedTouches() {
- return wrapTouchList(unwrap(this).changedTouches);
+ return wrapTouchList(unsafeUnwrap(this).changedTouches);
},
initTouchEvent: function() {
diff --git a/src/wrappers/WebGLRenderingContext.js b/src/wrappers/WebGLRenderingContext.js
index bfb4230..f009263 100644
--- a/src/wrappers/WebGLRenderingContext.js
+++ b/src/wrappers/WebGLRenderingContext.js
@@ -7,6 +7,8 @@
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -17,22 +19,22 @@
return;
function WebGLRenderingContext(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
mixin(WebGLRenderingContext.prototype, {
get canvas() {
- return wrap(this.impl.canvas);
+ return wrap(unsafeUnwrap(this).canvas);
},
texImage2D: function() {
arguments[5] = unwrapIfNeeded(arguments[5]);
- this.impl.texImage2D.apply(this.impl, arguments);
+ unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
},
texSubImage2D: function() {
arguments[6] = unwrapIfNeeded(arguments[6]);
- this.impl.texSubImage2D.apply(this.impl, arguments);
+ unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
}
});
diff --git a/src/wrappers/events.js b/src/wrappers/events.js
index e1a1911..0c8fe46 100644
--- a/src/wrappers/events.js
+++ b/src/wrappers/events.js
@@ -9,6 +9,8 @@
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrappers = scope.wrappers;
@@ -463,9 +465,10 @@
function Event(type, options) {
if (type instanceof OriginalEvent) {
var impl = type;
- if (!OriginalBeforeUnloadEvent && impl.type === 'beforeunload')
+ if (!OriginalBeforeUnloadEvent && impl.type === 'beforeunload') {
return new BeforeUnloadEvent(impl);
- this.impl = impl;
+ }
+ setWrapper(impl, this);
} else {
return wrap(constructEvent(OriginalEvent, 'Event', type, options));
}
@@ -509,7 +512,7 @@
var OriginalEvent = window[name];
var GenericEvent = function(type, options) {
if (type instanceof OriginalEvent)
- this.impl = type;
+ setWrapper(type, this);
else
return wrap(constructEvent(OriginalEvent, name, type, options));
};
@@ -640,10 +643,10 @@
BeforeUnloadEvent.prototype = Object.create(Event.prototype);
mixin(BeforeUnloadEvent.prototype, {
get returnValue() {
- return this.impl.returnValue;
+ return unsafeUnwrap(this).returnValue;
},
set returnValue(v) {
- this.impl.returnValue = v;
+ unsafeUnwrap(this).returnValue = v;
}
});
@@ -680,7 +683,7 @@
* @constructor
*/
function EventTarget(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
// Node and Window have different internal type checks in WebKit so we cannot
@@ -818,7 +821,8 @@
function elementFromPoint(self, document, x, y) {
scope.renderAllPending();
- var element = wrap(originalElementFromPoint.call(document.impl, x, y));
+ var element =
+ wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
if (!element)
return null;
var path = getEventPath(element, null);
diff --git a/test/js/FormData.js b/test/js/FormData.js
index a0bcf8b..2fe2196 100644
--- a/test/js/FormData.js
+++ b/test/js/FormData.js
@@ -24,7 +24,7 @@ suite('FormData', function() {
var fd = new FormData();
var unwrapped = unwrap(fd);
var wrapped = wrap(unwrapped);
- assert.equal(fd.impl, wrapped.impl);
+ assert.equal(fd, wrapped);
});
});
diff --git a/test/js/rerender.js b/test/js/rerender.js
index cfc49ae..d4261ab 100644
--- a/test/js/rerender.js
+++ b/test/js/rerender.js
@@ -6,6 +6,7 @@
suite('Shadow DOM rerender', function() {
+ var unsafeUnwrap = ShadowDOMPolyfill.unsafeUnwrap;
var unwrap = ShadowDOMPolyfill.unwrap;
function getVisualInnerHtml(el) {
@@ -501,40 +502,40 @@ suite('Shadow DOM rerender', function() {
a.textContent = 'x';
// Don't use getVisualInnerHtml but it does invalidation.
- assert.equal(host.impl.innerHTML, 'x');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'x');
host.appendChild(document.createTextNode('y'));
- assert.equal(host.impl.innerHTML, 'xy'); //dirty
+ assert.equal(unsafeUnwrap(host).innerHTML, 'xy'); //dirty
host.offsetWidth;
- assert.equal(host.impl.innerHTML, 'xy');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'xy');
sr.appendChild(document.createTextNode('z'));
- assert.equal(host.impl.innerHTML, 'xy'); //dirty
+ assert.equal(unsafeUnwrap(host).innerHTML, 'xy'); //dirty
host.offsetWidth;
- assert.equal(host.impl.innerHTML, 'xyz');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'xyz');
sr.insertBefore(document.createTextNode('w'), content);
- assert.equal(host.impl.innerHTML, 'xyz'); // dirty
+ assert.equal(unsafeUnwrap(host).innerHTML, 'xyz'); // dirty
host.offsetWidth;
- assert.equal(host.impl.innerHTML, 'wxyz');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wxyz');
// This case does not need invalidation.
// We could make the check a bit more specific (check for nextSibling being
// null or a content/shadow).
sr.insertBefore(document.createTextNode('v'), c);
- assert.equal(host.impl.innerHTML, 'wxyvz');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wxyvz');
host.offsetWidth;
- assert.equal(host.impl.innerHTML, 'wxyvz');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wxyvz');
content.select = '*';
- assert.equal(host.impl.innerHTML, 'wxyvz'); // dirty
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wxyvz'); // dirty
host.offsetWidth;
- assert.equal(host.impl.innerHTML, 'wxvz');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wxvz');
content.setAttribute('SelecT', 'no-match');
- assert.equal(host.impl.innerHTML, 'wxvz'); // dirty
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wxvz'); // dirty
host.offsetWidth;
- assert.equal(host.impl.innerHTML, 'wvz');
+ assert.equal(unsafeUnwrap(host).innerHTML, 'wvz');
});
test('minimal dom changes', function() {