Bug 724862 - Implement protocol support for modifying the values of a debuggee object's properties; r=rcampbell

This commit is contained in:
Panos Astithas 2012-05-24 14:23:53 +03:00
Родитель c39caaf368
Коммит 1d763d246b
7 изменённых файлов: 90 добавлений и 842 удалений

Просмотреть файл

@ -631,6 +631,18 @@ StackFrames.prototype = {
return aFrame["calleeName"] ? aFrame["calleeName"] : "(anonymous)";
}
return "(" + aFrame.type + ")";
},
/**
* Evaluate an expression in the context of the selected frame. This is used
* for modifying the value of variables in scope.
*
* @param string aExpression
* The expression to evaluate.
*/
evaluate: function SF_evaluate(aExpression) {
let frame = this.activeThread.cachedFrames[this.selectedFrame];
this.activeThread.eval(frame.actor, aExpression);
}
};
@ -709,6 +721,11 @@ SourceScripts.prototype = {
* Handler for the debugger client's unsolicited newScript notification.
*/
_onNewScript: function SS__onNewScript(aNotification, aPacket) {
// Ignore scripts generated from 'clientEvaluate' packets.
if (aPacket.url == "debugger eval code") {
return;
}
this._addScript({ url: aPacket.url, startLine: aPacket.startLine }, true);
},

Просмотреть файл

@ -862,6 +862,14 @@ PropertiesView.prototype = {
value: value
}));
// Maintain the symbolic name of the variable.
Object.defineProperty(element, "token", {
value: aName,
writable: false,
enumerable: true,
configurable: true
});
title.appendChild(separator);
title.appendChild(value);
@ -1078,6 +1086,14 @@ PropertiesView.prototype = {
value: value
}));
// Maintain the symbolic name of the property.
Object.defineProperty(element, "token", {
value: aVar.token + "['" + pKey + "']",
writable: false,
enumerable: true,
configurable: true
});
// Save the property to the variable for easier access.
Object.defineProperty(aVar, pKey, { value: element,
writable: false,
@ -1160,35 +1176,8 @@ PropertiesView.prototype = {
// The actual save mechanism for the new variable/property value.
function DVP_element_textbox_save() {
if (textbox.value !== value.textContent) {
// TODO: use the debugger client API to send the value to the debuggee,
// after bug 724862 lands.
let result = eval(textbox.value);
let grip;
// Construct the grip based on the evaluated expression in the textbox.
switch (typeof result) {
case "number":
case "boolean":
case "string":
grip = result;
break;
case "object":
if (result === null) {
grip = {
"type": "null"
};
} else {
grip = {
"type": "object",
"class": result.constructor.name || "Object"
};
}
break;
case "undefined":
grip = { type: "undefined" };
}
self._applyGrip(value, grip);
let expr = "(" + element.token + "=" + textbox.value + ")";
DebuggerController.StackFrames.evaluate(expr);
}
DVP_element_textbox_clear();
}

Просмотреть файл

@ -31,7 +31,6 @@ _BROWSER_TEST_FILES = \
browser_dbg_propertyview-07.js \
browser_dbg_propertyview-08.js \
browser_dbg_propertyview-edit.js \
browser_dbg_propertyview-edit2.js \
browser_dbg_panesize.js \
browser_dbg_stack-01.js \
browser_dbg_stack-02.js \

Просмотреть файл

@ -8,75 +8,58 @@ var gTab = null;
var gDebuggee = null;
var gDebugger = null;
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.contentWindow;
testSimpleCall();
testFrameEval();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
function testFrameEval() {
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Properties._addScope("test").expand();
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
let localVar0 = testScope.addVar("aNumber");
localVar0.setGrip(1.618);
var localScope = gDebugger.DebuggerView.Properties.localScope,
localNodes = localScope.querySelector(".details").childNodes,
varA = localNodes[7];
let localVar1 = testScope.addVar("aBoolean");
localVar1.setGrip(false);
is(varA.querySelector(".name").textContent, "a",
"Should have the right name for 'a'.");
let localVar2 = testScope.addVar("aString");
localVar2.setGrip("hello world");
is(varA.querySelector(".value").textContent, 1,
"Should have the right initial value for 'a'.");
let localVar3 = testScope.addVar("aUndefined");
localVar3.setGrip({ type: "undefined" });
let localVar4 = testScope.addVar("aNull");
localVar4.setGrip({ type: "null" });
testVar0(localVar0, function() {
testVar1(localVar1, function() {
testVar2(localVar2, function() {
testVar2_bis(localVar2, function() {
testVar3(localVar3, function() {
testVar4_switch(localVar4, localVar0, function() {
resumeAndFinish();
});
});
});
});
});
});
testModification(varA, function(aVar) {
testModification(aVar, function(aVar) {
testModification(aVar, function(aVar) {
resumeAndFinish();
}, "document.title", '"Debugger Function Call Parameter Test"');
}, "b", "[object Object]");
}, "{ a: 1 }", "[object Object]");
}}, 0);
});
}, false);
gDebuggee.simpleCall();
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function testVar0(aVar, aCallback) {
var changeTo = "true";
function testModification(aVar, aCallback, aNewValue, aNewResult) {
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendString(aNewValue);
EventUtils.sendKey("RETURN");
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for number variables.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple number variables shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
@ -85,316 +68,23 @@ function testVar0(aVar, aCallback) {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
// Get the variable reference anew, since the old ones were discarded when
// we resumed.
var localScope = gDebugger.DebuggerView.Properties.localScope,
localNodes = localScope.querySelector(".details").childNodes,
varA = localNodes[7];
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the variable wasn't set correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for boolean variables after exiting 'input-mode'.");
ok(aVar.visible,
"The variable should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple number elements shouldn't be expanded.");
is(varA.querySelector(".value").textContent, aNewResult,
"Should have the right value for 'a'.");
executeSoon(function() {
aCallback();
aCallback(varA);
});
});
});
}
function testVar1(aVar, aCallback) {
var changeTo = "\"nasu\"";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendKey("ENTER");
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for boolean variables.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple boolean variables shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
}, false);
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the variable wasn't set correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string variables after exiting 'input-mode'.");
ok(aVar.visible,
"The variable should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple string elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testVar2(aVar, aCallback) {
var changeTo = "1234.5678";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
gDebugger.editor.focus();
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string variables.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple string variables shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, "\"" + changeTo + "\"",
"The grip information for the variable wasn't set correctly.");
// when changing a string, its contents are automatically selected
// so that the result is another string; for example, if the value was
// "hello", then writing 42 would automatically produce "42"
// see more details in _activateElementInputMode from DebuggerView
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string variables after exiting 'input-mode'.");
ok(aVar.visible,
"The variable should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple string elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testVar2_bis(aVar, aCallback) {
var changeTo = "42";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
gDebugger.editor.focus();
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string variables.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple string variables shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
aVar.querySelector(".element-input").select();
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the variable wasn't set correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for number variables after exiting 'input-mode'.");
ok(aVar.visible,
"The variable should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple number elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testVar3(aVar, aCallback) {
var changeTo = "\"this will be ignored\"";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendKey("ESCAPE");
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for undefined variables.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple undefined variables shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, "undefined",
"The grip information for the variable wasn't reverted correctly.");
isnot(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the variable wasn't reverted correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for undefined variables after exiting 'input-mode'.");
ok(aVar.visible,
"The variable should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple undefined elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testVar4_switch(aVar, aVarSwitch, aCallback) {
var changeTo = "\"this will not be ignored\"";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendMouseEvent({ type: "click" },
aVarSwitch.querySelector(".value"),
gDebugger);
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for null variables.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple null variables shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the variable set correctly after the input element lost focus.");
executeSoon(function() {
aCallback();
});
});
});
}

