Index: Source/devtools/front_end/StylesSidebarPane.js |
diff --git a/Source/devtools/front_end/StylesSidebarPane.js b/Source/devtools/front_end/StylesSidebarPane.js |
index 794093e6518c72180c554eb2e8777daa31c7660f..ef1fb4a0f67f504fc1fc3cf975db2f1ba7629e9d 100644 |
--- a/Source/devtools/front_end/StylesSidebarPane.js |
+++ b/Source/devtools/front_end/StylesSidebarPane.js |
@@ -51,7 +51,7 @@ WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallb |
this.titleElement.appendChild(addButton); |
this._computedStylePane = computedStylePane; |
- computedStylePane._stylesSidebarPane = this; |
+ computedStylePane.setHostingPane(this); |
this._setPseudoClassCallback = setPseudoClassCallback; |
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); |
WebInspector.settings.colorFormat.addChangeListener(this._colorFormatSettingChanged.bind(this)); |
@@ -180,6 +180,62 @@ WebInspector.StylesSidebarPane.prototype = { |
contextMenu.show(); |
}, |
+ /** |
+ * @param {!Element} matchedStylesElement |
+ * @param {!Element} computedStylesElement |
+ */ |
+ setFilterBoxContainers: function(matchedStylesElement, computedStylesElement) |
+ { |
+ matchedStylesElement.appendChild(this._createCSSFilterControl()); |
+ this._computedStylePane.setFilterBoxContainer(computedStylesElement); |
+ }, |
+ |
+ /** |
+ * @return {!Element} |
+ */ |
+ _createCSSFilterControl: function() |
+ { |
+ var filterInput = this._createPropertyFilterElement(false, searchHandler.bind(this)); |
+ |
+ /** |
+ * @param {?RegExp} regex |
+ * @this {WebInspector.StylesSidebarPane} |
+ */ |
+ function searchHandler(regex) |
+ { |
+ this._filterRegex = regex; |
+ } |
+ |
+ filterInput.addEventListener("keydown", tabHandler.bind(this), false); |
+ |
+ /** |
+ * @param {?Event} event |
+ * @this {WebInspector.StylesSidebarPane} |
+ */ |
+ function tabHandler(event) |
pfeldman
2014/03/13 05:33:53
It seems like editingCommitted is already implemen
apavlov
2014/03/13 16:28:15
Correct. Reused the logic.
|
+ { |
+ if (event.keyIdentifier !== "U+0009") |
+ return; |
+ |
+ event.consume(true); |
+ var firstSection = this.sections[0][1]; |
+ if (!firstSection) |
+ return; |
+ if (event.shiftKey) { |
+ var lastSection = firstSection.previousEditableSibling(); |
+ if (!lastSection) |
+ return; |
+ lastSection.addNewBlankProperty().startEditing(); |
+ } else { |
+ if (firstSection.rule) |
+ firstSection.startEditingSelector(); |
+ else |
+ firstSection._moveEditorFromSelector("forward"); |
+ } |
+ } |
+ return filterInput; |
+ }, |
+ |
get _forcedPseudoClasses() |
{ |
return this.node ? (this.node.getUserProperty("pseudoState") || undefined) : undefined; |
@@ -807,20 +863,82 @@ WebInspector.StylesSidebarPane.prototype = { |
return td; |
} |
- var tr = document.createElement("tr"); |
+ var tr = table.createChild("tr"); |
tr.appendChild(createCheckbox.call(this, "active")); |
tr.appendChild(createCheckbox.call(this, "hover")); |
- table.appendChild(tr); |
- tr = document.createElement("tr"); |
+ tr = table.createChild("tr"); |
tr.appendChild(createCheckbox.call(this, "focus")); |
tr.appendChild(createCheckbox.call(this, "visited")); |
- table.appendChild(tr); |
this._elementStatePane.appendChild(table); |
}, |
/** |
+ * @return {?RegExp} |
+ */ |
+ filterRegex: function() |
+ { |
+ return this._filterRegex; |
+ }, |
+ |
+ /** |
+ * @param {boolean} isComputedStyleFilter |
+ * @return {!Element} |
+ * @param {function(?RegExp)} filterCallback |
+ */ |
+ _createPropertyFilterElement: function(isComputedStyleFilter, filterCallback) |
+ { |
+ var input = document.createElement("input"); |
+ input.type = "text"; |
+ input.placeholder = isComputedStyleFilter ? WebInspector.UIString("Filter") : WebInspector.UIString("Find in Styles"); |
+ input.className = "filter-box toolbar-search-control search-replace"; |
pfeldman
2014/03/13 05:33:53
You are using styles that can change independently
apavlov
2014/03/13 16:28:15
I'm sharing styles with other search controls, so
|
+ var boundSearchHandler = searchHandler.bind(this); |
+ |
+ /** |
+ * @this {WebInspector.StylesSidebarPane} |
+ */ |
+ function searchHandler() |
+ { |
+ var regex = input.value ? new RegExp(input.value.escapeForRegExp(), "i") : null; |
+ filterCallback(regex); |
+ this._updateFilter(isComputedStyleFilter); |
+ } |
+ input.addEventListener("input", boundSearchHandler, false); |
+ |
+ /** |
+ * @param {?Event} event |
+ */ |
+ function keydownHandler(event) |
+ { |
+ if (event.keyIdentifier !== "U+001B" || !input.value) |
pfeldman
2014/03/13 05:33:53
What is 1B?
apavlov
2014/03/13 16:28:15
It's "Esc". I'll create a separate var for this.
|
+ return; |
+ event.consume(true); |
+ input.value = ""; |
+ boundSearchHandler(); |
+ } |
+ input.addEventListener("keydown", keydownHandler, false); |
+ |
+ return input; |
+ }, |
+ |
+ /** |
+ * @param {boolean} isComputedStyleFilter |
+ */ |
+ _updateFilter: function(isComputedStyleFilter) |
+ { |
+ for (var pseudoId in this.sections) { |
+ var sections = this.sections[pseudoId]; |
+ for (var i = 0; i < sections.length; ++i) { |
+ var section = sections[i]; |
+ if (isComputedStyleFilter !== !!section.computedStyle) |
+ continue; |
+ section.updateFilter(); |
+ } |
+ } |
+ }, |
+ |
+ /** |
* @param {!WebInspector.Event} event |
*/ |
_showUserAgentStylesSettingChanged: function(event) |
@@ -881,6 +999,28 @@ WebInspector.ComputedStyleSidebarPane = function() |
} |
WebInspector.ComputedStyleSidebarPane.prototype = { |
+ /** |
+ * @param {!WebInspector.StylesSidebarPane} pane |
+ */ |
+ setHostingPane: function(pane) |
+ { |
+ this._stylesSidebarPane = pane; |
+ }, |
+ |
+ setFilterBoxContainer: function(element) |
+ { |
+ element.appendChild(this._stylesSidebarPane._createPropertyFilterElement(true, filterCallback.bind(this))); |
pfeldman
2014/03/13 05:33:53
This is a strange API. Why does computed style pan
apavlov
2014/03/13 16:28:15
The key point here is that the filters are uniform
|
+ |
+ /** |
+ * @param {?RegExp} regex |
+ * @this {WebInspector.ComputedStyleSidebarPane} |
+ */ |
+ function filterCallback(regex) |
+ { |
+ this._filterRegex = regex; |
+ } |
+ }, |
+ |
wasShown: function() |
{ |
WebInspector.SidebarPane.prototype.wasShown.call(this); |
@@ -905,6 +1045,14 @@ WebInspector.ComputedStyleSidebarPane.prototype = { |
this._stylesSidebarPane._refreshUpdate(null, true, wrappedCallback.bind(this)); |
}, |
+ /** |
+ * @return {?RegExp} |
+ */ |
+ filterRegex: function() |
+ { |
+ return this._filterRegex; |
+ }, |
+ |
__proto__: WebInspector.SidebarPane.prototype |
} |
@@ -1222,6 +1370,16 @@ WebInspector.StylePropertiesSection.prototype = { |
} |
}, |
+ updateFilter: function() |
+ { |
+ var children = this.propertiesTreeOutline.children; |
+ for (var i = 0; i < children.length; ++i) |
+ children[i].updateFilter(); |
+ |
+ if (this.styleRule.rule) |
+ this._markSelectorHighlights(); |
+ }, |
+ |
_markSelectorMatches: function() |
{ |
var rule = this.styleRule.rule; |
@@ -1257,6 +1415,17 @@ WebInspector.StylePropertiesSection.prototype = { |
this._selectorElement.removeChildren(); |
this._selectorElement.appendChild(fragment); |
+ this._markSelectorHighlights(); |
+ }, |
+ |
+ _markSelectorHighlights: function() |
+ { |
+ var selectors = this._selectorElement.getElementsByClassName("simple-selector"); |
+ var regex = this.pane.filterRegex(); |
+ for (var i = 0; i < selectors.length; ++i) { |
+ var selectorMatchesFilter = regex && regex.test(selectors[i].textContent); |
+ selectors[i].enableStyleClass("filter-match", selectorMatchesFilter); |
+ } |
}, |
_checkWillCancelEditing: function() |
@@ -1506,8 +1675,10 @@ WebInspector.ComputedStylePropertiesSection = function(stylesPane, styleRule, us |
{ |
WebInspector.PropertiesSection.call(this, ""); |
- var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited properties"), "sidebar-pane-subtitle"); |
- this.headerElement.appendChild(showInheritedCheckbox.element); |
+ var subtitle = this.headerElement.createChild("div", "sidebar-pane-subtitle vbox"); |
+ var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited properties"), "hbox"); |
+ subtitle.appendChild(showInheritedCheckbox.element); |
+ |
this._hasFreshContent = false; |
/** |
@@ -1564,6 +1735,13 @@ WebInspector.ComputedStylePropertiesSection.prototype = { |
this.populated = false; |
}, |
+ updateFilter: function() |
+ { |
+ var children = this.propertiesTreeOutline.children; |
+ for (var i = 0; i < children.length; ++i) |
+ children[i].updateFilter(); |
+ }, |
+ |
onpopulate: function() |
{ |
function sorter(a, b) |
@@ -1767,6 +1945,14 @@ WebInspector.StylePropertyTreeElementBase.prototype = { |
return null; // Overridden by ancestors. |
}, |
+ /** |
+ * @return {!WebInspector.StylesSidebarPane|!WebInspector.ComputedStyleSidebarPane} |
+ */ |
+ parentPane: function() |
+ { |
+ throw "Not implemented"; |
+ }, |
+ |
get inherited() |
{ |
return this._inherited; |
@@ -1956,6 +2142,13 @@ WebInspector.StylePropertyTreeElementBase.prototype = { |
} |
if (this.property.inactive) |
this.listItemElement.classList.add("inactive"); |
+ this.updateFilter(); |
+ }, |
+ |
+ updateFilter: function() |
+ { |
+ var regEx = this.parentPane().filterRegex(); |
+ this.listItemElement.enableStyleClass("filter-match", !!regEx && (regEx.test(this.property.name) || regEx.test(this.property.value))); |
}, |
/** |
@@ -2187,6 +2380,20 @@ WebInspector.ComputedStylePropertyTreeElement.prototype = { |
return null; |
}, |
+ /** |
+ * @return {!WebInspector.ComputedStyleSidebarPane} |
+ */ |
+ parentPane: function() |
+ { |
+ return this._stylesPane._computedStylePane; |
+ }, |
+ |
+ updateFilter: function() |
+ { |
+ var regEx = this.parentPane().filterRegex(); |
+ this.listItemElement.enableStyleClass("hidden", !!regEx && (!regEx.test(this.property.name) && !regEx.test(this.property.value))); |
+ }, |
+ |
__proto__: WebInspector.StylePropertyTreeElementBase.prototype |
} |
@@ -2226,6 +2433,14 @@ WebInspector.StylePropertyTreeElement.prototype = { |
}, |
/** |
+ * @return {!WebInspector.StylesSidebarPane} |
+ */ |
+ parentPane: function() |
+ { |
+ return this._parentPane; |
+ }, |
+ |
+ /** |
* @return {?WebInspector.StylePropertiesSection} |
*/ |
section: function() |