зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
69e25dc980
Коммит
f49f3db6d7
|
@ -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)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
Загрузка…
Ссылка в новой задаче