Просмотреть файл

@ -1,458 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.contentWindow;
testSimpleCall();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Properties._addScope("test").expand();
let v = testScope.addVar("aObject");
v.setGrip({ type: "object", "class": "Object" }).expand();
v.addProperties({ "someProp0": { "value": 42 },
"someProp1": { "value": true },
"someProp2": { "value": "nasu" },
"someProp3": { "value": { "type": "undefined" } },
"someProp4": { "value": { "type": "null" } },
"someProp5": { "value": { "type": "object", "class": "Object" } } });
testPropContainer(v, function() {
testProp0(v.someProp0, function() {
testProp1(v.someProp1, function() {
testProp2(v.someProp2, function() {
testProp2_bis(v.someProp2, function() {
testProp3(v.someProp3, function() {
testProp4_switch(v.someProp4, v.someProp0, function() {
resumeAndFinish();
});
});
});
});
});
});
});
}}, 0);
});
gDebuggee.simpleCall();
}
function testPropContainer(aVar, aCallback) {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this variable yet.");
ok(aVar.arrowVisible,
"The arrow should be visible for variable containers.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(aVar.expanded,
"This variable container should have been previously expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The variable should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The variable shouldn't be expanded while in 'input-mode'.");
gDebugger.editor.focus();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, "[object Object]",
"The grip information for the variable wasn't reset correctly.");
ok(aVar.arrowVisible,
"The arrow should be visible for variable containers after exiting 'input-mode'.'");
ok(aVar.visible,
"The variable should be visible before entering 'input-mode'.");
ok(aVar.expanded,
"This variable container should have been previously expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testProp0(aVar, aCallback) {
var changeTo = "true";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendKey("RETURN");
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this property yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for number properties.'");
ok(aVar.visible,
"The property should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple number properties shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The property should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The property shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the property wasn't set correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for boolean properties after exiting 'input-mode'.");
ok(aVar.visible,
"The property should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple number elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testProp1(aVar, aCallback) {
var changeTo = "\"nasu\"";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendKey("ENTER");
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this property yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for boolean properties.'");
ok(aVar.visible,
"The property should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple boolean properties shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The property should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The property shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the property wasn't set correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string properties after exiting 'input-mode'.");
ok(aVar.visible,
"The property should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple string elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testProp2(aVar, aCallback) {
var changeTo = "1234.5678";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
gDebugger.editor.focus();
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this property yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string properties.'");
ok(aVar.visible,
"The property should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple string properties shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The property should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The property shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, "\"" + changeTo + "\"",
"The grip information for the property wasn't set correctly.");
// when changing a string, its contents are automatically selected
// so that the result is another string; for example, if the value was
// "hello", then writing 42 would automatically produce "42"
// see more details in _activateElementInputMode from DebuggerView
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string properties after exiting 'input-mode'.");
ok(aVar.visible,
"The property should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple string elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testProp2_bis(aVar, aCallback) {
var changeTo = "42";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
gDebugger.editor.focus();
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this property yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for string properties.'");
ok(aVar.visible,
"The property should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple string properties shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The property should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The property shouldn't be expanded while in 'input-mode'.");
aVar.querySelector(".element-input").select();
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the property wasn't set correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for number properties after exiting 'input-mode'.");
ok(aVar.visible,
"The property should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple number elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testProp3(aVar, aCallback) {
var changeTo = "\"this will be ignored\"";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendKey("ESCAPE");
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this property yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for undefined properties.'");
ok(aVar.visible,
"The property should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple undefined properties shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The property should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The property shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, "undefined",
"The grip information for the property wasn't reverted correctly.");
isnot(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the property wasn't reverted correctly.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for undefined properties after exiting 'input-mode'.");
ok(aVar.visible,
"The property should be visible after exiting 'input-mode'.");
ok(!aVar.expanded,
"Simple undefined elements shouldn't be expanded.");
executeSoon(function() {
aCallback();
});
});
});
}
function testProp4_switch(aVar, aVarSwitch, aCallback) {
var changeTo = "\"this will not be ignored\"";
function makeChangesAndExitInputMode() {
EventUtils.sendString(changeTo);
EventUtils.sendMouseEvent({ type: "click" },
aVarSwitch.querySelector(".value"),
gDebugger);
}
ok(!aVar.querySelector(".element-input"),
"There should be no input elements for this property yet.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible for null properties.'");
ok(aVar.visible,
"The property should be visible before entering 'input-mode'.");
ok(!aVar.expanded,
"Simple null properties shouldn't be expanded.");
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
"There should be an input element created.");
ok(!aVar.arrowVisible,
"The arrow shouldn't be visible while in 'input-mode.'");
ok(aVar.visible,
"The property should be visible while in 'input-mode'.");
ok(!aVar.expanded,
"The property shouldn't be expanded while in 'input-mode'.");
makeChangesAndExitInputMode();
executeSoon(function() {
ok(!aVar.querySelector(".element-input"),
"There should be no input elements after exiting 'input-mode'.");
is(aVar.querySelector(".value").textContent, changeTo,
"The grip information for the property set correctly after the input element lost focus.");
executeSoon(function() {
aCallback();
});
});
});
}
function resumeAndFinish() {
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish(gTab);
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

Просмотреть файл

@ -180,6 +180,7 @@ const UnsolicitedNotifications = {
* sent to the server.
*/
const DebugProtocolTypes = {
"assign": "assign",
"attach": "attach",
"clientEvaluate": "clientEvaluate",
"delete": "delete",
@ -584,6 +585,14 @@ ThreadClient.prototype = {
/**
* Send a clientEvaluate packet to the debuggee. Response
* will be a resume packet.
*
* @param string aFrame
* The actor ID of the frame where the evaluation should take place.
* @param string aExpression
* The expression that will be evaluated in the scope of the frame
* above.
* @param function aOnResponse
* Called with the response packet.
*/
eval: function TC_eval(aFrame, aExpression, aOnResponse) {
this._assertPaused("eval");
@ -630,9 +639,9 @@ ThreadClient.prototype = {
/**
* Request to set a breakpoint in the specified location.
*
* @param aLocation object
* @param object aLocation
* The source location object where the breakpoint will be set.
* @param aOnResponse integer
* @param function aOnResponse
* Called with the thread's response.
*/
setBreakpoint: function TC_setBreakpoint(aLocation, aOnResponse) {

Просмотреть файл

@ -1473,13 +1473,15 @@ EnvironmentActor.prototype = {
* The protocol request object.
*/
onAssign: function EA_onAssign(aRequest) {
let desc = this.obj.getVariableDescriptor(aRequest.name);
// TODO: enable the commented-out part when getVariableDescriptor lands
// (bug 725815).
/*let desc = this.obj.getVariableDescriptor(aRequest.name);
if (!desc.writable) {
return { error: "immutableBinding",
message: "Changing the value of an immutable binding is not " +
"allowed" };
}
}*/
try {
this.obj.setVariable(aRequest.name, aRequest.value);