Bug 1515046 - Let reps invoke the right getter when it's shadowed. r=nchevobbe

Depends on D15788

Differential Revision: https://phabricator.services.mozilla.com/D15789

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Oriol Brufau 2019-01-09 01:47:34 +00:00
parent 69e25dc980
commit f49f3db6d7
3 changed files with 104 additions and 8 deletions

View File

@ -3688,13 +3688,26 @@ function getClosestNonBucketNode(item) {
return getClosestNonBucketNode(parent); return getClosestNonBucketNode(parent);
} }
function getNonPrototypeParentGripValue(item) { function getParentGripNode(item) {
const parentNode = getParent(item); const parentNode = getParent(item);
if (!parentNode) { if (!parentNode) {
return null; return null;
} }
const parentGripNode = getClosestGripNode(parentNode); return getClosestGripNode(parentNode);
}
function getParentGripValue(item) {
const parentGripNode = getParentGripNode(item);
if (!parentGripNode) {
return null;
}
return getValue(parentGripNode);
}
function getNonPrototypeParentGripValue(item) {
const parentGripNode = getParentGripNode(item);
if (!parentGripNode) { if (!parentGripNode) {
return null; return null;
} }
@ -3716,6 +3729,7 @@ module.exports = {
getClosestGripNode, getClosestGripNode,
getClosestNonBucketNode, getClosestNonBucketNode,
getParent, getParent,
getParentGripValue,
getNonPrototypeParentGripValue, getNonPrototypeParentGripValue,
getNumericalPropertiesCount, getNumericalPropertiesCount,
getValue, getValue,
@ -6406,11 +6420,11 @@ function releaseActors(state, client) {
} }
} }
function invokeGetter(node, grip, getterName) { function invokeGetter(node, targetGrip, receiverId, getterName) {
return async ({ dispatch, client, getState }) => { return async ({ dispatch, client, getState }) => {
try { try {
const objectClient = client.createObjectClient(grip); const objectClient = client.createObjectClient(targetGrip);
const result = await objectClient.getPropertyValue(getterName, null); const result = await objectClient.getPropertyValue(getterName, receiverId);
dispatch({ dispatch({
type: "GETTER_INVOKED", type: "GETTER_INVOKED",
data: { data: {
@ -7004,6 +7018,7 @@ const {
nodeIsLongString, nodeIsLongString,
nodeHasFullText, nodeHasFullText,
nodeHasGetter, nodeHasGetter,
getParentGripValue,
getNonPrototypeParentGripValue getNonPrototypeParentGripValue
} = Utils.node; } = Utils.node;
@ -7078,10 +7093,11 @@ class ObjectInspectorItem extends Component {
} }
if (nodeHasGetter(item)) { if (nodeHasGetter(item)) {
const parentGrip = getNonPrototypeParentGripValue(item); const targetGrip = getParentGripValue(item);
if (parentGrip) { const receiverGrip = getNonPrototypeParentGripValue(item);
if (targetGrip && receiverGrip) {
Object.assign(repProps, { Object.assign(repProps, {
onInvokeGetterButtonClick: () => this.props.invokeGetter(item, parentGrip, item.name) onInvokeGetterButtonClick: () => this.props.invokeGetter(item, targetGrip, receiverGrip.actor, item.name)
}); });
} }
} }

View File

@ -355,6 +355,7 @@ skip-if = true # Bug 1438979
[browser_webconsole_object_inspector_entries.js] [browser_webconsole_object_inspector_entries.js]
[browser_webconsole_object_inspector_getters.js] [browser_webconsole_object_inspector_getters.js]
[browser_webconsole_object_inspector_getters_prototype.js] [browser_webconsole_object_inspector_getters_prototype.js]
[browser_webconsole_object_inspector_getters_shadowed.js]
[browser_webconsole_object_inspector_key_sorting.js] [browser_webconsole_object_inspector_key_sorting.js]
[browser_webconsole_object_inspector_local_session_storage.js] [browser_webconsole_object_inspector_local_session_storage.js]
[browser_webconsole_object_inspector_selected_text.js] [browser_webconsole_object_inspector_selected_text.js]

View File

@ -0,0 +1,79 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check evaluating shadowed getters in the console.
const TEST_URI = "data:text/html;charset=utf8,<h1>Object Inspector on Getters</h1>";
add_task(async function() {
const hud = await openNewTabAndConsole(TEST_URI);
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
const a = {
getter: "[A]",
__proto__: {
get getter() {
return "[B]";
},
__proto__: {
get getter() {
return "[C]";
},
},
},
};
const b = {
value: 1,
get getter() {
return `[A-${this.value}]`;
},
__proto__: {
value: 2,
get getter() {
return `[B-${this.value}]`;
},
},
};
content.wrappedJSObject.console.log("oi-test", a, b);
});
const node = await waitFor(() => findMessage(hud, "oi-test"));
const [a, b] = node.querySelectorAll(".tree");
await testObject(a, [null, "[B]", "[C]"]);
await testObject(b, ["[A-1]", "[B-1]"]);
});
async function testObject(oi, values) {
let node = oi.querySelector(".tree-node");
for (const value of values) {
await expand(node);
if (value != null) {
const getter = findObjectInspectorNodeChild(node, "getter");
await invokeGetter(getter);
ok(getter.textContent.includes(`getter: "${value}"`),
`Getter now has the expected "${value}" content`);
}
node = findObjectInspectorNodeChild(node, "<prototype>");
}
}
function expand(node) {
expandObjectInspectorNode(node);
return waitFor(() => getObjectInspectorChildrenNodes(node).length > 0);
}
function invokeGetter(node) {
getObjectInspectorInvokeGetterButton(node).click();
return waitFor(() => !getObjectInspectorInvokeGetterButton(node));
}
function findObjectInspectorNodeChild(node, nodeLabel) {
return getObjectInspectorChildrenNodes(node).find(child => {
const label = child.querySelector(".object-label");
return label && label.textContent === nodeLabel;
});
}