mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 17:31:47 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
303
devtools/client/debugger/views/watch-expressions-view.js
Normal file
303
devtools/client/debugger/views/watch-expressions-view.js
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
/* -*- 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 */
|
||||
"use strict";
|
||||
|
||||
const {KeyCodes} = require("devtools/client/shared/keycodes");
|
||||
|
||||
/**
|
||||
* Functions handling the watch expressions UI.
|
||||
*/
|
||||
function WatchExpressionsView(DebuggerController, DebuggerView) {
|
||||
dumpn("WatchExpressionsView was instantiated");
|
||||
|
||||
this.StackFrames = DebuggerController.StackFrames;
|
||||
this.DebuggerView = DebuggerView;
|
||||
|
||||
this.switchExpression = this.switchExpression.bind(this);
|
||||
this.deleteExpression = this.deleteExpression.bind(this);
|
||||
this._createItemView = this._createItemView.bind(this);
|
||||
this._onClick = this._onClick.bind(this);
|
||||
this._onClose = this._onClose.bind(this);
|
||||
this._onBlur = this._onBlur.bind(this);
|
||||
this._onKeyPress = this._onKeyPress.bind(this);
|
||||
}
|
||||
|
||||
WatchExpressionsView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Initialization function, called when the debugger is started.
|
||||
*/
|
||||
initialize: function () {
|
||||
dumpn("Initializing the WatchExpressionsView");
|
||||
|
||||
this.widget = new SimpleListWidget(document.getElementById("expressions"));
|
||||
this.widget.setAttribute("context", "debuggerWatchExpressionsContextMenu");
|
||||
this.widget.addEventListener("click", this._onClick, false);
|
||||
|
||||
this.headerText = L10N.getStr("addWatchExpressionText");
|
||||
this._addCommands();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destruction function, called when the debugger is closed.
|
||||
*/
|
||||
destroy: function () {
|
||||
dumpn("Destroying the WatchExpressionsView");
|
||||
|
||||
this.widget.removeEventListener("click", this._onClick, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add commands that XUL can fire.
|
||||
*/
|
||||
_addCommands: function () {
|
||||
XULUtils.addCommands(document.getElementById("debuggerCommands"), {
|
||||
addWatchExpressionCommand: () => this._onCmdAddExpression(),
|
||||
removeAllWatchExpressionsCommand: () => this._onCmdRemoveAllExpressions()
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a watch expression in this container.
|
||||
*
|
||||
* @param string aExpression [optional]
|
||||
* An optional initial watch expression text.
|
||||
* @param boolean aSkipUserInput [optional]
|
||||
* Pass true to avoid waiting for additional user input
|
||||
* on the watch expression.
|
||||
*/
|
||||
addExpression: function (aExpression = "", aSkipUserInput = false) {
|
||||
// Watch expressions are UI elements which benefit from visible panes.
|
||||
this.DebuggerView.showInstrumentsPane();
|
||||
|
||||
// Create the element node for the watch expression item.
|
||||
let itemView = this._createItemView(aExpression);
|
||||
|
||||
// Append a watch expression item to this container.
|
||||
let expressionItem = this.push([itemView.container], {
|
||||
index: 0, /* specifies on which position should the item be appended */
|
||||
attachment: {
|
||||
view: itemView,
|
||||
initialExpression: aExpression,
|
||||
currentExpression: "",
|
||||
}
|
||||
});
|
||||
|
||||
// Automatically focus the new watch expression input
|
||||
// if additional user input is desired.
|
||||
if (!aSkipUserInput) {
|
||||
expressionItem.attachment.view.inputNode.select();
|
||||
expressionItem.attachment.view.inputNode.focus();
|
||||
this.DebuggerView.Variables.parentNode.scrollTop = 0;
|
||||
}
|
||||
// Otherwise, add and evaluate the new watch expression immediately.
|
||||
else {
|
||||
this.toggleContents(false);
|
||||
this._onBlur({ target: expressionItem.attachment.view.inputNode });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the watch expression corresponding to the specified variable item.
|
||||
* This function is called whenever a watch expression's code is edited in
|
||||
* the variables view container.
|
||||
*
|
||||
* @param Variable aVar
|
||||
* The variable representing the watch expression evaluation.
|
||||
* @param string aExpression
|
||||
* The new watch expression text.
|
||||
*/
|
||||
switchExpression: function (aVar, aExpression) {
|
||||
let expressionItem =
|
||||
[...this].filter(i => i.attachment.currentExpression == aVar.name)[0];
|
||||
|
||||
// Remove the watch expression if it's going to be empty or a duplicate.
|
||||
if (!aExpression || this.getAllStrings().indexOf(aExpression) != -1) {
|
||||
this.deleteExpression(aVar);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the watch expression code string.
|
||||
expressionItem.attachment.currentExpression = aExpression;
|
||||
expressionItem.attachment.view.inputNode.value = aExpression;
|
||||
|
||||
// Synchronize with the controller's watch expressions store.
|
||||
this.StackFrames.syncWatchExpressions();
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the watch expression corresponding to the specified variable item.
|
||||
* This function is called whenever a watch expression's value is edited in
|
||||
* the variables view container.
|
||||
*
|
||||
* @param Variable aVar
|
||||
* The variable representing the watch expression evaluation.
|
||||
*/
|
||||
deleteExpression: function (aVar) {
|
||||
let expressionItem =
|
||||
[...this].filter(i => i.attachment.currentExpression == aVar.name)[0];
|
||||
|
||||
// Remove the watch expression.
|
||||
this.remove(expressionItem);
|
||||
|
||||
// Synchronize with the controller's watch expressions store.
|
||||
this.StackFrames.syncWatchExpressions();
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the watch expression code string for an item in this container.
|
||||
*
|
||||
* @param number aIndex
|
||||
* The index used to identify the watch expression.
|
||||
* @return string
|
||||
* The watch expression code string.
|
||||
*/
|
||||
getString: function (aIndex) {
|
||||
return this.getItemAtIndex(aIndex).attachment.currentExpression;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the watch expressions code strings for all items in this container.
|
||||
*
|
||||
* @return array
|
||||
* The watch expressions code strings.
|
||||
*/
|
||||
getAllStrings: function () {
|
||||
return this.items.map(e => e.attachment.currentExpression);
|
||||
},
|
||||
|
||||
/**
|
||||
* Customization function for creating an item's UI.
|
||||
*
|
||||
* @param string aExpression
|
||||
* The watch expression string.
|
||||
*/
|
||||
_createItemView: function (aExpression) {
|
||||
let container = document.createElement("hbox");
|
||||
container.className = "list-widget-item dbg-expression";
|
||||
container.setAttribute("align", "center");
|
||||
|
||||
let arrowNode = document.createElement("hbox");
|
||||
arrowNode.className = "dbg-expression-arrow";
|
||||
|
||||
let inputNode = document.createElement("textbox");
|
||||
inputNode.className = "plain dbg-expression-input devtools-monospace";
|
||||
inputNode.setAttribute("value", aExpression);
|
||||
inputNode.setAttribute("flex", "1");
|
||||
|
||||
let closeNode = document.createElement("toolbarbutton");
|
||||
closeNode.className = "plain variables-view-delete";
|
||||
|
||||
closeNode.addEventListener("click", this._onClose, false);
|
||||
inputNode.addEventListener("blur", this._onBlur, false);
|
||||
inputNode.addEventListener("keypress", this._onKeyPress, false);
|
||||
|
||||
container.appendChild(arrowNode);
|
||||
container.appendChild(inputNode);
|
||||
container.appendChild(closeNode);
|
||||
|
||||
return {
|
||||
container: container,
|
||||
arrowNode: arrowNode,
|
||||
inputNode: inputNode,
|
||||
closeNode: closeNode
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the add watch expression key sequence was pressed.
|
||||
*/
|
||||
_onCmdAddExpression: function (aText) {
|
||||
// Only add a new expression if there's no pending input.
|
||||
if (this.getAllStrings().indexOf("") == -1) {
|
||||
this.addExpression(aText || this.DebuggerView.editor.getSelection());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the remove all watch expressions key sequence was pressed.
|
||||
*/
|
||||
_onCmdRemoveAllExpressions: function () {
|
||||
// Empty the view of all the watch expressions and clear the cache.
|
||||
this.empty();
|
||||
|
||||
// Synchronize with the controller's watch expressions store.
|
||||
this.StackFrames.syncWatchExpressions();
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for this container.
|
||||
*/
|
||||
_onClick: function (e) {
|
||||
if (e.button != 0) {
|
||||
// Only allow left-click to trigger this event.
|
||||
return;
|
||||
}
|
||||
let expressionItem = this.getItemForElement(e.target);
|
||||
if (!expressionItem) {
|
||||
// The container is empty or we didn't click on an actual item.
|
||||
this.addExpression();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for a watch expression's close button.
|
||||
*/
|
||||
_onClose: function (e) {
|
||||
// Remove the watch expression.
|
||||
this.remove(this.getItemForElement(e.target));
|
||||
|
||||
// Synchronize with the controller's watch expressions store.
|
||||
this.StackFrames.syncWatchExpressions();
|
||||
|
||||
// Prevent clicking the expression element itself.
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
},
|
||||
|
||||
/**
|
||||
* The blur listener for a watch expression's textbox.
|
||||
*/
|
||||
_onBlur: function ({ target: textbox }) {
|
||||
let expressionItem = this.getItemForElement(textbox);
|
||||
let oldExpression = expressionItem.attachment.currentExpression;
|
||||
let newExpression = textbox.value.trim();
|
||||
|
||||
// Remove the watch expression if it's empty.
|
||||
if (!newExpression) {
|
||||
this.remove(expressionItem);
|
||||
}
|
||||
// Remove the watch expression if it's a duplicate.
|
||||
else if (!oldExpression && this.getAllStrings().indexOf(newExpression) != -1) {
|
||||
this.remove(expressionItem);
|
||||
}
|
||||
// Expression is eligible.
|
||||
else {
|
||||
expressionItem.attachment.currentExpression = newExpression;
|
||||
}
|
||||
|
||||
// Synchronize with the controller's watch expressions store.
|
||||
this.StackFrames.syncWatchExpressions();
|
||||
},
|
||||
|
||||
/**
|
||||
* The keypress listener for a watch expression's textbox.
|
||||
*/
|
||||
_onKeyPress: function (e) {
|
||||
switch (e.keyCode) {
|
||||
case KeyCodes.DOM_VK_RETURN:
|
||||
case KeyCodes.DOM_VK_ESCAPE:
|
||||
e.stopPropagation();
|
||||
this.DebuggerView.editor.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
DebuggerView.WatchExpressions = new WatchExpressionsView(DebuggerController,
|
||||
DebuggerView);
|
||||
Loading…
Add table
Add a link
Reference in a new issue