Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js

Issue 1803813002: [DevTools] Added keyboard search while in sources (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Final code cleanup Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
index 7755b1cdc7fc565c0af853c00ba39addfbd23400..f15c29c9fc68e5d0257db86096ce10edddf5995a 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
@@ -42,10 +42,14 @@ function TreeOutline(nonFocusable)
this._contentElement = this._rootElement._childrenListNode;
this._contentElement.addEventListener("keydown", this._treeKeyDown.bind(this), true);
+ this._contentElement.addEventListener("keypress", this._treeKeyPress.bind(this), true);
this.setFocusable(!nonFocusable);
this.element = this._contentElement;
+
+ this.element.addEventListener("blur", this._handleBlur.bind(this), true);
+ this.element.addEventListener("click", this._handleClick.bind(this), true);
}
TreeOutline.Events = {
@@ -64,6 +68,11 @@ TreeOutline.prototype = {
this._rootElement.selectable = false;
this._rootElement.expanded = true;
this._rootElement._childrenListNode.classList.remove("children");
+
+ this._currentSelectionFilterString = '';
pfeldman 2016/03/14 23:51:35 Please only use double quotes.
Allada-Google 2016/03/15 17:13:08 Done.
+ this._currentSelectionFilter = null;
pfeldman 2016/03/14 23:51:34 You should declare a type here using JSDoc.
Allada-Google 2016/03/15 17:13:07 Done.
+ this._highlightChanges = [];
+ this._interactiveFilterEnabled = false;
},
/**
@@ -75,6 +84,79 @@ TreeOutline.prototype = {
},
/**
+ * This will also set/override the RegExp to filter on (ie: setCurrentSelectionFilter())
pfeldman 2016/03/14 23:51:34 We don't explain why (in Blink)...
Allada-Google 2016/03/15 17:13:08 Done.
+ * @param {string} filterString String to filter text on.
pfeldman 2016/03/14 23:51:35 or what... Just the types.
Allada-Google 2016/03/15 17:13:08 Done.
+ */
+ setCurrentSelectionFilterString: function (filterString)
pfeldman 2016/03/14 23:51:35 Seems to be private (starts with _)
Allada-Google 2016/03/15 17:13:08 Done.
+ {
+ this._currentSelectionFilterString = filterString;
+ if (this._currentSelectionFilterString === '')
pfeldman 2016/03/14 23:51:34 ""
Allada-Google 2016/03/15 17:13:08 Done.
+ this.setCurrentSelectionFilter(null);
+ else
+ this.setCurrentSelectionFilter(new RegExp(['(', this._currentSelectionFilterString.escapeForRegExp(), ')'].join(''), 'i'));
+ },
+
+ /**
+ * @return {string}
+ */
+ currentSelectionFilterString: function ()
pfeldman 2016/03/14 23:51:34 lets not expose until required.
Allada-Google 2016/03/15 17:13:08 Done.
+ {
+
+ return this._currentSelectionFilterString;
+ },
+
+ setInteractiveFilterable: function (enable)
pfeldman 2016/03/14 23:51:34 JSDoc for enable type.
Allada-Google 2016/03/15 17:13:07 Done.
+ {
+ this._interactiveFilterEnabled = !!enable;
pfeldman 2016/03/14 23:51:34 Declare it as a boolean and there would be no need
Allada-Google 2016/03/15 17:13:08 Done.
+ },
+
+ /**
+ * @param {?RegExp} filterRegExp Regular Expression to use to filter selectable items
+ */
+ setCurrentSelectionFilter: function (filterRegExp)
+ {
+ var currentFilter = this._currentSelectionFilter;
+ this._currentSelectionFilter = filterRegExp;
+
+ if (this._highlightChanges && this._highlightChanges.length > 0)
pfeldman 2016/03/14 23:51:34 (this._highlightChanges && this._highlightChanges.
Allada-Google 2016/03/15 17:13:08 Done.
+ WebInspector.revertDomChanges(this._highlightChanges);
pfeldman 2016/03/14 23:51:34 We are now vulnerable to the changes made to the e
Allada-Google 2016/03/15 17:13:08 Done.
+ this._highlightChanges = [];
+
+ if (filterRegExp && filterRegExp !== currentFilter) {
pfeldman 2016/03/14 23:51:34 We prefer early returns to nested conditions.
Allada-Google 2016/03/15 17:13:08 Done.
+ // If the list is not fully rendered don't try and continue
+ if (this._rootElement) {
pfeldman 2016/03/14 23:51:34 ditto
Allada-Google 2016/03/15 17:13:08 Done.
+ var textNode = this._rootElement.firstChild();
pfeldman 2016/03/14 23:51:35 textNode is not really a text node, it is a first
+ var childTextNodes = this.element.childTextNodes();
pfeldman 2016/03/14 23:51:34 unused?
+ var newExp = new RegExp(filterRegExp.source, 'gi');
pfeldman 2016/03/14 23:51:34 "gi", also, why new regex?
Allada-Google 2016/03/15 17:13:08 Done.
+
+ if (this.selectedTreeElement && !this.selectedTreeElement.selectable)
+ this.selectNext() || this.selectPrevious();
+
+ do {
+ var match;
+ var ranges = [];
+ var textContent = textNode._listItemNode.textContent;
+ while ((match = newExp.exec(textContent)) !== null) {
pfeldman 2016/03/14 23:51:35 drop !== null, extract match from comparison into
Allada-Google 2016/03/15 17:13:08 Done.
+ ranges.push(new WebInspector.SourceRange(match.index, match[0].length));
+ }
+ if (ranges.length > 0)
+ WebInspector.highlightRangesWithStyleClass(textNode._listItemNode, ranges, "tree-text-interactive-highlight", this._highlightChanges);
+
+ textNode = textNode.traverseNextTreeElement(true, null, true);
+ } while(textNode);
+ }
+ }
+ },
+
+ /**
+ * @return {?RegExp}
+ */
+ currentSelectionFilter: function ()
pfeldman 2016/03/14 23:51:34 do not expose
Allada-Google 2016/03/15 17:13:08 Done.
+ {
+ return this._currentSelectionFilter;
+ },
+
+ /**
* @return {?TreeElement}
*/
firstChild: function()
@@ -187,6 +269,15 @@ TreeOutline.prototype = {
},
/**
+ * @param {!TreeElement} treeElement
+ * @return {boolean}
+ */
+ checkFilter: function (treeElement)
pfeldman 2016/03/14 23:51:34 ditto
Allada-Google 2016/03/15 17:13:08 Done.
+ {
+ return this.currentSelectionFilter() ? this.currentSelectionFilter().test(treeElement.titleText) : true;
+ },
+
+ /**
* @return {boolean}
*/
selectPrevious: function()
@@ -221,6 +312,24 @@ TreeOutline.prototype = {
/**
* @param {!Event} event
*/
+ _handleClick: function (event)
+ {
+ if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString('');
pfeldman 2016/03/14 23:51:34 ""
Allada-Google 2016/03/15 17:13:08 Done.
+ },
+
+ /**
+ * @param {!Event} event
+ */
+ _handleBlur: function (event)
+ {
+ if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString('');
+ },
+
+ /**
+ * @param {!Event} event
+ */
_treeKeyDown: function(event)
{
if (event.target !== this._contentElement)
@@ -229,30 +338,33 @@ TreeOutline.prototype = {
if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
return;
+ var currentFilterString = this.currentSelectionFilterString();
var handled = false;
+ var key = event.keyCode;
var nextSelectedElement;
- if (event.keyIdentifier === "Up" && !event.altKey) {
- handled = this.selectPrevious();
- } else if (event.keyIdentifier === "Down" && !event.altKey) {
- handled = this.selectNext();
- } else if (event.keyIdentifier === "Left") {
- if (this.selectedTreeElement.expanded) {
- if (event.altKey)
- this.selectedTreeElement.collapseRecursively();
- else
- this.selectedTreeElement.collapse();
- handled = true;
- } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
- handled = true;
- if (this.selectedTreeElement.parent.selectable) {
- nextSelectedElement = this.selectedTreeElement.parent;
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.parent;
- handled = nextSelectedElement ? true : false;
- } else if (this.selectedTreeElement.parent)
- this.selectedTreeElement.parent.collapse();
+
+ switch (key) {
+ case WebInspector.KeyboardShortcut.Keys.Esc.code:
+ if (this._interactiveFilterEnabled) {
+ if (currentFilterString.length !== 0)
pfeldman 2016/03/14 23:51:35 drop !== 0
Allada-Google 2016/03/15 17:13:08 Done.
+ // Consider the item handled if the filter string is already set (this will keep the console from triggering)
+ handled = true;
+ this.setCurrentSelectionFilterString('');
}
- } else if (event.keyIdentifier === "Right") {
+ break;
+ case WebInspector.KeyboardShortcut.Keys.Delete.code:
+ if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString('');
+ case WebInspector.KeyboardShortcut.Keys.Backspace.code:
+ if (this._interactiveFilterEnabled === false || currentFilterString.length === 0)
+ handled = this.selectedTreeElement.ondelete();
+ else if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString(currentFilterString.substr(0, currentFilterString.length - 1));
+ break;
+ case WebInspector.KeyboardShortcut.Keys.Right.code:
pfeldman 2016/03/14 23:51:34 Group these and use case fallthrough to handle the
Allada-Google 2016/03/15 17:13:08 I optimized the code I added here as much as I fou
+ if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString('');
+
if (!this.selectedTreeElement.revealed()) {
this.selectedTreeElement.reveal();
handled = true;
@@ -270,12 +382,49 @@ TreeOutline.prototype = {
this.selectedTreeElement.expand();
}
}
- } else if (event.keyCode === 8 /* Backspace */ || event.keyCode === 46 /* Delete */)
- handled = this.selectedTreeElement.ondelete();
- else if (isEnterKey(event))
- handled = this.selectedTreeElement.onenter();
- else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
- handled = this.selectedTreeElement.onspace();
+ break;
+ case WebInspector.KeyboardShortcut.Keys.Left.code:
+ if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString('');
+
+ if (this.selectedTreeElement.expanded) {
+ if (event.altKey)
+ this.selectedTreeElement.collapseRecursively();
+ else
+ this.selectedTreeElement.collapse();
+ handled = true;
+ } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
+ handled = true;
+ if (this.selectedTreeElement.parent.selectable) {
+ nextSelectedElement = this.selectedTreeElement.parent;
+ while (nextSelectedElement && !nextSelectedElement.selectable)
+ nextSelectedElement = nextSelectedElement.parent;
+ handled = nextSelectedElement ? true : false;
+ } else if (this.selectedTreeElement.parent)
+ this.selectedTreeElement.parent.collapse();
+ }
+ break;
+ case WebInspector.KeyboardShortcut.Keys.Down.code:
+ if (!event.altKey)
+ handled = this.selectNext();
+ break;
+ case WebInspector.KeyboardShortcut.Keys.Up.code:
+ if (!event.altKey)
+ handled = this.selectPrevious();
+ break;
+ case WebInspector.KeyboardShortcut.Keys.Space.code:
+ // Do not send space key event if the search filter has stuff in buffer
+ if (currentFilterString.length === 0)
+ handled = this.selectedTreeElement.onspace();
+ break;
+ default:
+ if (isEnterKey(event)) {
+ if (this._interactiveFilterEnabled)
+ this.setCurrentSelectionFilterString('');
+
+ handled = this.selectedTreeElement.onenter();
+ }
+ }
if (nextSelectedElement) {
nextSelectedElement.reveal();
@@ -287,6 +436,35 @@ TreeOutline.prototype = {
},
/**
+ * @param {!Event} event
+ */
+ _treeKeyPress: function (event)
+ {
+ if (this._interactiveFilterEnabled === false)
pfeldman 2016/03/14 23:51:34 !this._interactiveFilterEnabled
Allada-Google 2016/03/15 17:13:08 Done.
+ return;
+
+ if (event.target !== this._contentElement)
+ return;
+
+ if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
+ return;
+
+ var currentFilterString = this.currentSelectionFilterString();
+
+ switch (event.data) {
+ case "\r":
+ case "\n":
+ break;
+ case " ":
+ if (currentFilterString.length === 0) {
+ break;
+ }
+ default:
+ this.setCurrentSelectionFilterString(currentFilterString + event.data);
+ }
+ },
+
+ /**
* @param {!TreeElement} treeElement
* @param {boolean} center
*/
@@ -360,6 +538,7 @@ function TreeElement(title, expandable)
this._listItemNode = createElement("li");
this._listItemNode.treeElement = this;
+ this.titleText = null;
pfeldman 2016/03/14 23:51:34 Lets compute this dynamically off element's text c
if (title)
this.title = title;
this._listItemNode.addEventListener("mousedown", this._handleMouseDown.bind(this), false);
@@ -603,7 +782,7 @@ TreeElement.prototype = {
get selectable()
{
- if (this._hidden)
+ if (this._hidden || !this.treeOutline.checkFilter(this))
return false;
return this._selectable;
},
@@ -641,6 +820,7 @@ TreeElement.prototype = {
this._titleElement = createElementWithClass("span", "tree-element-title");
this._titleElement.textContent = x;
this.tooltip = x;
+ this.titleText = x;
} else {
this._titleElement = x;
this.tooltip = "";

Powered by Google App Engine
This is Rietveld 408576698