Bug 257061: adding a counter of found matches to the find in page bar. r=Unfocused.

This commit is contained in:
Mike de Boer 2014-05-01 11:30:26 +02:00
parent 8f31d14de2
commit 3b54ae345d
12 changed files with 501 additions and 47 deletions

View File

@ -524,6 +524,8 @@ pref("accessibility.typeaheadfind.enabletimeout", true);
pref("accessibility.typeaheadfind.soundURL", "beep");
pref("accessibility.typeaheadfind.enablesound", true);
pref("accessibility.typeaheadfind.prefillwithselection", true);
pref("accessibility.typeaheadfind.matchesCountTimeout", 250);
pref("accessibility.typeaheadfind.matchesCountLimit", 100);
// use Mac OS X Appearance panel text smoothing setting when rendering text, disabled by default
pref("gfx.use_text_smoothing_setting", false);

View File

@ -17,7 +17,7 @@ interface nsIDocShell;
/****************************** nsTypeAheadFind ******************************/
[scriptable, uuid(0749a445-19d3-4eb9-9d66-78eca8c6f604)]
[scriptable, uuid(f4411c5b-761b-498c-8050-dcfc8311f69e)]
interface nsITypeAheadFind : nsISupports
{
/****************************** Initializer ******************************/
@ -37,6 +37,9 @@ interface nsITypeAheadFind : nsISupports
/* Find another match in the page. */
unsigned short findAgain(in boolean findBackwards, in boolean aLinksOnly);
/* Return the range of the most recent match. */
nsIDOMRange getFoundRange();
/**************************** Helper functions ***************************/
@ -53,6 +56,8 @@ interface nsITypeAheadFind : nsISupports
* necessarily happen automatically. */
void collapseSelection();
/* Check if a range is visible */
boolean isRangeVisible(in nsIDOMRange aRange, in boolean aMustBeInViewPort);
/******************************* Attributes ******************************/

View File

@ -66,7 +66,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTypeAheadFind)
NS_IMPL_CYCLE_COLLECTION(nsTypeAheadFind, mFoundLink, mFoundEditable,
mCurrentWindow, mStartFindRange, mSearchRange,
mStartPointRange, mEndPointRange, mSoundInterface,
mFind)
mFind, mFoundRange)
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
@ -176,6 +176,7 @@ nsTypeAheadFind::SetDocShell(nsIDocShell* aDocShell)
mFoundLink = nullptr;
mFoundEditable = nullptr;
mFoundRange = nullptr;
mCurrentWindow = nullptr;
mSelectionController = nullptr;
@ -275,6 +276,7 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, bool aIsLinksOnly,
*aResult = FIND_NOTFOUND;
mFoundLink = nullptr;
mFoundEditable = nullptr;
mFoundRange = nullptr;
mCurrentWindow = nullptr;
nsCOMPtr<nsIPresShell> startingPresShell (GetPresShell());
if (!startingPresShell) {
@ -437,6 +439,8 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, bool aIsLinksOnly,
continue;
}
mFoundRange = returnRange;
// ------ Success! -------
// Hide old selection (new one may be on a different controller)
if (selection) {
@ -1091,6 +1095,44 @@ nsTypeAheadFind::GetSelection(nsIPresShell *aPresShell,
}
}
NS_IMETHODIMP
nsTypeAheadFind::GetFoundRange(nsIDOMRange** aFoundRange)
{
NS_ENSURE_ARG_POINTER(aFoundRange);
if (mFoundRange == nullptr) {
*aFoundRange = nullptr;
return NS_OK;
}
mFoundRange->CloneRange(aFoundRange);
return NS_OK;
}
NS_IMETHODIMP
nsTypeAheadFind::IsRangeVisible(nsIDOMRange *aRange,
bool aMustBeInViewPort,
bool *aResult)
{
// Jump through hoops to extract the docShell from the range.
nsCOMPtr<nsIDOMNode> node;
aRange->GetStartContainer(getter_AddRefs(node));
nsCOMPtr<nsIDOMDocument> document;
node->GetOwnerDocument(getter_AddRefs(document));
nsCOMPtr<nsIDOMWindow> window;
document->GetDefaultView(getter_AddRefs(window));
nsCOMPtr<nsIWebNavigation> navNav (do_GetInterface(window));
nsCOMPtr<nsIDocShell> docShell (do_GetInterface(navNav));
// Set up the arguments needed to check if a range is visible.
nsCOMPtr<nsIPresShell> presShell (docShell->GetPresShell());
nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
nsCOMPtr<nsIDOMRange> startPointRange = new nsRange(presShell->GetDocument());
*aResult = IsRangeVisible(presShell, presContext, aRange,
aMustBeInViewPort, false,
getter_AddRefs(startPointRange),
nullptr);
return NS_OK;
}
bool
nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,

