Bug 672744 - Add search filter to style inspector; r=msucan

This commit is contained in:
Michael Ratcliffe 2011-09-20 11:59:13 +02:00
parent 293a19d75f
commit 620028efdf
15 changed files with 182 additions and 5 deletions

View File

@ -527,6 +527,10 @@ statuspanel[label=""] {
-moz-box-align: end;
}
.styleInspector {
min-width: 350px;
}
.panel-inner-arrowcontentfooter[footertype="promobox"] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#promobox");
}

View File

@ -40,6 +40,7 @@
* ***** END LICENSE BLOCK ***** */
const Cu = Components.utils;
const FILTER_CHANGED_TIMEOUT = 300;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PluralForm.jsm");
@ -150,6 +151,12 @@ XPCOMUtils.defineLazyGetter(CssHtmlTree, "_strings", function() Services.strings
CssHtmlTree.prototype = {
htmlComplete: false,
// Used for cancelling timeouts in the style filter.
filterChangedTimeout: null,
// The search filter
searchField: null,
// Reference to the "Only user Styles" checkbox.
onlyUserStylesCheckbox: null,
@ -243,6 +250,25 @@ CssHtmlTree.prototype = {
}
},
/**
* Called when the user enters a search term.
*
* @param {Event} aEvent the DOM Event object.
*/
filterChanged: function CssHtmlTree_filterChanged(aEvent)
{
let win = this.styleWin.contentWindow;
if (this.filterChangedTimeout) {
win.clearTimeout(this.filterChangedTimeout);
this.filterChangeTimeout = null;
}
this.filterChangedTimeout = win.setTimeout(function() {
this.refreshPanel();
}.bind(this), FILTER_CHANGED_TIMEOUT);
},
/**
* The change event handler for the onlyUserStyles checkbox. When
* onlyUserStyles.checked is true we do not display properties that have no
@ -397,6 +423,12 @@ PropertyView.prototype = {
return false;
}
let searchTerm = this.tree.searchField.value.toLowerCase();
if (searchTerm && this.name.toLowerCase().indexOf(searchTerm) == -1 &&
this.value.toLowerCase().indexOf(searchTerm) == -1) {
return false;
}
return true;
},

View File

@ -68,6 +68,7 @@ var StyleInspector = {
let ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let panel = win.document.createElementNS(ns, "panel");
panel.setAttribute("class", "styleInspector");
panel.setAttribute("orient", "vertical");
panel.setAttribute("ignorekeys", "true");
panel.setAttribute("noautofocus", "true");
@ -75,11 +76,8 @@ var StyleInspector = {
panel.setAttribute("titlebar", "normal");
panel.setAttribute("close", "true");
panel.setAttribute("label", StyleInspector.l10n("panelTitle"));
// size panel to 200px wide by half browser height - 60.
let contentWindow = win.gBrowser.selectedBrowser.contentWindow;
panel.setAttribute("width", 200);
panel.setAttribute("height", contentWindow.outerHeight / 2 - 60);
panel.setAttribute("width", 350);
panel.setAttribute("height", win.screen.height / 2);
let vbox = win.document.createElement("vbox");
vbox.setAttribute("flex", "1");

View File

@ -89,6 +89,8 @@ To visually debug the templates without running firefox, alter the display:none
<input class="userStyles" save="${onlyUserStylesCheckbox}" type="checkbox"
onchange="${onlyUserStylesChanged}" checked=""/>
</label>
<input save="${searchField}" class="searchfield" type="text"
oninput="${filterChanged}"/>
</div>
</div>

View File

@ -50,6 +50,7 @@ _BROWSER_TEST_FILES = \
browser_styleinspector_webconsole.js \
browser_bug683672.js \
browser_styleinspector_bug_672746_default_styles.js \
browser_styleinspector_bug_672744_search_filter.js \
head.js \
$(NULL)

View File

@ -0,0 +1,112 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the search filter works properly.
let doc;
let stylePanel;
function createDocument()
{
doc.body.innerHTML = '<style type="text/css"> ' +
'.matches {color: #F00;}</style>' +
'<span id="matches" class="matches">Some styled text</span>' +
'</div>';
doc.title = "Style Inspector Search Filter Test";
ok(window.StyleInspector, "StyleInspector exists");
ok(StyleInspector.isEnabled, "style inspector preference is enabled");
stylePanel = StyleInspector.createPanel();
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
stylePanel.openPopup(gBrowser.selectedBrowser, "end_before", 0, 0, false, false);
}
function runStyleInspectorTests()
{
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
Services.obs.addObserver(SI_toggleDefaultStyles, "StyleInspector-populated", false);
SI_inspectNode();
}
function SI_inspectNode()
{
var span = doc.querySelector("#matches");
ok(span, "captain, we have the matches span");
let htmlTree = stylePanel.cssHtmlTree;
stylePanel.selectNode(span);
is(span, htmlTree.viewedElement,
"style inspector node matches the selected node");
is(htmlTree.viewedElement, stylePanel.cssLogic.viewedElement,
"cssLogic node matches the cssHtmlTree node");
}
function SI_toggleDefaultStyles()
{
Services.obs.removeObserver(SI_toggleDefaultStyles, "StyleInspector-populated", false);
info("clearing \"only user styles\" checkbox");
let iframe = stylePanel.querySelector("iframe");
let checkbox = iframe.contentDocument.querySelector(".userStyles");
Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false);
EventUtils.synthesizeMouse(checkbox, 5, 5, {}, iframe.contentWindow);
}
function SI_AddFilterText()
{
Services.obs.removeObserver(SI_AddFilterText, "StyleInspector-populated", false);
let iframe = stylePanel.querySelector("iframe");
let searchbar = iframe.contentDocument.querySelector(".searchfield");
Services.obs.addObserver(SI_checkFilter, "StyleInspector-populated", false);
info("setting filter text to \"color\"");
searchbar.focus();
EventUtils.synthesizeKey("c", {}, iframe.contentWindow);
EventUtils.synthesizeKey("o", {}, iframe.contentWindow);
EventUtils.synthesizeKey("l", {}, iframe.contentWindow);
EventUtils.synthesizeKey("o", {}, iframe.contentWindow);
EventUtils.synthesizeKey("r", {}, iframe.contentWindow);
}
function SI_checkFilter()
{
Services.obs.removeObserver(SI_checkFilter, "StyleInspector-populated", false);
let propertyViews = stylePanel.cssHtmlTree.propertyViews;
info("check that the correct properties are visible");
for each(let propView in propertyViews) {
let name = propView.name;
is(propView.visible, name.indexOf("color") > -1,
"span " + name + " property visibility check");
}
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
stylePanel.hidePopup();
}
function finishUp()
{
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null;
gBrowser.removeCurrentTab();
finish();
}
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
doc = content.document;
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html,default styles test";
}

View File

@ -121,6 +121,14 @@ a.link:visited {
background-position: 24px 0;
}
.searchfield {
background: url("chrome://browser/skin/devtools/search.png") no-repeat #FFF;
border-radius: 5px;
-moz-padding-start: 20px;
width: 135px;
float: right;
}
.expander[dir="rtl"] {
background-position: 16px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -85,6 +85,7 @@ browser.jar:
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/browser/devtools/search.png (devtools/search.png)
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png

View File

@ -121,6 +121,14 @@ a.link:visited {
background-position: 24px 0;
}
.searchfield {
background: url("chrome://browser/skin/devtools/search.png") no-repeat #FFF;
border-radius: 5px;
-moz-padding-start: 20px;
width: 135px;
float: right;
}
.expander[dir="rtl"] {
background-position: 16px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -124,6 +124,7 @@ browser.jar:
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/browser/devtools/search.png (devtools/search.png)
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png

View File

@ -121,6 +121,14 @@ a.link:visited {
background-position: 24px 0;
}
.searchfield {
background: url("chrome://browser/skin/devtools/search.png") no-repeat #FFF;
border-radius: 5px;
-moz-padding-start: 20px;
width: 135px;
float: right;
}
.expander[dir="rtl"] {
background-position: 16px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -107,6 +107,7 @@ browser.jar:
skin/classic/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/browser/devtools/search.png (devtools/search.png)
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
@ -229,6 +230,7 @@ browser.jar:
skin/classic/aero/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
skin/classic/aero/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/aero/browser/devtools/arrows.png (devtools/arrows.png)
skin/classic/aero/browser/devtools/search.png (devtools/search.png)
skin/classic/aero/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/sync-throbber.png