Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #476 from ochameau/bug/769006-fix-MutationObserver

Bug: 769006: Ensure that MutationObserver works in content scripts. r=@gozala
  • Loading branch information...
commit 7e78b8a7916d51becedc0dcb6f71b0e5b34eb514 2 parents 983a9ef + 5d86f98
@ochameau ochameau authored
View
29 packages/api-utils/lib/content/content-proxy.js
@@ -542,7 +542,7 @@ const xRayWrappersMissFixes = [
// Trap access to form["node name"]
// http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#9477
function (obj, name) {
- if (typeof obj == "object" && obj.tagName == "FORM") {
+ if (typeof obj == "object" && "tagName" in obj && obj.tagName == "FORM") {
let match = obj.wrappedJSObject[name];
let nodes = obj.ownerDocument.getElementsByName(name);
for (let i = 0, l = nodes.length; i < l; i++) {
@@ -660,6 +660,33 @@ const xRayWrappersMethodsFixes = {
};
return getProxyForFunction(f, NativeFunctionWrapper(f));
+ },
+
+ // Bug 769006: nsIDOMMutationObserver.observe fails with proxy as options
+ // attributes
+ observe: function observe(obj) {
+ // Ensure that we are on a DOMMutation object
+ try {
+ // nsIDOMMutationObserver starts with FF14
+ if ("nsIDOMMutationObserver" in Ci)
+ obj.QueryInterface(Ci.nsIDOMMutationObserver);
+ else
+ return null;
+ }
+ catch(e) {
+ return null;
+ }
+ return function nsIDOMMutationObserverObserveFix(target, options) {
+ // Gets native/unwrapped this
+ let self = this && typeof this.valueOf == "function" ?
+ this.valueOf(UNWRAP_ACCESS_KEY) : this;
+ // Unwrap the xraywrapper target out of JS proxy
+ let targetXray = unwrap(target);
+ // But do not wrap `options` through ContentScriptObjectWrapper
+ let result = wrap(self.observe(targetXray, options));
+ // Finally wrap result into JS proxies
+ return wrap(result);
+ };
}
};
View
39 packages/api-utils/tests/test-content-proxy.js
@@ -808,3 +808,42 @@ exports.testCrossDomainIframe = createProxyTest("", function (helper) {
worker.postMessage("http://localhost:" + serverPort + "/");
});
+
+// Bug 769006: Ensure that MutationObserver works fine with proxies
+let html = '<a href="foo">link</a>';
+exports.testMutationObvserver = createProxyTest(html, function (helper) {
+
+ helper.createWorker(
+ 'new ' + function ContentScriptScope() {
+ if (typeof MutationObserver == "undefined") {
+ assert(true, "No MutationObserver for this FF version");
+ done();
+ return;
+ }
+ let link = document.getElementsByTagName("a")[0];
+
+ // Register a Mutation observer
+ let obs = new MutationObserver(function(mutations){
+ // Ensure that mutation data are valid
+ assert(mutations.length == 1, "only one attribute mutation");
+ let mutation = mutations[0];
+ assert(mutation.type == "attributes", "check `type`");
+ assert(mutation.target == link, "check `target`");
+ assert(mutation.attributeName == "href", "check `attributeName`");
+ assert(mutation.oldValue == "foo", "check `oldValue`");
+ obs.disconnect();
+ done();
+ });
+ obs.observe(document, {
+ subtree: true,
+ attributes: true,
+ attributeOldValue: true,
+ attributeFilter: ["href"]
+ });
+
+ // Modify the DOM
+ link.setAttribute("href", "bar");
+ }
+ );
+
+});
Please sign in to comment.
Something went wrong with that request. Please try again.