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);
}
function getNonPrototypeParentGripValue(item) {
function getParentGripNode(item) {
const parentNode = getParent(item);
if (!parentNode) {
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) {
return null;
}
@ -3716,6 +3729,7 @@ module.exports = {
getClosestGripNode,
getClosestNonBucketNode,
getParent,
getParentGripValue,
getNonPrototypeParentGripValue,
getNumericalPropertiesCount,
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 }) => {
try {
const objectClient = client.createObjectClient(grip);
const result = await objectClient.getPropertyValue(getterName, null);
const objectClient = client.createObjectClient(targetGrip);
const result = await objectClient.getPropertyValue(getterName, receiverId);
dispatch({
type: "GETTER_INVOKED",
data: {
@ -7004,6 +7018,7 @@ const {
nodeIsLongString,
nodeHasFullText,
nodeHasGetter,
getParentGripValue,
getNonPrototypeParentGripValue
} = Utils.node;
@ -7078,10 +7093,11 @@ class ObjectInspectorItem extends Component {
}
if (nodeHasGetter(item)) {
const parentGrip = getNonPrototypeParentGripValue(item);
if (parentGrip) {
const targetGrip = getParentGripValue(item);
const receiverGrip = getNonPrototypeParentGripValue(item);
if (targetGrip && receiverGrip) {
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_getters.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_local_session_storage.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;
});
}