Chromium Code Reviews| 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..9bf1a75ad50e228a04d8f4f67dd303bfe15a517c 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js |
| @@ -42,6 +42,7 @@ 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); |
| @@ -52,7 +53,8 @@ TreeOutline.Events = { |
| ElementAttached: "ElementAttached", |
| ElementExpanded: "ElementExpanded", |
| ElementCollapsed: "ElementCollapsed", |
| - ElementSelected: "ElementSelected" |
| + ElementSelected: "ElementSelected", |
| + FilterChanged: "FilterChanged" |
| } |
| TreeOutline.prototype = { |
| @@ -64,6 +66,9 @@ TreeOutline.prototype = { |
| this._rootElement.selectable = false; |
| this._rootElement.expanded = true; |
| this._rootElement._childrenListNode.classList.remove("children"); |
| + |
| + this._currentSelectionFilterString = ''; |
|
lushnikov
2016/03/14 20:56:38
style: double quotes for strings
|
| + this._currentSelectionFilter = null; |
| }, |
| /** |
| @@ -75,6 +80,53 @@ TreeOutline.prototype = { |
| }, |
| /** |
| + * This will also set/override the RegExp to filter on (ie: setCurrentSelectionFilter()) |
| + * @param {string} filterString String to filter text on. |
| + */ |
| + setCurrentSelectionFilterString: function (filterString) |
| + { |
| + this._currentSelectionFilterString = filterString; |
| + if(this._currentSelectionFilterString === '') |
| + this.setCurrentSelectionFilter(null); |
| + else |
| + this.setCurrentSelectionFilter(new RegExp(['(', this._currentSelectionFilterString, ')'].join(''), 'i')); |
| + }, |
| + |
| + /** |
| + * @return {string} |
| + */ |
| + currentSelectionFilterString: function () |
| + { |
| + |
|
lushnikov
2016/03/14 20:56:38
style: stray line
|
| + return this._currentSelectionFilterString; |
| + }, |
| + |
| + /** |
| + * @param {?RegExp} filterRegExp Regular Expression to use to filter selectable items |
| + */ |
| + setCurrentSelectionFilter: function (filterRegExp) |
| + { |
| + var currentFilter = this._currentSelectionFilter; |
| + this._currentSelectionFilter = filterRegExp; |
| + |
| + if (filterRegExp !== currentFilter) { |
| + this.dispatchEventToListeners(TreeOutline.Events.FilterChanged, { |
| + treeOutline: this, |
| + changeTo: filterRegExp, |
| + changeFrom: currentFilter |
| + }); |
| + } |
| + }, |
| + |
| + /** |
| + * @return {?RegExp} |
| + */ |
| + currentSelectionFilter: function () |
| + { |
| + return this._currentSelectionFilter; |
| + }, |
| + |
| + /** |
| * @return {?TreeElement} |
| */ |
| firstChild: function() |
| @@ -187,12 +239,22 @@ TreeOutline.prototype = { |
| }, |
| /** |
| + * @param {!TreeElement} treeElement |
| + * @return {boolean} |
| + */ |
| + checkFilter: function (treeElement) |
| + { |
| + return this.currentSelectionFilter() ? this.currentSelectionFilter().test(treeElement.titleText) : true; |
| + }, |
| + |
| + /** |
| + * @param {!RegExp=} filter |
| * @return {boolean} |
| */ |
| - selectPrevious: function() |
| + selectPrevious: function(filter) |
| { |
| var nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true); |
| - while (nextSelectedElement && !nextSelectedElement.selectable) |
| + while (nextSelectedElement && (!nextSelectedElement.selectable || (filter ? !filter.test(nextSelectedElement.titleText) : false))) |
| nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing); |
| if (nextSelectedElement) { |
| nextSelectedElement.reveal(); |
| @@ -229,53 +291,89 @@ TreeOutline.prototype = { |
| if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey) |
| return; |
| - var handled = false; |
| - 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(); |
| - } |
| - } else if (event.keyIdentifier === "Right") { |
| - if (!this.selectedTreeElement.revealed()) { |
| - this.selectedTreeElement.reveal(); |
| - handled = true; |
| - } else if (this.selectedTreeElement._expandable) { |
| - handled = true; |
| - if (this.selectedTreeElement.expanded) { |
| - nextSelectedElement = this.selectedTreeElement.firstChild(); |
| - while (nextSelectedElement && !nextSelectedElement.selectable) |
| - nextSelectedElement = nextSelectedElement.nextSibling; |
| - handled = nextSelectedElement ? true : false; |
| + var currentFilterString = this.currentSelectionFilterString(), |
| + nextSelectedElement, |
|
lushnikov
2016/03/14 20:56:38
style: we don't wrap variable declaration.
If ther
|
| + handled = false, |
| + key = event.keyCode; |
| + |
| + // is a key to ignore (non printable key) |
| + switch (key) { |
| + case WebInspector.KeyboardShortcut.Keys.Esc.code: |
| + if (currentFilterString.length !== 0) { |
| + // Consider the item handled if the filter string is already set. (this will keep the console from triggering) |
| + handled = true; |
| + } |
| + this.setCurrentSelectionFilterString(''); |
| + break; |
| + case WebInspector.KeyboardShortcut.Keys.Delete.code: |
| + // Clear out the filter |
| + this.setCurrentSelectionFilterString(''); |
| + case WebInspector.KeyboardShortcut.Keys.Backspace.code: |
| + // Only perform this action if no filter is set. |
| + if (currentFilterString.length === 0) { |
| + handled = this.selectedTreeElement.ondelete(); |
| } else { |
| + this.setCurrentSelectionFilterString(currentFilterString.substr(0, currentFilterString.length - 1)); |
| + } |
| + break; |
| + case WebInspector.KeyboardShortcut.Keys.Right.code: |
| + this.setCurrentSelectionFilterString(''); |
| + if (!this.selectedTreeElement.revealed()) { |
| + this.selectedTreeElement.reveal(); |
| + handled = true; |
| + } else if (this.selectedTreeElement._expandable) { |
| + handled = true; |
| + if (this.selectedTreeElement.expanded) { |
| + nextSelectedElement = this.selectedTreeElement.firstChild(); |
| + while (nextSelectedElement && !nextSelectedElement.selectable) |
| + nextSelectedElement = nextSelectedElement.nextSibling; |
| + handled = nextSelectedElement ? true : false; |
| + } else { |
| + if (event.altKey) |
| + this.selectedTreeElement.expandRecursively(); |
| + else |
| + this.selectedTreeElement.expand(); |
| + } |
| + } |
| + break; |
| + case WebInspector.KeyboardShortcut.Keys.Left.code: |
| + this.setCurrentSelectionFilterString(''); |
| + if (this.selectedTreeElement.expanded) { |
| if (event.altKey) |
| - this.selectedTreeElement.expandRecursively(); |
| + this.selectedTreeElement.collapseRecursively(); |
| else |
| - this.selectedTreeElement.expand(); |
| + 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)) { |
| + this.setCurrentSelectionFilterString(''); |
| + handled = this.selectedTreeElement.onenter(); |
| } |
| } |
| - } 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(); |
| if (nextSelectedElement) { |
| nextSelectedElement.reveal(); |
| @@ -287,6 +385,35 @@ TreeOutline.prototype = { |
| }, |
| /** |
| + * @param {!Event} event |
| + */ |
| + _treeKeyPress: function (event) |
| + { |
| + 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": |
| + // Ignore these (do not append to filter string) |
| + break; |
| + case " ": |
| + if (currentFilterString.length === 0) { |
| + // Do not append string if there is no filter data |
| + break; |
| + } |
| + default: |
| + // Append the new character to the current filter string and select next element if fails try previous element |
| + this.setCurrentSelectionFilterString(currentFilterString + event.data); |
| + } |
| + }, |
| + |
| + /** |
| * @param {!TreeElement} treeElement |
| * @param {boolean} center |
| */ |
| @@ -360,6 +487,7 @@ function TreeElement(title, expandable) |
| this._listItemNode = createElement("li"); |
| this._listItemNode.treeElement = this; |
| + this.titleText = null; |
| if (title) |
| this.title = title; |
| this._listItemNode.addEventListener("mousedown", this._handleMouseDown.bind(this), false); |
| @@ -603,7 +731,7 @@ TreeElement.prototype = { |
| get selectable() |
| { |
| - if (this._hidden) |
| + if (this._hidden || !this.treeOutline.checkFilter(this)) |
| return false; |
| return this._selectable; |
| }, |
| @@ -641,6 +769,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 = ""; |