commit a192b4adaca5dce8d96331066ed88390554f7167
parent 33beadcdd30716d67241b1fa6bc5ac920bad7a54
Author: Lorenz A <me@lorenzackermann.xyz>
Date: Mon, 15 Dec 2025 14:25:56 +0000
Bug 2004255 - [devtools] Turn devtools/client/shared/widgets/TreeWidget.js into an ES class. r=devtools-reviewers,nchevobbe
Differential Revision: https://phabricator.services.mozilla.com/D276393
Diffstat:
1 file changed, 111 insertions(+), 110 deletions(-)
diff --git a/devtools/client/shared/widgets/TreeWidget.js b/devtools/client/shared/widgets/TreeWidget.js
@@ -10,47 +10,47 @@ const { KeyCodes } = require("resource://devtools/client/shared/keycodes.js");
/**
* A tree widget with keyboard navigation and collapsable structure.
- *
- * @param {Node} node
- * The container element for the tree widget.
- * @param {object} options
- * - emptyText {string}: text to display when no entries in the table.
- * - defaultType {string}: The default type of the tree items. For ex.
- * 'js'
- * - sorted {boolean}: Defaults to true. If true, tree items are kept in
- * lexical order. If false, items will be kept in insertion order.
- * - contextMenuId {string}: ID of context menu to be displayed on
- * tree items.
*/
-function TreeWidget(node, options = {}) {
- EventEmitter.decorate(this);
+class TreeWidget extends EventEmitter {
+ /**
+ * @param {Node} node
+ * The container element for the tree widget.
+ * @param {object} options
+ * @param {string} [options.emptyText] text to display when no entries in the table.
+ * @param {string} options.defaultType The default type of the tree items. For ex.
+ * 'js'
+ * @param {boolean} [options.sorted] Defaults to true. If true, tree items are kept in
+ * lexical order. If false, items will be kept in insertion order.
+ * @param {string} [options.contextMenuId] ID of context menu to be displayed on
+ * tree items.
+ */
+ constructor(node, options = {}) {
+ super();
- this.document = node.ownerDocument;
- this.window = this.document.defaultView;
- this._parent = node;
+ this.document = node.ownerDocument;
+ this.window = this.document.defaultView;
+ this._parent = node;
- this.emptyText = options.emptyText || "";
- this.defaultType = options.defaultType;
- this.sorted = options.sorted !== false;
- this.contextMenuId = options.contextMenuId;
+ this.emptyText = options.emptyText || "";
+ this.defaultType = options.defaultType;
+ this.sorted = options.sorted !== false;
+ this.contextMenuId = options.contextMenuId;
- this.setupRoot();
+ this.setupRoot();
- this.placeholder = this.document.createElementNS(HTML_NS, "label");
- this.placeholder.className = "tree-widget-empty-text";
- this._parent.appendChild(this.placeholder);
+ this.placeholder = this.document.createElementNS(HTML_NS, "label");
+ this.placeholder.className = "tree-widget-empty-text";
+ this._parent.appendChild(this.placeholder);
- if (this.emptyText) {
- this.setPlaceholderText(this.emptyText);
+ if (this.emptyText) {
+ this.setPlaceholderText(this.emptyText);
+ }
+ // A map to hold all the passed attachment to each leaf in the tree.
+ this.attachments = new Map();
}
- // A map to hold all the passed attachment to each leaf in the tree.
- this.attachments = new Map();
-}
-
-TreeWidget.prototype = {
- _selectedLabel: null,
- _selectedItem: null,
+ _selectedLabel = null;
+ _selectedItem = null;
/**
* Select any node in the tree.
*
@@ -83,7 +83,7 @@ TreeWidget.prototype = {
this.attachments.get(JSON.stringify(ids))
);
}
- },
+ }
/**
* Gets the selected item in the tree.
@@ -93,7 +93,7 @@ TreeWidget.prototype = {
*/
get selectedItem() {
return this._selectedItem;
- },
+ }
/**
* Returns if the passed array corresponds to the selected item in the tree.
@@ -113,12 +113,12 @@ TreeWidget.prototype = {
}
return true;
- },
+ }
destroy() {
this.root.remove();
this.root = null;
- },
+ }
/**
* Sets up the root container of the TreeWidget.
@@ -140,7 +140,7 @@ TreeWidget.prototype = {
this.root.children.addEventListener("mousedown", e => this.onClick(e));
this.root.children.addEventListener("keydown", e => this.onKeydown(e));
- },
+ }
/**
* Sets the text to be shown when no node is present in the tree.
@@ -153,7 +153,7 @@ TreeWidget.prototype = {
} else {
this.placeholder.setAttribute("hidden", "true");
}
- },
+ }
/**
* Select any node in the tree.
@@ -163,7 +163,7 @@ TreeWidget.prototype = {
*/
selectItem(id) {
this.selectedItem = id;
- },
+ }
/**
* Selects the next visible item in the tree.
@@ -173,7 +173,7 @@ TreeWidget.prototype = {
if (next) {
this.selectedItem = next;
}
- },
+ }
/**
* Selects the previos visible item in the tree
@@ -183,7 +183,7 @@ TreeWidget.prototype = {
if (prev) {
this.selectedItem = prev;
}
- },
+ }
/**
* Returns the next visible item in the tree
@@ -205,7 +205,7 @@ TreeWidget.prototype = {
node = node.parentNode;
}
return null;
- },
+ }
/**
* Returns the previous visible item in the tree
@@ -234,11 +234,11 @@ TreeWidget.prototype = {
return JSON.parse(node.getAttribute("data-id"));
}
return null;
- },
+ }
clearSelection() {
this.selectedItem = -1;
- },
+ }
/**
* Adds an item in the tree. The item can be added as a child to any node in
@@ -281,7 +281,7 @@ TreeWidget.prototype = {
}
// Empty the empty-tree-text
this.setPlaceholderText("");
- },
+ }
/**
* Check if an item exists.
@@ -300,7 +300,7 @@ TreeWidget.prototype = {
}
}
return true;
- },
+ }
/**
* Removes the specified item and all of its child items from the tree.
@@ -315,7 +315,7 @@ TreeWidget.prototype = {
if (this.root.items.size == 0 && this.emptyText) {
this.setPlaceholderText(this.emptyText);
}
- },
+ }
/**
* Removes all of the child nodes from this tree.
@@ -327,21 +327,21 @@ TreeWidget.prototype = {
if (this.emptyText) {
this.setPlaceholderText(this.emptyText);
}
- },
+ }
/**
* Expands the tree completely
*/
expandAll() {
this.root.expandAll();
- },
+ }
/**
* Collapses the tree completely
*/
collapseAll() {
this.root.collapseAll();
- },
+ }
/**
* Click handler for the tree. Used to select, open and close the tree nodes.
@@ -368,7 +368,7 @@ TreeWidget.prototype = {
const ids = target.parentNode.getAttribute("data-id");
this.selectedItem = JSON.parse(ids);
}
- },
+ }
/**
* Keydown handler for this tree. Used to select next and previous visible
@@ -407,7 +407,7 @@ TreeWidget.prototype = {
return;
}
event.preventDefault();
- },
+ }
/**
* Scrolls the viewport of the tree so that the selected item is always
@@ -421,72 +421,73 @@ TreeWidget.prototype = {
} else if (bottom > height) {
this._selectedLabel.scrollIntoView(false);
}
- },
-};
+ }
+}
module.exports.TreeWidget = TreeWidget;
/**
* Any item in the tree. This can be an empty leaf node also.
- *
- * @param {HTMLDocument} document
- * The document element used for creating new nodes.
- * @param {TreeItem} parent
- * The parent item for this item.
- * @param {string|DOMElement} label
- * Either the dom node to be used as the item, or the string to be
- * displayed for this node in the tree
- * @param {string} type
- * The type of the current node. For ex. "js"
*/
-function TreeItem(document, parent, label, type) {
- this.document = document;
- this.node = this.document.createElementNS(HTML_NS, "li");
- this.node.setAttribute("tabindex", "0");
- this.isRoot = !parent;
- this.parent = parent;
- if (this.parent) {
- this.level = this.parent.level + 1;
- }
- if (label) {
- this.label = this.document.createElementNS(HTML_NS, "div");
- this.label.setAttribute("empty", "true");
- this.label.setAttribute("level", this.level);
- this.label.className = "tree-widget-item";
- if (type) {
- this.label.setAttribute("type", type);
- }
- if (typeof label == "string") {
- this.label.textContent = label;
+class TreeItem {
+ /**
+ * @param {HTMLDocument} document
+ * The document element used for creating new nodes.
+ * @param {TreeItem} parent
+ * The parent item for this item.
+ * @param {string|DOMElement} label
+ * Either the dom node to be used as the item, or the string to be
+ * displayed for this node in the tree
+ * @param {string} type
+ * The type of the current node. For ex. "js"
+ */
+ constructor(document, parent, label, type) {
+ this.document = document;
+ this.node = this.document.createElementNS(HTML_NS, "li");
+ this.node.setAttribute("tabindex", "0");
+ this.isRoot = !parent;
+ this.parent = parent;
+ if (this.parent) {
+ this.level = this.parent.level + 1;
+ }
+ if (label) {
+ this.label = this.document.createElementNS(HTML_NS, "div");
+ this.label.setAttribute("empty", "true");
+ this.label.setAttribute("level", this.level);
+ this.label.className = "tree-widget-item";
+ if (type) {
+ this.label.setAttribute("type", type);
+ }
+ if (typeof label == "string") {
+ this.label.textContent = label;
+ } else {
+ this.label.appendChild(label);
+ }
+ this.node.appendChild(this.label);
+ }
+ this.children = this.document.createElementNS(HTML_NS, "ul");
+ if (this.isRoot) {
+ this.children.className = "tree-widget-container";
} else {
- this.label.appendChild(label);
+ this.children.className = "tree-widget-children";
}
- this.node.appendChild(this.label);
- }
- this.children = this.document.createElementNS(HTML_NS, "ul");
- if (this.isRoot) {
- this.children.className = "tree-widget-container";
- } else {
- this.children.className = "tree-widget-children";
+ this.node.appendChild(this.children);
+ this.items = new Map();
}
- this.node.appendChild(this.children);
- this.items = new Map();
-}
-TreeItem.prototype = {
- items: null,
+ items = null;
- isSelected: false,
+ isSelected = false;
- expanded: false,
+ expanded = false;
- isRoot: false,
+ isRoot = false;
- parent: null,
+ parent = null;
- children: null,
+ children = null;
- level: 0,
+ level = 0;
/**
* Adds the item to the sub tree contained by this node. The item to be
@@ -559,7 +560,7 @@ TreeItem.prototype = {
this.label.removeAttribute("empty");
}
this.items.set(id, treeItem);
- },
+ }
/**
* If this item is to be removed, then removes this item and thus all of its
@@ -584,7 +585,7 @@ TreeItem.prototype = {
} else if (!id) {
this.destroy();
}
- },
+ }
/**
* If this item is to be selected, then selected and expands the item.
@@ -607,7 +608,7 @@ TreeItem.prototype = {
return label;
}
return null;
- },
+ }
/**
* Collapses this item and all of its sub tree items
@@ -619,7 +620,7 @@ TreeItem.prototype = {
for (const child of this.items.values()) {
child.collapseAll();
}
- },
+ }
/**
* Expands this item and all of its sub tree items
@@ -631,7 +632,7 @@ TreeItem.prototype = {
for (const child of this.items.values()) {
child.expandAll();
}
- },
+ }
destroy() {
this.children.remove();
@@ -639,5 +640,5 @@ TreeItem.prototype = {
this.label = null;
this.items = null;
this.children = null;
- },
-};
+ }
+}