зеркало из https://github.com/mozilla/gecko-dev.git
Bug 269442 - whole word matching support for nsFind. r=ehsan,dao. ui-r=shorlander
MozReview-Commit-ID: KIDWHyjOSYL
This commit is contained in:
Родитель
9e552a2542
Коммит
fe68c53f4b
|
@ -557,18 +557,21 @@ nsFind::SetCaseSensitive(bool aCaseSensitive)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute boolean entireWord; */
|
||||
NS_IMETHODIMP
|
||||
nsFind::GetWordBreaker(nsIWordBreaker** aWordBreaker)
|
||||
nsFind::GetEntireWord(bool *aEntireWord)
|
||||
{
|
||||
*aWordBreaker = mWordBreaker;
|
||||
NS_IF_ADDREF(*aWordBreaker);
|
||||
if (!aEntireWord)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aEntireWord = !!mWordBreaker;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFind::SetWordBreaker(nsIWordBreaker* aWordBreaker)
|
||||
nsFind::SetEntireWord(bool aEntireWord)
|
||||
{
|
||||
mWordBreaker = aWordBreaker;
|
||||
mWordBreaker = aEntireWord ? nsContentUtils::WordBreaker() : nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -730,6 +733,82 @@ nsFind::NextNode(nsIDOMRange* aSearchRange,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS PeekNextCharRestoreState final
|
||||
{
|
||||
public:
|
||||
explicit PeekNextCharRestoreState(nsFind* aFind)
|
||||
: mIterOffset(aFind->mIterOffset),
|
||||
mIterNode(aFind->mIterNode),
|
||||
mCurrNode(aFind->mIterator->GetCurrentNode()),
|
||||
mFind(aFind)
|
||||
{
|
||||
}
|
||||
|
||||
~PeekNextCharRestoreState()
|
||||
{
|
||||
mFind->mIterOffset = mIterOffset;
|
||||
mFind->mIterNode = mIterNode;
|
||||
mFind->mIterator->PositionAt(mCurrNode);
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t mIterOffset;
|
||||
nsCOMPtr<nsIDOMNode> mIterNode;
|
||||
nsCOMPtr<nsINode> mCurrNode;
|
||||
RefPtr<nsFind> mFind;
|
||||
};
|
||||
|
||||
char16_t
|
||||
nsFind::PeekNextChar(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPoint,
|
||||
nsIDOMRange* aEndPoint)
|
||||
{
|
||||
// We need to restore the necessary member variables before this function
|
||||
// returns.
|
||||
PeekNextCharRestoreState restoreState(this);
|
||||
|
||||
nsCOMPtr<nsIContent> tc;
|
||||
nsresult rv;
|
||||
const nsTextFragment *frag;
|
||||
int32_t fragLen;
|
||||
|
||||
// Loop through non-block nodes until we find one that's not empty.
|
||||
do {
|
||||
tc = nullptr;
|
||||
NextNode(aSearchRange, aStartPoint, aEndPoint, false);
|
||||
|
||||
// Get the text content:
|
||||
tc = do_QueryInterface(mIterNode);
|
||||
|
||||
// Get the block parent.
|
||||
nsCOMPtr<nsIDOMNode> blockParent;
|
||||
rv = GetBlockParent(mIterNode, getter_AddRefs(blockParent));
|
||||
if (NS_FAILED(rv))
|
||||
return L'\0';
|
||||
|
||||
// If out of nodes or in new parent.
|
||||
if (!mIterNode || !tc || (blockParent != mLastBlockParent))
|
||||
return L'\0';
|
||||
|
||||
frag = tc->GetText();
|
||||
fragLen = frag->GetLength();
|
||||
} while (fragLen <= 0);
|
||||
|
||||
const char16_t *t2b = nullptr;
|
||||
const char *t1b = nullptr;
|
||||
|
||||
if (frag->Is2b()) {
|
||||
t2b = frag->Get2b();
|
||||
} else {
|
||||
t1b = frag->Get1b();
|
||||
}
|
||||
|
||||
// Index of char to return.
|
||||
int32_t index = mFindBackward ? fragLen - 1 : 0;
|
||||
|
||||
return t1b ? CHAR_TO_UNICHAR(t1b[index]) : t2b[index];
|
||||
}
|
||||
|
||||
bool
|
||||
nsFind::IsBlockNode(nsIContent* aContent)
|
||||
{
|
||||
|
@ -901,6 +980,8 @@ nsFind::Find(const char16_t* aPatText, nsIDOMRange* aSearchRange,
|
|||
// Keep track of when we're in whitespace:
|
||||
// (only matters when we're matching)
|
||||
bool inWhitespace = false;
|
||||
// Keep track of whether the previous char was a word-breaking one.
|
||||
bool wordBreakPrev = false;
|
||||
|
||||
// Place to save the range start point in case we find a match:
|
||||
nsCOMPtr<nsIDOMNode> matchAnchorNode;
|
||||
|
@ -912,7 +993,10 @@ nsFind::Find(const char16_t* aPatText, nsIDOMRange* aSearchRange,
|
|||
aEndPoint->GetEndContainer(getter_AddRefs(endNode));
|
||||
aEndPoint->GetEndOffset(&endOffset);
|
||||
|
||||
char16_t c = 0;
|
||||
char16_t patc = 0;
|
||||
char16_t prevChar = 0;
|
||||
char16_t prevCharInMatch = 0;
|
||||
while (1) {
|
||||
#ifdef DEBUG_FIND
|
||||
printf("Loop ...\n");
|
||||
|
@ -1046,9 +1130,11 @@ nsFind::Find(const char16_t* aPatText, nsIDOMRange* aSearchRange,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Save the previous character for word boundary detection
|
||||
prevChar = c;
|
||||
// The two characters we'll be comparing:
|
||||
char16_t c = (t2b ? t2b[findex] : CHAR_TO_UNICHAR(t1b[findex]));
|
||||
char16_t patc = patStr[pindex];
|
||||
c = (t2b ? t2b[findex] : CHAR_TO_UNICHAR(t1b[findex]));
|
||||
patc = patStr[pindex];
|
||||
|
||||
#ifdef DEBUG_FIND
|
||||
printf("Comparing '%c'=%x to '%c' (%d of %d), findex=%d%s\n",
|
||||
|
@ -1111,7 +1197,7 @@ nsFind::Find(const char16_t* aPatText, nsIDOMRange* aSearchRange,
|
|||
|
||||
// a '\n' between CJ characters is ignored
|
||||
if (pindex != (mFindBackward ? patLen : 0) && c != patc && !inWhitespace) {
|
||||
if (c == '\n' && t2b && IS_CJ_CHAR(prevChar)) {
|
||||
if (c == '\n' && t2b && IS_CJ_CHAR(prevCharInMatch)) {
|
||||
int32_t nindex = findex + incr;
|
||||
if (mFindBackward ? (nindex >= 0) : (nindex < fragLen)) {
|
||||
if (IS_CJ_CHAR(t2b[nindex])) {
|
||||
|
@ -1121,9 +1207,22 @@ nsFind::Find(const char16_t* aPatText, nsIDOMRange* aSearchRange,
|
|||
}
|
||||
}
|
||||
|
||||
// Compare
|
||||
if (c == patc || (inWhitespace && IsSpace(c))) {
|
||||
prevChar = c;
|
||||
wordBreakPrev = false;
|
||||
if (mWordBreaker) {
|
||||
if (prevChar == NBSP_CHARCODE)
|
||||
prevChar = CHAR_TO_UNICHAR(' ');
|
||||
wordBreakPrev = mWordBreaker->BreakInBetween(&prevChar, 1, &c, 1);
|
||||
}
|
||||
|
||||
// Compare. Match if we're in whitespace and c is whitespace, or if the
|
||||
// characters match and at least one of the following is true:
|
||||
// a) we're not matching the entire word
|
||||
// b) a match has already been stored
|
||||
// c) the previous character is a different "class" than the current character.
|
||||
if ((c == patc && (!mWordBreaker || matchAnchorNode || wordBreakPrev)) ||
|
||||
(inWhitespace && IsSpace(c)))
|
||||
{
|
||||
prevCharInMatch = c;
|
||||
#ifdef DEBUG_FIND
|
||||
if (inWhitespace) {
|
||||
printf("YES (whitespace)(%d of %d)\n", pindex, patLen);
|
||||
|
@ -1148,6 +1247,29 @@ nsFind::Find(const char16_t* aPatText, nsIDOMRange* aSearchRange,
|
|||
// Make the range:
|
||||
nsCOMPtr<nsIDOMNode> startParent;
|
||||
nsCOMPtr<nsIDOMNode> endParent;
|
||||
|
||||
// Check for word break (if necessary)
|
||||
if (mWordBreaker) {
|
||||
int32_t nextfindex = findex + incr;
|
||||
|
||||
char16_t nextChar;
|
||||
// If still in array boundaries, get nextChar.
|
||||
if (mFindBackward ? (nextfindex >= 0) : (nextfindex < fragLen))
|
||||
nextChar = (t2b ? t2b[nextfindex] : CHAR_TO_UNICHAR(t1b[nextfindex]));
|
||||
// Get next character from the next node.
|
||||
else
|
||||
nextChar = PeekNextChar(aSearchRange, aStartPoint, aEndPoint);
|
||||
|
||||
if (nextChar == NBSP_CHARCODE)
|
||||
nextChar = CHAR_TO_UNICHAR(' ');
|
||||
|
||||
// If a word break isn't there when it needs to be, reset search.
|
||||
if (!mWordBreaker->BreakInBetween(&c, 1, &nextChar, 1)) {
|
||||
matchAnchorNode = nullptr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range = CreateRange(tc);
|
||||
if (range) {
|
||||
int32_t matchStartOffset, matchEndOffset;
|
||||
|
|
|
@ -44,6 +44,8 @@ protected:
|
|||
bool mFindBackward;
|
||||
bool mCaseSensitive;
|
||||
|
||||
// Use "find entire words" mode by setting to a word breaker or null, to
|
||||
// disable "entire words" mode.
|
||||
nsCOMPtr<nsIWordBreaker> mWordBreaker;
|
||||
|
||||
int32_t mIterOffset;
|
||||
|
@ -64,6 +66,11 @@ protected:
|
|||
nsIDOMRange* aStartPoint, nsIDOMRange* aEndPoint,
|
||||
bool aContinueOk);
|
||||
|
||||
// Get the first character from the next node (last if mFindBackward).
|
||||
char16_t PeekNextChar(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPoint,
|
||||
nsIDOMRange* aEndPoint);
|
||||
|
||||
// Reset variables before returning -- don't hold any references.
|
||||
void ResetAll();
|
||||
|
||||
|
@ -71,6 +78,8 @@ protected:
|
|||
nsresult InitIterator(nsIDOMNode* aStartNode, int32_t aStartOffset,
|
||||
nsIDOMNode* aEndNode, int32_t aEndOffset);
|
||||
RefPtr<nsFindContentIterator> mIterator;
|
||||
|
||||
friend class PeekNextCharRestoreState;
|
||||
};
|
||||
|
||||
#endif // nsFind_h__
|
||||
|
|
|
@ -8,17 +8,12 @@
|
|||
interface nsIDOMRange;
|
||||
interface nsIWordBreaker;
|
||||
|
||||
[scriptable, uuid(75125d55-37ee-4575-b9b5-f33bfa68c2a1)]
|
||||
[scriptable, uuid(40aba110-2a56-4678-be90-e2c17a9ae7d7)]
|
||||
interface nsIFind : nsISupports
|
||||
{
|
||||
attribute boolean findBackwards;
|
||||
attribute boolean caseSensitive;
|
||||
|
||||
/**
|
||||
* Use "find entire words" mode by setting to a word breaker
|
||||
* or null, to disable "entire words" mode.
|
||||
*/
|
||||
[noscript] attribute nsIWordBreaker wordBreaker;
|
||||
attribute boolean entireWord;
|
||||
|
||||
/**
|
||||
* Find some text in the current context. The implementation is
|
||||
|
|
|
@ -719,8 +719,7 @@ nsWebBrowserFind::SearchInFrame(nsPIDOMWindowOuter* aWindow, bool aWrapping,
|
|||
(void)find->SetCaseSensitive(mMatchCase);
|
||||
(void)find->SetFindBackwards(mFindBackwards);
|
||||
|
||||
// XXX Make and set a line breaker here, once that's implemented.
|
||||
(void)find->SetWordBreaker(nullptr);
|
||||
(void)find->SetEntireWord(mEntireWord);
|
||||
|
||||
// Now make sure the content (for actual finding) and frame (for
|
||||
// selection) models are up to date.
|
||||
|
|
|
@ -864,6 +864,7 @@ pref("accessibility.typeaheadfind.matchesCountTimeout", 100);
|
|||
pref("accessibility.typeaheadfind.matchesCountLimit", 1000);
|
||||
pref("findbar.highlightAll", false);
|
||||
pref("findbar.modalHighlight", false);
|
||||
pref("findbar.entireword", false);
|
||||
|
||||
// use Mac OS X Appearance panel text smoothing setting when rendering text, disabled by default
|
||||
pref("gfx.use_text_smoothing_setting", false);
|
||||
|
|
|
@ -18,7 +18,7 @@ interface nsIDocShell;
|
|||
|
||||
/****************************** nsTypeAheadFind ******************************/
|
||||
|
||||
[scriptable, uuid(c8ca2c38-7030-4453-ae63-a16eeb10e096)]
|
||||
[scriptable, uuid(ae501e28-c57f-4692-ac74-410e1bed98b7)]
|
||||
interface nsITypeAheadFind : nsISupports
|
||||
{
|
||||
/****************************** Initializer ******************************/
|
||||
|
@ -65,6 +65,7 @@ interface nsITypeAheadFind : nsISupports
|
|||
readonly attribute AString searchString;
|
||||
// Most recent search string
|
||||
attribute boolean caseSensitive; // Searches are case sensitive
|
||||
attribute boolean entireWord; // Search for whole words only
|
||||
readonly attribute nsIDOMElement foundLink;
|
||||
// Most recent elem found, if a link
|
||||
readonly attribute nsIDOMElement foundEditable;
|
||||
|
|
|
@ -80,7 +80,8 @@ nsTypeAheadFind::nsTypeAheadFind():
|
|||
mDidAddObservers(false),
|
||||
mLastFindLength(0),
|
||||
mIsSoundInitialized(false),
|
||||
mCaseSensitive(false)
|
||||
mCaseSensitive(false),
|
||||
mEntireWord(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -167,6 +168,26 @@ nsTypeAheadFind::GetCaseSensitive(bool* isCaseSensitive)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTypeAheadFind::SetEntireWord(bool isEntireWord)
|
||||
{
|
||||
mEntireWord = isEntireWord;
|
||||
|
||||
if (mFind) {
|
||||
mFind->SetEntireWord(mEntireWord);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTypeAheadFind::GetEntireWord(bool* isEntireWord)
|
||||
{
|
||||
*isEntireWord = mEntireWord;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTypeAheadFind::SetDocShell(nsIDocShell* aDocShell)
|
||||
{
|
||||
|
|
|
@ -106,6 +106,7 @@ protected:
|
|||
nsCOMPtr<nsIFind> mFind;
|
||||
|
||||
bool mCaseSensitive;
|
||||
bool mEntireWord;
|
||||
|
||||
bool EnsureFind() {
|
||||
if (mFind) {
|
||||
|
@ -118,7 +119,7 @@ protected:
|
|||
}
|
||||
|
||||
mFind->SetCaseSensitive(mCaseSensitive);
|
||||
mFind->SetWordBreaker(nullptr);
|
||||
mFind->SetEntireWord(mEntireWord);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,16 @@
|
|||
oncommand="_setCaseSensitivity(this.checked ? 1 : 0);"
|
||||
type="checkbox"
|
||||
xbl:inherits="accesskey=matchcaseaccesskey"/>
|
||||
<xul:toolbarbutton anonid="find-entire-word"
|
||||
class="findbar-entire-word findbar-button tabbable"
|
||||
label="&entireWord.label;"
|
||||
accesskey="&entireWord.accesskey;"
|
||||
tooltiptext="&entireWord.tooltiptext;"
|
||||
oncommand="_setEntireWord(this.checked);"
|
||||
type="checkbox"
|
||||
xbl:inherits="accesskey=entirewordaccesskey"/>
|
||||
<xul:label anonid="match-case-status" class="findbar-find-fast"/>
|
||||
<xul:label anonid="entire-word-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"
|
||||
|
@ -334,6 +343,10 @@
|
|||
case "accessibility.typeaheadfind.casesensitive":
|
||||
this._self._setCaseSensitivity(prefsvc.getIntPref(aPrefName));
|
||||
break;
|
||||
case "findbar.entireword":
|
||||
this._self._entireWord = prefsvc.getBoolPref(aPrefName);
|
||||
this._self._updateEntireWord();
|
||||
break;
|
||||
case "findbar.highlightAll":
|
||||
this._self.toggleHighlight(prefsvc.getBoolPref(aPrefName), true);
|
||||
break;
|
||||
|
@ -375,6 +388,7 @@
|
|||
this._observer, false);
|
||||
prefsvc.addObserver("accessibility.typeaheadfind.casesensitive",
|
||||
this._observer, false);
|
||||
prefsvc.addObserver("findbar.entireword", this._observer, false);
|
||||
prefsvc.addObserver("findbar.highlightAll", this._observer, false);
|
||||
prefsvc.addObserver("findbar.modalHighlight", this._observer, false);
|
||||
|
||||
|
@ -384,6 +398,7 @@
|
|||
prefsvc.getBoolPref("accessibility.typeaheadfind.linksonly");
|
||||
this._typeAheadCaseSensitive =
|
||||
prefsvc.getIntPref("accessibility.typeaheadfind.casesensitive");
|
||||
this._entireWord = prefsvc.getBoolPref("findbar.entireword");
|
||||
this._highlightAll = prefsvc.getBoolPref("findbar.highlightAll");
|
||||
|
||||
// Convenience
|
||||
|
@ -424,6 +439,7 @@
|
|||
this._observer);
|
||||
prefsvc.removeObserver("accessibility.typeaheadfind.casesensitive",
|
||||
this._observer);
|
||||
prefsvc.removeObserver("findbar.entireword", this._observer);
|
||||
prefsvc.removeObserver("findbar.highlightAll", this._observer);
|
||||
prefsvc.removeObserver("findbar.modalHighlight", this._observer);
|
||||
|
||||
|
@ -622,6 +638,51 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
- Updates the entire-word mode of the findbar and its UI.
|
||||
-->
|
||||
<method name="_updateEntireWord">
|
||||
<body><![CDATA[
|
||||
let entireWord = this._entireWord;
|
||||
let checkbox = this.getElement("find-entire-word");
|
||||
let statusLabel = this.getElement("entire-word-status");
|
||||
checkbox.checked = entireWord;
|
||||
|
||||
statusLabel.value = entireWord ? this._entireWordStr : "";
|
||||
|
||||
// Show the checkbox on the full Find bar in non-auto mode.
|
||||
// Show the label in all other cases.
|
||||
let hideCheckbox = this._findMode != this.FIND_NORMAL;
|
||||
checkbox.hidden = hideCheckbox;
|
||||
statusLabel.hidden = !hideCheckbox;
|
||||
|
||||
this.browser.finder.entireWord = entireWord;
|
||||
|
||||
// Update the matches count
|
||||
this._updateMatchesCount(this.nsITypeAheadFind.FIND_FOUND);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
- Sets the findbar entire-word mode
|
||||
- @param aEntireWord (boolean)
|
||||
- Whether or not entire-word mode should be turned on.
|
||||
-->
|
||||
<method name="_setEntireWord">
|
||||
<parameter name="aEntireWord"/>
|
||||
<body><![CDATA[
|
||||
let prefsvc =
|
||||
Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
// Just set the pref; our observer will change the find bar behavior.
|
||||
prefsvc.setBoolPref("findbar.entireword", aEntireWord);
|
||||
|
||||
if (this.getElement("highlight").checked)
|
||||
this._setHighlightTimeout();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="_strBundle">null</field>
|
||||
<property name="strBundle">
|
||||
<getter><![CDATA[
|
||||
|
@ -665,6 +726,8 @@
|
|||
stringsBundle.GetStringFromName("FastFindLinks");
|
||||
this._caseSensitiveStr =
|
||||
stringsBundle.GetStringFromName("CaseSensitive");
|
||||
this._entireWordStr =
|
||||
stringsBundle.GetStringFromName("EntireWord");
|
||||
}
|
||||
|
||||
this._findFailedString = null;
|
||||
|
@ -910,6 +973,7 @@
|
|||
this.getElement("find-previous").hidden = showMinimalUI;
|
||||
foundMatches.hidden = showMinimalUI || !foundMatches.value;
|
||||
this._updateCaseSensitivity();
|
||||
this._updateEntireWord();
|
||||
this._setHighlightAll();
|
||||
|
||||
if (showMinimalUI)
|
||||
|
@ -941,9 +1005,13 @@
|
|||
|
||||
// Only search on input if we don't have a last-failed string,
|
||||
// or if the current search string doesn't start with it.
|
||||
// In entire-word mode we always attemp a find; since sequential matching
|
||||
// is not guaranteed, the first character typed may not be a word (no
|
||||
// match), but the with the second character it may well be a word,
|
||||
// thus a match.
|
||||
if (!this._findFailedString ||
|
||||
!val.startsWith(this._findFailedString))
|
||||
{
|
||||
!val.startsWith(this._findFailedString) ||
|
||||
this._entireWord) {
|
||||
// Getting here means the user commanded a find op. Make sure any
|
||||
// initial prefilling is ignored if it hasn't happened yet.
|
||||
if (this._startFindDeferred) {
|
||||
|
@ -956,6 +1024,7 @@
|
|||
this._setHighlightTimeout();
|
||||
|
||||
this._updateCaseSensitivity(val);
|
||||
this._updateEntireWord();
|
||||
|
||||
this.browser.finder.fastFind(val, this._findMode == this.FIND_LINKS,
|
||||
this._findMode != this.FIND_NORMAL);
|
||||
|
@ -1065,6 +1134,7 @@
|
|||
event.initCustomEvent("find" + aType, true, true, {
|
||||
query: this._findField.value,
|
||||
caseSensitive: !!this._typeAheadCaseSensitive,
|
||||
entireWord: this._entireWord,
|
||||
highlightAll: this._highlightAll,
|
||||
findPrevious: aFindPrevious
|
||||
});
|
||||
|
|
|
@ -14,3 +14,6 @@
|
|||
<!ENTITY caseSensitive.label "Match Case">
|
||||
<!ENTITY caseSensitive.accesskey "c">
|
||||
<!ENTITY caseSensitive.tooltiptext "Search with case sensitivity">
|
||||
<!ENTITY entireWord.label "Whole Words">
|
||||
<!ENTITY entireWord.accesskey "w">
|
||||
<!ENTITY entireWord.tooltiptext "Search whole words only">
|
||||
|
|
|
@ -10,6 +10,7 @@ NormalFind=Find in page
|
|||
FastFind=Quick find
|
||||
FastFindLinks=Quick find (links only)
|
||||
CaseSensitive=(Case sensitive)
|
||||
EntireWord=(Whole words only)
|
||||
# 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.
|
||||
|
|
|
@ -121,6 +121,10 @@ Finder.prototype = {
|
|||
this._fastFind.caseSensitive = aSensitive;
|
||||
},
|
||||
|
||||
set entireWord(aEntireWord) {
|
||||
this._fastFind.entireWord = aEntireWord;
|
||||
},
|
||||
|
||||
get highlighter() {
|
||||
if (this._highlighter)
|
||||
return this._highlighter;
|
||||
|
@ -468,6 +472,7 @@ Finder.prototype = {
|
|||
.createInstance()
|
||||
.QueryInterface(Ci.nsIFind);
|
||||
finder.caseSensitive = this._fastFind.caseSensitive;
|
||||
finder.entireWord = this._fastFind.entireWord;
|
||||
|
||||
while ((retRange = finder.Find(aWord, searchRange, startPt, endPt))) {
|
||||
yield retRange;
|
||||
|
|
|
@ -127,6 +127,11 @@ RemoteFinder.prototype = {
|
|||
{ caseSensitive: aSensitive });
|
||||
},
|
||||
|
||||
set entireWord(aEntireWord) {
|
||||
this._browser.messageManager.sendAsyncMessage("Finder:EntireWord",
|
||||
{ entireWord: aEntireWord });
|
||||
},
|
||||
|
||||
getInitialSelection: function() {
|
||||
this._browser.messageManager.sendAsyncMessage("Finder:GetInitialSelection", {});
|
||||
},
|
||||
|
@ -217,6 +222,7 @@ RemoteFinderListener.prototype = {
|
|||
MESSAGES: [
|
||||
"Finder:CaseSensitive",
|
||||
"Finder:Destroy",
|
||||
"Finder:EntireWord",
|
||||
"Finder:FastFind",
|
||||
"Finder:FindAgain",
|
||||
"Finder:SetSearchStringToSelection",
|
||||
|
@ -257,6 +263,10 @@ RemoteFinderListener.prototype = {
|
|||
this._finder.caseSensitive = data.caseSensitive;
|
||||
break;
|
||||
|
||||
case "Finder:EntireWord":
|
||||
this._finder.entireWord = data.entireWord;
|
||||
break;
|
||||
|
||||
case "Finder:SetSearchStringToSelection": {
|
||||
let selection = this._finder.setSearchStringToSelection();
|
||||
this._global.sendAsyncMessage("Finder:CurrentSelectionResult",
|
||||
|
|
|
@ -143,7 +143,8 @@ findbar[noanim] {
|
|||
}
|
||||
|
||||
.findbar-highlight,
|
||||
.findbar-case-sensitive {
|
||||
.findbar-case-sensitive,
|
||||
.findbar-entire-word {
|
||||
margin-inline-start: 5px;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,8 @@ label.findbar-find-fast:-moz-lwtheme,
|
|||
.findbar-find-next,
|
||||
.findbar-find-previous,
|
||||
.findbar-highlight,
|
||||
.findbar-case-sensitive {
|
||||
.findbar-case-sensitive,
|
||||
.findbar-entire-word {
|
||||
-moz-appearance: none;
|
||||
border-radius: 10000px;
|
||||
border: @roundButtonBorder@;
|
||||
|
@ -90,7 +91,8 @@ label.findbar-find-fast:-moz-lwtheme,
|
|||
}
|
||||
|
||||
.findbar-highlight,
|
||||
.findbar-case-sensitive {
|
||||
.findbar-case-sensitive,
|
||||
.findbar-entire-word {
|
||||
margin-inline-end: 5px;
|
||||
padding: 2px 9px;
|
||||
}
|
||||
|
@ -114,8 +116,10 @@ label.findbar-find-fast:-moz-lwtheme,
|
|||
.findbar-find-previous:not([disabled]):hover:active,
|
||||
.findbar-highlight:not([disabled]):hover:active,
|
||||
.findbar-case-sensitive:not([disabled]):hover:active,
|
||||
.findbar-entire-word:not([disabled]):hover:active,
|
||||
.findbar-highlight:not([disabled])[checked="true"],
|
||||
.findbar-case-sensitive:not([disabled])[checked="true"] {
|
||||
.findbar-case-sensitive:not([disabled])[checked="true"],
|
||||
.findbar-entire-word:not([disabled])[checked="true"] {
|
||||
text-shadow: @loweredShadow@;
|
||||
background: @roundButtonPressedBackground@;
|
||||
box-shadow: @roundButtonPressedShadow@;
|
||||
|
|
|
@ -131,12 +131,14 @@ findbar[noanim] {
|
|||
}
|
||||
|
||||
.findbar-highlight,
|
||||
.findbar-case-sensitive {
|
||||
.findbar-case-sensitive,
|
||||
.findbar-entire-word {
|
||||
margin-inline-start: 5px;
|
||||
}
|
||||
|
||||
.findbar-highlight > .toolbarbutton-icon,
|
||||
.findbar-case-sensitive > .toolbarbutton-icon {
|
||||
.findbar-case-sensitive > .toolbarbutton-icon,
|
||||
.findbar-entire-word > .toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче