зеркало из https://github.com/mozilla/gecko-dev.git
Bug 948893 - Hovering certain bounds in a HTML source while paused in the debugger can sometimes incorrectly show a variable inspection popup, r=past
This commit is contained in:
Родитель
d1bf402a34
Коммит
f6dea06b20
|
@ -1357,7 +1357,11 @@ VariableBubbleView.prototype = {
|
|||
|
||||
let scriptLine = hoveredLine - scriptLineOffset;
|
||||
let scriptColumn = hoveredColumn - scriptColumnOffset;
|
||||
let identifierInfo = parsedSource.getIdentifierAt(scriptLine + 1, scriptColumn);
|
||||
let identifierInfo = parsedSource.getIdentifierAt({
|
||||
line: scriptLine + 1,
|
||||
column: scriptColumn,
|
||||
scriptIndex: scriptInfo.index
|
||||
});
|
||||
|
||||
// If the info is null, we're not hovering any identifier.
|
||||
if (!identifierInfo) {
|
||||
|
|
|
@ -52,6 +52,7 @@ support-files =
|
|||
doc_recursion-stack.html
|
||||
doc_scope-variable.html
|
||||
doc_scope-variable-2.html
|
||||
doc_scope-variable-3.html
|
||||
doc_script-switching-01.html
|
||||
doc_script-switching-02.html
|
||||
doc_step-out.html
|
||||
|
@ -222,6 +223,7 @@ support-files =
|
|||
[browser_dbg_variables-view-popup-06.js]
|
||||
[browser_dbg_variables-view-popup-07.js]
|
||||
[browser_dbg_variables-view-popup-08.js]
|
||||
[browser_dbg_variables-view-popup-09.js]
|
||||
[browser_dbg_variables-view-reexpand-01.js]
|
||||
[browser_dbg_variables-view-reexpand-02.js]
|
||||
[browser_dbg_variables-view-webidl.js]
|
||||
|
|
|
@ -33,44 +33,44 @@ function test() {
|
|||
is(parsed.scriptCount, 3,
|
||||
"There should be 3 scripts parsed in the parent HTML source.");
|
||||
|
||||
is(parsed.getScriptInfo(0).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(0).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"There is no script at the beginning of the parent source.");
|
||||
is(parsed.getScriptInfo(source.length - 1).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.length - 1).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"There is no script at the end of the parent source.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:31, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:31, length:13, index:0})",
|
||||
"The first script was located correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13, index:1})",
|
||||
"The second script was located correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:151, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:151, length:13, index:2})",
|
||||
"The third script was located correctly.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") - 1).toSource(), "({start:31, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") - 1).toSource(), "({start:31, length:13, index:0})",
|
||||
"The left edge of the first script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") - 1).toSource(), "({start:85, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") - 1).toSource(), "({start:85, length:13, index:1})",
|
||||
"The left edge of the second script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:151, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:151, length:13, index:2})",
|
||||
"The left edge of the third script was interpreted correctly.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") - 2).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") - 2).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The left outside of the first script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") - 2).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") - 2).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The left outside of the second script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") - 2).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") - 2).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The left outside of the third script was interpreted correctly.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") + 12).toSource(), "({start:31, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") + 12).toSource(), "({start:31, length:13, index:0})",
|
||||
"The right edge of the first script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") + 12).toSource(), "({start:85, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") + 12).toSource(), "({start:85, length:13, index:1})",
|
||||
"The right edge of the second script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:151, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:151, length:13, index:2})",
|
||||
"The right edge of the third script was interpreted correctly.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") + 13).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a") + 13).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The right outside of the first script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") + 13).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let b") + 13).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The right outside of the second script was interpreted correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") + 13).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let c") + 13).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The right outside of the third script was interpreted correctly.");
|
||||
|
||||
finish();
|
||||
|
|
|
@ -43,11 +43,11 @@ function test() {
|
|||
is(parsed.scriptCount, 1,
|
||||
"There should be 1 script parsed in the parent HTML source.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The first script shouldn't be considered valid.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13, index:0})",
|
||||
"The second script was located correctly.");
|
||||
is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:-1, length:-1})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:-1, length:-1, index:-1})",
|
||||
"The third script shouldn't be considered valid.");
|
||||
|
||||
finish();
|
||||
|
|
|
@ -32,11 +32,11 @@ function test() {
|
|||
is(parsed.scriptCount, 1,
|
||||
"There should be 1 script parsed in the parent source.");
|
||||
|
||||
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:261})",
|
||||
is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:261, index:0})",
|
||||
"The script location is correct (1).");
|
||||
is(parsed.getScriptInfo(source.indexOf("<script>")).toSource(), "({start:0, length:261})",
|
||||
is(parsed.getScriptInfo(source.indexOf("<script>")).toSource(), "({start:0, length:261, index:0})",
|
||||
"The script location is correct (2).");
|
||||
is(parsed.getScriptInfo(source.indexOf("</script>")).toSource(), "({start:0, length:261})",
|
||||
is(parsed.getScriptInfo(source.indexOf("</script>")).toSource(), "({start:0, length:261, index:0})",
|
||||
"The script location is correct (3).");
|
||||
|
||||
finish();
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests opening inspecting variables works across scopes.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_scope-variable-3.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.test());
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 15);
|
||||
|
||||
yield openVarPopup(panel, { line: 12, ch: 10 });
|
||||
ok(true, "The variable inspection popup was shown for the real variable.");
|
||||
|
||||
once(tooltip, "popupshown").then(() => {
|
||||
ok(false, "The variable inspection popup shouldn't have been opened.");
|
||||
});
|
||||
|
||||
reopenVarPopup(panel, { line: 18, ch: 10 });
|
||||
yield waitForTime(1000);
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(panel);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var trap = "first script";
|
||||
function test() {
|
||||
debugger;
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">/*
|
||||
trololol
|
||||
*/</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -132,15 +132,15 @@ SyntaxTreesPool.prototype = {
|
|||
/**
|
||||
* @see SyntaxTree.prototype.getIdentifierAt
|
||||
*/
|
||||
getIdentifierAt: function(aLine, aColumn) {
|
||||
return this._first(this._call("getIdentifierAt", aLine, aColumn));
|
||||
getIdentifierAt: function({ line, column, scriptIndex }) {
|
||||
return this._first(this._call("getIdentifierAt", scriptIndex, line, column));
|
||||
},
|
||||
|
||||
/**
|
||||
* @see SyntaxTree.prototype.getNamedFunctionDefinitions
|
||||
*/
|
||||
getNamedFunctionDefinitions: function(aSubstring) {
|
||||
return this._call("getNamedFunctionDefinitions", aSubstring);
|
||||
return this._call("getNamedFunctionDefinitions", -1, aSubstring);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -161,12 +161,19 @@ SyntaxTreesPool.prototype = {
|
|||
* The offset and length relative to the enclosing script.
|
||||
*/
|
||||
getScriptInfo: function(aOffset) {
|
||||
let info = { start: -1, length: -1, index: -1 };
|
||||
|
||||
for (let { offset, length } of this._trees) {
|
||||
if (offset <= aOffset && offset + length >= aOffset) {
|
||||
return { start: offset, length: length };
|
||||
info.index++;
|
||||
if (offset <= aOffset && offset + length >= aOffset) {
|
||||
info.start = offset;
|
||||
info.length = length;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return { start: -1, length: -1 };
|
||||
|
||||
info.index = -1;
|
||||
return info;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -182,23 +189,31 @@ SyntaxTreesPool.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Handles a request for all known syntax trees.
|
||||
* Handles a request for a specific or all known syntax trees.
|
||||
*
|
||||
* @param string aFunction
|
||||
* The function name to call on the SyntaxTree instances.
|
||||
* @param number aSyntaxTreeIndex
|
||||
* The syntax tree for which to handle the request. If the tree at
|
||||
* the specified index isn't found, the accumulated results for all
|
||||
* syntax trees are returned.
|
||||
* @param any aParams
|
||||
* Any kind params to pass to the request function.
|
||||
* @return array
|
||||
* The results given by all known syntax trees.
|
||||
*/
|
||||
_call: function(aFunction, ...aParams) {
|
||||
_call: function(aFunction, aSyntaxTreeIndex, ...aParams) {
|
||||
let results = [];
|
||||
let requestId = aFunction + aParams.toSource(); // Cache all the things!
|
||||
let requestId = [aFunction, aSyntaxTreeIndex, aParams].toSource();
|
||||
|
||||
if (this._cache.has(requestId)) {
|
||||
return this._cache.get(requestId);
|
||||
}
|
||||
for (let syntaxTree of this._trees) {
|
||||
|
||||
let requestedTree = this._trees[aSyntaxTreeIndex];
|
||||
let targettedTrees = requestedTree ? [requestedTree] : this._trees;
|
||||
|
||||
for (let syntaxTree of targettedTrees) {
|
||||
try {
|
||||
results.push({
|
||||
sourceUrl: syntaxTree.url,
|
||||
|
|
Загрузка…
Ссылка в новой задаче