View File

@ -80,6 +80,7 @@ protected:
bool mCaretBrowsingOn;
nsCOMPtr<nsIDOMElement> mFoundLink; // Most recent elem found, if a link
nsCOMPtr<nsIDOMElement> mFoundEditable; // Most recent elem found, if editable
nsCOMPtr<nsIDOMRange> mFoundRange; // Most recent range found
nsCOMPtr<nsIDOMWindow> mCurrentWindow;
// mLastFindLength is the character length of the last find string. It is used for
// disabling the "not found" sound when using backspace or delete

View File

@ -101,8 +101,17 @@
testDrop();
testQuickFindLink();
if (gHasFindClipboard)
testStatusText();
testQuickFindClose();
testStatusText(afterStatusText);
else
afterStatusText();
function afterStatusText() {
testFindCountUI(function() {
gFindBar.close();
ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI");
testQuickFindClose();
});
}
}
function testFindbarSelection() {
@ -163,9 +172,10 @@
setTimeout(_isClosedCallback, gFindBar._quickFindTimeoutLength + 100);
}
function testStatusText() {
function testStatusText(aCallback) {
var _delayedCheckStatusText = function() {
ok(gStatusText == SAMPLE_URL, "testStatusText: Failed to set status text of found link");
aCallback();
};
setTimeout(_delayedCheckStatusText, 100);
}
@ -384,6 +394,100 @@
testClipboardSearchString(SEARCH_TEXT);
}
// Perform an async function in serial on each of the list items.
function asyncForEach(list, async, callback) {
let i = 0;
let len = list.length;
if (!len)
return callback();
async(list[i], function handler() {
i++;
if (i < len) {
async(list[i], handler, i);
} else {
callback();
}
}, i);
}
function testFindCountUI(callback) {
clearFocus();
document.getElementById("cmd_find").doCommand();
ok(!gFindBar.hidden, "testFindCountUI: failed to open findbar");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"testFindCountUI: find field is not focused");
let matchCase = gFindBar.getElement("find-case-sensitive");
if (matchCase.checked)
matchCase.click();
let foundMatches = gFindBar._foundMatches;
let tests = [{
text: "t",
current: 5,
total: 10,
}, {
text: "te",
current: 3,
total: 5,
}, {
text: "tes",
current: 1,
total: 2,
}, {
text: "texxx",
current: 0,
total: 0
}];
let regex = /([\d]*)\sof\s([\d]*)/;
let timeout = gFindBar._matchesCountTimeoutLength + 20;
function assertMatches(aTest, aMatches) {
window.opener.wrappedJSObject.SimpleTest.is(aTest.current, aMatches[1],
"Currently highlighted match should be at " + aTest.current);
window.opener.wrappedJSObject.SimpleTest.is(aTest.total, aMatches[2],
"Total amount of matches should be " + aTest.total);
}
function testString(aTest, aNext) {
gFindBar.clear();
enterStringIntoFindField(aTest.text);
setTimeout(function() {
let matches = foundMatches.value.match(regex);
if (!aTest.total) {
ok(!matches, "No message should be shown when 0 matches are expected");
aNext();
} else {
assertMatches(aTest, matches);
let cycleTests = [];
let cycles = aTest.total;
while (--cycles) {
aTest.current++;
if (aTest.current > aTest.total)
aTest.current = 1;
cycleTests.push({
current: aTest.current,
total: aTest.total
});
}
asyncForEach(cycleTests, function(aCycleTest, aNextCycle) {
gFindBar.onFindAgainCommand();
setTimeout(function() {
assertMatches(aCycleTest, foundMatches.value.match(regex));
aNextCycle();
}, timeout);
}, aNext);
}
}, timeout);
}
asyncForEach(tests, testString, callback);
}
function testClipboardSearchString(aExpected) {
if (!gHasFindClipboard)
return;

View File

@ -4,16 +4,19 @@
href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=257061
https://bugzilla.mozilla.org/show_bug.cgi?id=288254
-->
<window title="Mozilla Bug 288254"
<window title="Mozilla Bug 257061 and Bug 288254"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=257061">Mozilla Bug 257061</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=288254">Mozilla Bug 288254</a>
<p id="display"></p>
<div id="content" style="display: none">
@ -26,7 +29,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=288254
<script class="testbody" type="application/javascript">
<![CDATA[
/** Test for Bug 288254 **/
/** Test for Bug 257061 and Bug 288254 **/
SimpleTest.waitForExplicitFinish();
window.open("findbar_window.xul", "findbartest",
"chrome,width=600,height=600");

View File

@ -191,6 +191,7 @@
type="checkbox"
xbl:inherits="accesskey=matchcaseaccesskey"/>
<xul:label anonid="match-case-status" class="findbar-find-fast"/>
<xul:label anonid="found-matches" class="findbar-find-fast found-matches" hidden="true"/>
<xul:image anonid="find-status-icon" class="findbar-find-fast find-status-icon"/>
<xul:description anonid="find-status"
control="findbar-textbox"
@ -318,6 +319,7 @@
<constructor><![CDATA[
// These elements are accessed frequently and are therefore cached
this._findField = this.getElement("findbar-textbox");
this._foundMatches = this.getElement("found-matches");
this._findStatusIcon = this.getElement("find-status-icon");
this._findStatusDesc = this.getElement("find-status");
@ -331,6 +333,10 @@
prefsvc.getIntPref("accessibility.typeaheadfind.timeout");
this._flashFindBar =
prefsvc.getIntPref("accessibility.typeaheadfind.flashBar");
this._matchesCountTimeoutLength =
prefsvc.getIntPref("accessibility.typeaheadfind.matchesCountTimeout");
this._matchesCountLimit =
prefsvc.getIntPref("accessibility.typeaheadfind.matchesCountLimit");
prefsvc.addObserver("accessibility.typeaheadfind",
this._observer, false);
@ -430,6 +436,54 @@
]]></body>
</method>
<field name="_pluralForm">null</field>
<property name="pluralForm">
<getter><![CDATA[
if (!this._pluralForm) {
this._pluralForm = Components.utils.import(
"resource://gre/modules/PluralForm.jsm", {}).PluralForm;
}
return this._pluralForm;
]]></getter>
</property>
<method name="_updateMatchesCountWorker">
<parameter name="aRes"/>
<body><![CDATA[
let word = this._findField.value;
if (aRes == this.nsITypeAheadFind.FIND_NOTFOUND || !word) {
this._foundMatches.hidden = true;
this._foundMatches.value = "";
} else {
let matchesCount = this.browser.finder.requestMatchesCount(
word, this._matchesCountLimit, this._findMode == this.FIND_LINKS);
window.clearTimeout(this._updateMatchesCountTimeout);
this._updateMatchesCountTimeout = null;
}
]]></body>
</method>
<!--
- Updates the search match count after each find operation on a new string.
- @param aRes
- the result of the find operation
-->
<method name="_updateMatchesCount">
<parameter name="aRes"/>
<body><![CDATA[
if (this._matchesCountLimit == 0 || !this._dispatchFindEvent("matchescount"))
return;
if (this._updateMatchesCountTimeout) {
window.clearTimeout(this._updateMatchesCountTimeout);
this._updateMatchesCountTimeout = null;
}
this._updateMatchesCountTimeout =
window.setTimeout(() => this._updateMatchesCountWorker(aRes),
this._matchesCountTimeoutLength);
]]></body>
</method>
<!--
- Turns highlight on or off.
- @param aHighlight (boolean)
@ -448,6 +502,9 @@
this.browser._lastSearchHighlight = aHighlight;
this.browser.finder.highlight(aHighlight, word);
// Update the matches count
this._updateMatchesCount(this.nsITypeAheadFind.FIND_FOUND);
]]></body>
</method>
@ -503,6 +560,19 @@
]]></body>
</method>
<field name="_strBundle">null</field>
<property name="strBundle">
<getter><![CDATA[
if (!this._strBundle) {
this._strBundle =
Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService)
.createBundle("chrome://global/locale/findbar.properties");
}
return this._strBundle;
]]></getter>
</property>
<!--
- Opens and displays the find bar.
-
@ -519,10 +589,7 @@
this._findMode = aMode;
if (!this._notFoundStr) {
let stringsBundle =
Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService)
.createBundle("chrome://global/locale/findbar.properties");
var stringsBundle = this.strBundle;
this._notFoundStr = stringsBundle.GetStringFromName("NotFound");
this._wrappedToTopStr =
stringsBundle.GetStringFromName("WrappedToTop");
@ -953,6 +1020,7 @@
this._findField.removeAttribute("status");
break;
}
this._updateMatchesCount(res);
]]></body>
</method>
@ -1169,6 +1237,36 @@
]]></body>
</method>
<!--
- This handles all the result changes for matches counts.
- @param aResult
- Result Object, containing the total amount of matches and a vector
- of the current result.
-->
<method name="onMatchesCountResult">
<parameter name="aResult"/>
<body><![CDATA[
if (aResult.total !== 0) {
if (aResult.total == -1) {
this._foundMatches.value = this.pluralForm.get(
this._matchesCountLimit,
this.strBundle.GetStringFromName("FoundTooManyMatches")
).replace("#1", this._matchesCountLimit);
} else {
this._foundMatches.value = this.pluralForm.get(
aResult.total,
this.strBundle.GetStringFromName("FoundMatches")
).replace("#1", aResult.current)
.replace("#2", aResult.total);
}
this._foundMatches.hidden = false;
} else {
this._foundMatches.hidden = true;
this._foundMatches.value = "";
}
]]></body>
</method>
<!--
- This handler may cancel a request to focus content by returning |false|
- explicitly.

