mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 22:53:04 +00:00
c656138b3f
- Bug 1165052 - Part 9: Use ArraySpeciesCreate in Array.prototype.filter. r=efaust (198da18845) - Bug 1165052 - Part 10: Use ArraySpeciesCreate in Array.prototype.map. r=efaust (9dcd625daa) - Bug 1263618: Adapt assertions in RegExp*Raw functions for int32_t; r=arai (8ad46db66d) - Bug 1263340 - Part 1: Use internal slot for global and sticky flags in RegExpBuiltinExec. r=h4writer (9b5fbe6358) - Bug 1263340 - Part 2: Use internal slot for sticky flag in @@replace and @@search optimized path. r=h4writer (2b64567c6a) - Bug 1264264 - Add optimized path for RegExp.prototype[@@replace] with functional replace and substitution. r=till (e55722bc0a) - Bug 1263340 - Part 3: Use internal slot for sticky flag in RegExp native functions. r=h4writer (725cf7b9b0) - Bug 1264264 - Part 2: Enable optimization for packers again in RegExp.prototype[@@replace]. r=h4writer (7f4b819e40) - Bug 1268056 - Check if |this| value is a RegExp object in the optimized path in RegExpSplit. r=h4writer (8891f0a3ef) - Bug 1263340 - Part 4: Followup for @@split - Apply optimized path for empty string too. r=till (956d1804a5) - Bug 1261207 - Forward declare js::ScriptSource instead of casting `¦void*` pointers; r=jimb (4914273e96) - Bug 1041586 - Implement Symbol.isConcatSpreadable. r=arai (238e5f97c6) - Bug 1041586 - Use IsConcatSpreadable in Array.prototype.concat. r=arai (33333cb30f) - Bug 1165052 - Part 11: Use ArraySpeciesCreate in Array.prototype.slice. r=efaust (45f34c0a87) - Bug 1165052 - Part 12: Use ArraySpeciesCreate in Array.prototype.splice. r=efaust,evilpie (096f9ff03d) - Bug 1165052 - Part 13: Add tests for ArraySpeciesCreate. r=efaust (4403642d3c) - Bug 1041586 - Tests. r=arai (efc2d06863) - Bug 1267364 - Check isNative every time in GetStringDataProperty. r=h4writer (6e7898c494) - Bug 1041586 - Fold away property accesses to not-defined properties. r=jandem (216e6387db) - add emacs (fa858771bf) - Bug 1268574 - Check the outparam JSFunction* value after GetGetterPure. r=lth (3d80c79337) - Bug 1263888 - Push TypeBarrier after ArraySlice. r=jandem (2617518401) - Bug 1255316 - IonMonkey: Enable folding of MLoadUnboxedObjectOrNull with the stored value, r=jandem (0f75675721) - Bug 1252313 - Fix wasm i64 shift ops with a constant rhs. r=bbouvier (2c05b901c6) - Bug 1263609: SharedStubs - Port JSOP_POW to shared stubs, r=efaust (54523590d9) - Bug 1247880 - Only remove MUrsh operands when the input of MUrsh is guaranteed to be unsigned. r=sunfish (4a29e0b071) - Bug 1254528: IonMonkey - Check slot before removing load with value of store, r=nbp (3527eb5263) - Bug 1255316 - IonMonkey: Also take into account the offsetAdjustment when folding MLoadUnboxedObjectOrNull, r=jandem (9cbea97df1) - Bug 1263558 - Part 1: Self-host Array generics. r=till,bholley (e1dc0c54c8) - Bug 1103588 - Part 1: Replace deprecated String#contains with String#includes in browser tests and extensions. r=dolske (37558174e8) - Bug 1103588 - Part 3: Replace deprecated String#contains warning with an expression closure warning in sharedWorker_sharedWorker.js test. r=bz (221ff40ebc) - Bug 1103588 - Part 4: Replace deprecated String#contains in js tests. r=till (a794c0b385) - Bug 1103588 - Part 5: Remove deprecated String#contains function; use String#includes instead. r=till (bc1365603e) - Bug 964709 - Updates Parser regex and tests to support self-closing script tags, r=vporof (f04c475ec8) - Bug 1224726 - Do not attempt to parse source file when searching in debugger if text > 1MB;r=jlongster (8743b7bf19) - Bug 1243243 - Use standard license boilerplate in debugger js files. r=jlongster (82684adab3) - Bug 1240804 - Allow remaining unhandled rejections. r=ejpbruel (c30bd6dad2) - Bug 1207702 - Fix a bug in test_promises_object_timetosettle-02.js;r=fitzgen (de776ce006) - Bug 1103588 - Part 2: Replace deprecated String#contains with String#includes in devtools tests. r=jryans (801926270d) - Bug 1263558 - Part 2: Self-host String generics. r=till (4e5766489b) - Bug 1263558 - Part 3: Remove JSFUN_GENERIC_NATIVE. r=till (3f94c198b0) - Bug 1263558 - Part 4: Call initBuiltinConstructor after defining properties in InitStringClass. r=till (f25edc6096) - Bug 1263558 - Part 0.1: Handle OOM inside BuildDominatorTree at AnalyzeNewScriptDefiniteProperties and AnalyzeArgumentsUsage. r=jandem (0f4745e9d4) - Bug 1266573 - Add the JS::ubi::dumpPaths debug utility; r=jimb (9a8680d7c7) - Bug 1266835 - Request names from the rootlist in JS::ubi::dumpPaths and clean up formatting of dumped paths. r=jimb (1e15dd3ab9) - Bug 1263332 - Avoid startup JavaScript strict warning in DirectoryLinksProvider.jsm. r=MattN (06ff76be4d) - Bug 1259911: Only add predecessors to the join block once; r=sunfish (53a9522e68) - Bug 1258905: Remove a bunch of dead IPC code. r=jld (0d9f930a14) - Bug 1266869 - Print a message when no retaining paths are found in JS::ubi::dumpPaths. r=jimb (77a541b4d1)
307 lines
11 KiB
JavaScript
307 lines
11 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
/* import-globals-from ../debugger-controller.js */
|
|
/* import-globals-from ../debugger-view.js */
|
|
/* import-globals-from ../utils.js */
|
|
/* globals document, window */
|
|
"use strict";
|
|
|
|
/**
|
|
* Functions handling the variables bubble UI.
|
|
*/
|
|
function VariableBubbleView(DebuggerController, DebuggerView) {
|
|
dumpn("VariableBubbleView was instantiated");
|
|
|
|
this.StackFrames = DebuggerController.StackFrames;
|
|
this.Parser = DebuggerController.Parser;
|
|
this.DebuggerView = DebuggerView;
|
|
|
|
this._onMouseMove = this._onMouseMove.bind(this);
|
|
this._onMouseOut = this._onMouseOut.bind(this);
|
|
this._onPopupHiding = this._onPopupHiding.bind(this);
|
|
}
|
|
|
|
VariableBubbleView.prototype = {
|
|
/**
|
|
* Initialization function, called when the debugger is started.
|
|
*/
|
|
initialize: function() {
|
|
dumpn("Initializing the VariableBubbleView");
|
|
|
|
this._toolbox = DebuggerController._toolbox;
|
|
this._editorContainer = document.getElementById("editor");
|
|
this._editorContainer.addEventListener("mousemove", this._onMouseMove, false);
|
|
this._editorContainer.addEventListener("mouseout", this._onMouseOut, false);
|
|
|
|
this._tooltip = new Tooltip(document, {
|
|
closeOnEvents: [{
|
|
emitter: this._toolbox,
|
|
event: "select"
|
|
}, {
|
|
emitter: this._editorContainer,
|
|
event: "scroll",
|
|
useCapture: true
|
|
}]
|
|
});
|
|
this._tooltip.defaultPosition = EDITOR_VARIABLE_POPUP_POSITION;
|
|
this._tooltip.defaultShowDelay = EDITOR_VARIABLE_HOVER_DELAY;
|
|
this._tooltip.panel.addEventListener("popuphiding", this._onPopupHiding);
|
|
},
|
|
|
|
/**
|
|
* Destruction function, called when the debugger is closed.
|
|
*/
|
|
destroy: function() {
|
|
dumpn("Destroying the VariableBubbleView");
|
|
|
|
this._tooltip.panel.removeEventListener("popuphiding", this._onPopupHiding);
|
|
this._editorContainer.removeEventListener("mousemove", this._onMouseMove, false);
|
|
this._editorContainer.removeEventListener("mouseout", this._onMouseOut, false);
|
|
},
|
|
|
|
/**
|
|
* Specifies whether literals can be (redundantly) inspected in a popup.
|
|
* This behavior is deprecated, but still tested in a few places.
|
|
*/
|
|
_ignoreLiterals: true,
|
|
|
|
/**
|
|
* Searches for an identifier underneath the specified position in the
|
|
* source editor, and if found, opens a VariablesView inspection popup.
|
|
*
|
|
* @param number x, y
|
|
* The left/top coordinates where to look for an identifier.
|
|
*/
|
|
_findIdentifier: function(x, y) {
|
|
let editor = this.DebuggerView.editor;
|
|
|
|
// Calculate the editor's line and column at the current x and y coords.
|
|
let hoveredPos = editor.getPositionFromCoords({ left: x, top: y });
|
|
let hoveredOffset = editor.getOffset(hoveredPos);
|
|
let hoveredLine = hoveredPos.line;
|
|
let hoveredColumn = hoveredPos.ch;
|
|
|
|
// A source contains multiple scripts. Find the start index of the script
|
|
// containing the specified offset relative to its parent source.
|
|
let contents = editor.getText();
|
|
let location = this.DebuggerView.Sources.selectedValue;
|
|
let parsedSource = this.Parser.get(contents, location);
|
|
let scriptInfo = parsedSource.getScriptInfo(hoveredOffset);
|
|
|
|
// If the script length is negative, we're not hovering JS source code.
|
|
if (scriptInfo.length == -1) {
|
|
return;
|
|
}
|
|
|
|
// Using the script offset, determine the actual line and column inside the
|
|
// script, to use when finding identifiers.
|
|
let scriptStart = editor.getPosition(scriptInfo.start);
|
|
let scriptLineOffset = scriptStart.line;
|
|
let scriptColumnOffset = (hoveredLine == scriptStart.line ? scriptStart.ch : 0);
|
|
|
|
let scriptLine = hoveredLine - scriptLineOffset;
|
|
let scriptColumn = hoveredColumn - scriptColumnOffset;
|
|
let identifierInfo = parsedSource.getIdentifierAt({
|
|
line: scriptLine + 1,
|
|
column: scriptColumn,
|
|
scriptIndex: scriptInfo.index,
|
|
ignoreLiterals: this._ignoreLiterals
|
|
});
|
|
|
|
// If the info is null, we're not hovering any identifier.
|
|
if (!identifierInfo) {
|
|
return;
|
|
}
|
|
|
|
// Transform the line and column relative to the parsed script back
|
|
// to the context of the parent source.
|
|
let { start: identifierStart, end: identifierEnd } = identifierInfo.location;
|
|
let identifierCoords = {
|
|
line: identifierStart.line + scriptLineOffset,
|
|
column: identifierStart.column + scriptColumnOffset,
|
|
length: identifierEnd.column - identifierStart.column
|
|
};
|
|
|
|
// Evaluate the identifier in the current stack frame and show the
|
|
// results in a VariablesView inspection popup.
|
|
this.StackFrames.evaluate(identifierInfo.evalString)
|
|
.then(frameFinished => {
|
|
if ("return" in frameFinished) {
|
|
this.showContents({
|
|
coords: identifierCoords,
|
|
evalPrefix: identifierInfo.evalString,
|
|
objectActor: frameFinished.return
|
|
});
|
|
} else {
|
|
let msg = "Evaluation has thrown for: " + identifierInfo.evalString;
|
|
console.warn(msg);
|
|
dumpn(msg);
|
|
}
|
|
})
|
|
.then(null, err => {
|
|
let msg = "Couldn't evaluate: " + err.message;
|
|
console.error(msg);
|
|
dumpn(msg);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Shows an inspection popup for a specified object actor grip.
|
|
*
|
|
* @param string object
|
|
* An object containing the following properties:
|
|
* - coords: the inspected identifier coordinates in the editor,
|
|
* containing the { line, column, length } properties.
|
|
* - evalPrefix: a prefix for the variables view evaluation macros.
|
|
* - objectActor: the value grip for the object actor.
|
|
*/
|
|
showContents: function({ coords, evalPrefix, objectActor }) {
|
|
let editor = this.DebuggerView.editor;
|
|
let { line, column, length } = coords;
|
|
|
|
// Highlight the function found at the mouse position.
|
|
this._markedText = editor.markText(
|
|
{ line: line - 1, ch: column },
|
|
{ line: line - 1, ch: column + length });
|
|
|
|
// If the grip represents a primitive value, use a more lightweight
|
|
// machinery to display it.
|
|
if (VariablesView.isPrimitive({ value: objectActor })) {
|
|
let className = VariablesView.getClass(objectActor);
|
|
let textContent = VariablesView.getString(objectActor);
|
|
this._tooltip.setTextContent({
|
|
messages: [textContent],
|
|
messagesClass: className,
|
|
containerClass: "plain"
|
|
}, [{
|
|
label: L10N.getStr('addWatchExpressionButton'),
|
|
className: "dbg-expression-button",
|
|
command: () => {
|
|
this.DebuggerView.VariableBubble.hideContents();
|
|
this.DebuggerView.WatchExpressions.addExpression(evalPrefix, true);
|
|
}
|
|
}]);
|
|
} else {
|
|
this._tooltip.setVariableContent(objectActor, {
|
|
searchPlaceholder: L10N.getStr("emptyPropertiesFilterText"),
|
|
searchEnabled: Prefs.variablesSearchboxVisible,
|
|
eval: (variable, value) => {
|
|
let string = variable.evaluationMacro(variable, value);
|
|
this.StackFrames.evaluate(string);
|
|
this.DebuggerView.VariableBubble.hideContents();
|
|
}
|
|
}, {
|
|
getEnvironmentClient: aObject => gThreadClient.environment(aObject),
|
|
getObjectClient: aObject => gThreadClient.pauseGrip(aObject),
|
|
simpleValueEvalMacro: this._getSimpleValueEvalMacro(evalPrefix),
|
|
getterOrSetterEvalMacro: this._getGetterOrSetterEvalMacro(evalPrefix),
|
|
overrideValueEvalMacro: this._getOverrideValueEvalMacro(evalPrefix)
|
|
}, {
|
|
fetched: (aEvent, aType) => {
|
|
if (aType == "properties") {
|
|
window.emit(EVENTS.FETCHED_BUBBLE_PROPERTIES);
|
|
}
|
|
}
|
|
}, [{
|
|
label: L10N.getStr("addWatchExpressionButton"),
|
|
className: "dbg-expression-button",
|
|
command: () => {
|
|
this.DebuggerView.VariableBubble.hideContents();
|
|
this.DebuggerView.WatchExpressions.addExpression(evalPrefix, true);
|
|
}
|
|
}], this._toolbox);
|
|
}
|
|
|
|
this._tooltip.show(this._markedText.anchor);
|
|
},
|
|
|
|
/**
|
|
* Hides the inspection popup.
|
|
*/
|
|
hideContents: function() {
|
|
clearNamedTimeout("editor-mouse-move");
|
|
this._tooltip.hide();
|
|
},
|
|
|
|
/**
|
|
* Checks whether the inspection popup is shown.
|
|
*
|
|
* @return boolean
|
|
* True if the panel is shown or showing, false otherwise.
|
|
*/
|
|
contentsShown: function() {
|
|
return this._tooltip.isShown();
|
|
},
|
|
|
|
/**
|
|
* Functions for getting customized variables view evaluation macros.
|
|
*
|
|
* @param string aPrefix
|
|
* See the corresponding VariablesView.* functions.
|
|
*/
|
|
_getSimpleValueEvalMacro: function(aPrefix) {
|
|
return (item, string) =>
|
|
VariablesView.simpleValueEvalMacro(item, string, aPrefix);
|
|
},
|
|
_getGetterOrSetterEvalMacro: function(aPrefix) {
|
|
return (item, string) =>
|
|
VariablesView.getterOrSetterEvalMacro(item, string, aPrefix);
|
|
},
|
|
_getOverrideValueEvalMacro: function(aPrefix) {
|
|
return (item, string) =>
|
|
VariablesView.overrideValueEvalMacro(item, string, aPrefix);
|
|
},
|
|
|
|
/**
|
|
* The mousemove listener for the source editor.
|
|
*/
|
|
_onMouseMove: function(e) {
|
|
// Prevent the variable inspection popup from showing when the thread client
|
|
// is not paused, or while a popup is already visible, or when the user tries
|
|
// to select text in the editor.
|
|
let isResumed = gThreadClient && gThreadClient.state != "paused";
|
|
let isSelecting = this.DebuggerView.editor.somethingSelected() && e.buttons > 0;
|
|
let isPopupVisible = !this._tooltip.isHidden();
|
|
if (isResumed || isSelecting || isPopupVisible) {
|
|
clearNamedTimeout("editor-mouse-move");
|
|
return;
|
|
}
|
|
// Allow events to settle down first. If the mouse hovers over
|
|
// a certain point in the editor long enough, try showing a variable bubble.
|
|
setNamedTimeout("editor-mouse-move",
|
|
EDITOR_VARIABLE_HOVER_DELAY, () => this._findIdentifier(e.clientX, e.clientY));
|
|
},
|
|
|
|
/**
|
|
* The mouseout listener for the source editor container node.
|
|
*/
|
|
_onMouseOut: function() {
|
|
clearNamedTimeout("editor-mouse-move");
|
|
},
|
|
|
|
/**
|
|
* Listener handling the popup hiding event.
|
|
*/
|
|
_onPopupHiding: function({ target }) {
|
|
if (this._tooltip.panel != target) {
|
|
return;
|
|
}
|
|
if (this._markedText) {
|
|
this._markedText.clear();
|
|
this._markedText = null;
|
|
}
|
|
if (!this._tooltip.isEmpty()) {
|
|
this._tooltip.empty();
|
|
}
|
|
},
|
|
|
|
_editorContainer: null,
|
|
_markedText: null,
|
|
_tooltip: null
|
|
};
|
|
|
|
DebuggerView.VariableBubble = new VariableBubbleView(DebuggerController, DebuggerView);
|