View File

@ -10,6 +10,12 @@ NormalFind=Find in page
FastFind=Quick find
FastFindLinks=Quick find (links only)
CaseSensitive=(Case sensitive)
FoundMatchCount=%S match
FoundMatchesCount=%S matches
FoundTooManyMatches=More than %S matches
# LOCALIZATION NOTE (FoundMatches): Semicolon-separated list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is currently selected match and #2 the total amount of matches.
FoundMatches=#1 of #2 match;#1 of #2 matches
# LOCALIZATION NOTE (FoundTooManyMatches): Semicolon-separated list of plural
# forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the total amount of matches allowed before counting stops.
FoundTooManyMatches=More than #1 match;More than #1 matches

View File

@ -74,7 +74,9 @@ Finder.prototype = {
};
for (let l of this._listeners) {
l.onFindResult(data);
try {
l.onFindResult(data);
} catch (ex) {}
}
},
@ -194,8 +196,10 @@ Finder.prototype = {
focusContent: function() {
// Allow Finder listeners to cancel focusing the content.
for (let l of this._listeners) {
if (!l.shouldFocusContent())
return;
try {
if (!l.shouldFocusContent())
return;
} catch (ex) {}
}
let fastFind = this._fastFind;
@ -255,6 +259,180 @@ Finder.prototype = {
}
},
requestMatchesCount: function(aWord, aMatchLimit, aLinksOnly) {
let window = this._getWindow();
let result = this._countMatchesInWindow(aWord, aMatchLimit, aLinksOnly, window);
// Count matches in (i)frames AFTER searching through the main window.
for (let frame of result._framesToCount) {
// We've reached our limit; no need to do more work.
if (result.total == -1 || result.total == aMatchLimit)
break;
this._countMatchesInWindow(aWord, aMatchLimit, aLinksOnly, frame, result);
}
// The `_currentFound` and `_framesToCount` properties are only used for
// internal bookkeeping between recursive calls.
delete result._currentFound;
delete result._framesToCount;
for (let l of this._listeners) {
try {
l.onMatchesCountResult(result);
} catch (ex) {}
}
},
/**
* Counts the number of matches for the searched word in the passed window's
* content.
* @param aWord
* the word to search for.
* @param aMatchLimit
* the maximum number of matches shown (for speed reasons).
* @param aLinksOnly
* whether we should only search through links.
* @param aWindow
* the window to search in. Passing undefined will search the
* current content window. Optional.
* @param aStats
* the Object that is returned by this function. It may be passed as an
* argument here in the case of a recursive call.
* @returns an object stating the number of matches and a vector for the current match.
*/
_countMatchesInWindow: function(aWord, aMatchLimit, aLinksOnly, aWindow = null, aStats = null) {
aWindow = aWindow || this._getWindow();
aStats = aStats || {
total: 0,
current: 0,
_framesToCount: new Set(),
_currentFound: false
};
// If we already reached our max, there's no need to do more work!
if (aStats.total == -1 || aStats.total == aMatchLimit) {
aStats.total = -1;
return aStats;
}
this._collectFrames(aWindow, aStats);
let foundRange = this._fastFind.getFoundRange();
this._findIterator(aWord, aWindow, aRange => {
if (!aLinksOnly || this._rangeStartsInLink(aRange)) {
++aStats.total;
if (!aStats._currentFound) {
++aStats.current;
aStats._currentFound = (foundRange &&
aRange.startContainer == foundRange.startContainer &&
aRange.startOffset == foundRange.startOffset &&
aRange.endContainer == foundRange.endContainer &&
aRange.endOffset == foundRange.endOffset);
}
}
if (aStats.total == aMatchLimit) {
aStats.total = -1;
return false;
}
});
return aStats;
},
/**
* Basic wrapper around nsIFind that provides invoking a callback `aOnFind`
* each time an occurence of `aWord` string is found.
*
* @param aWord
* the word to search for.
* @param aWindow
* the window to search in.
* @param aOnFind
* the Function to invoke when a word is found. if Boolean `false` is
* returned, the find operation will be stopped and the Function will
* not be invoked again.
*/
_findIterator: function(aWord, aWindow, aOnFind) {
let doc = aWindow.document;
let body = (doc instanceof Ci.nsIDOMHTMLDocument && doc.body) ?
doc.body : doc.documentElement;
let searchRange = doc.createRange();
searchRange.selectNodeContents(body);
let startPt = searchRange.cloneRange();
startPt.collapse(true);
let endPt = searchRange.cloneRange();
endPt.collapse(false);
let retRange = null;
let finder = Cc["@mozilla.org/embedcomp/rangefind;1"]
.createInstance()
.QueryInterface(Ci.nsIFind);
finder.caseSensitive = this._fastFind.caseSensitive;
while ((retRange = finder.Find(aWord, searchRange, startPt, endPt))) {
if (aOnFind(retRange) === false)
break;
startPt = retRange.cloneRange();
startPt.collapse(false);
}
},
/**
* Helper method for `_countMatchesInWindow` that recursively collects all
* visible (i)frames inside a window.
*
* @param aWindow
* the window to extract the (i)frames from.
* @param aStats
* Object that contains a Set called '_framesToCount'
*/
_collectFrames: function(aWindow, aStats) {
if (!aWindow.frames || !aWindow.frames.length)
return;
// Casting `aWindow.frames` to an Iterator doesn't work, so we're stuck with
// a plain, old for-loop.
for (let i = 0, l = aWindow.frames.length; i < l; ++i) {
let frame = aWindow.frames[i];
// Don't count matches in hidden frames.
let frameEl = frame && frame.frameElement;
if (!frameEl)
continue;
// Construct a range around the frame element to check its visiblity.
let range = aWindow.document.createRange();
range.setStart(frameEl, 0);
range.setEnd(frameEl, 0);
if (!this._fastFind.isRangeVisible(range, this._getDocShell(range), true))
continue;
// All good, so add it to the set to count later.
if (!aStats._framesToCount.has(frame))
aStats._framesToCount.add(frame);
this._collectFrames(frame, aStats);
}
},
/**
* Helper method to extract the docShell reference from a Window or Range object.
*
* @param aWindowOrRange
* Window object to query. May also be a Range, from which the owner
* window will be queried.
* @returns nsIDocShell
*/
_getDocShell: function(aWindowOrRange) {
let window = aWindowOrRange;
// Ranges may also be passed in, so fetch its window.
if (aWindowOrRange instanceof Ci.nsIDOMRange)
window = aWindowOrRange.startContainer.ownerDocument.defaultView;
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
},
_getWindow: function () {
return this._docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
},
@ -354,34 +532,11 @@ Finder.prototype = {
return found;
}
let body = (doc instanceof Ci.nsIDOMHTMLDocument && doc.body) ?
doc.body : doc.documentElement;
if (aHighlight) {
let searchRange = doc.createRange();
searchRange.selectNodeContents(body);
let startPt = searchRange.cloneRange();
startPt.collapse(true);
let endPt = searchRange.cloneRange();
endPt.collapse(false);
let retRange = null;
let finder = Cc["@mozilla.org/embedcomp/rangefind;1"]
.createInstance()
.QueryInterface(Ci.nsIFind);
finder.caseSensitive = this._fastFind.caseSensitive;
while ((retRange = finder.Find(aWord, searchRange,
startPt, endPt))) {
this._highlightRange(retRange, controller);
startPt = retRange.cloneRange();
startPt.collapse(false);
this._findIterator(aWord, win, aRange => {
this._highlightRange(aRange, controller);
found = true;
}
});
} else {
// First, attempt to remove highlighting from main document
let sel = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);
@ -578,6 +733,41 @@ Finder.prototype = {
return null;
},
/**
* Determines whether a range is inside a link.
* @param aRange
* the range to check
* @returns true if the range starts in a link
*/
_rangeStartsInLink: function(aRange) {
let isInsideLink = false;
let node = aRange.startContainer;
if (node.nodeType == node.ELEMENT_NODE) {
if (node.hasChildNodes) {
let childNode = node.item(aRange.startOffset);
if (childNode)
node = childNode;
}
}
const XLink_NS = "http://www.w3.org/1999/xlink";
do {
if (node instanceof HTMLAnchorElement) {
isInsideLink = node.hasAttribute("href");
break;
} else if (typeof node.hasAttributeNS == "function" &&
node.hasAttributeNS(XLink_NS, "href")) {
isInsideLink = (node.getAttributeNS(XLink_NS, "type") == "simple");
break;
}
node = node.parentNode;
} while (node);
return isInsideLink;
},
// Start of nsIWebProgressListener implementation.
onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {

View File

@ -150,7 +150,8 @@ findbar[hidden] {
-moz-margin-start: 5px;
}
.findbar-find-status {
.findbar-find-status,
.findbar-matches {
color: GrayText;
margin: 0 !important;
-moz-margin-start: 12px !important;

View File

@ -210,7 +210,8 @@ label.findbar-find-fast:-moz-lwtheme,
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
.findbar-find-status {
.findbar-find-status,
.found-matches {
color: rgba(0,0,0,.5);
margin: 0 !important;
-moz-margin-start: 12px !important;

View File

@ -143,7 +143,8 @@ findbar[hidden] {
display: none;
}
.findbar-find-status {
.findbar-find-status,
.found-matches {
color: GrayText;
margin: 0 !important;
-moz-margin-start: 12px !important;