зеркало из https://github.com/mozilla/pjs.git
Bug 175046, bug 172991, bug 166471. Make sure typeaheadfind and regular find don't find comment nodes, display:none, visibility:hidden or visibility:collapsed nodes. r=akkana, sr=kin
This commit is contained in:
Родитель
93fac61aaf
Коммит
963530889d
|
@ -32,6 +32,7 @@ REQUIRES = string \
|
|||
docshell \
|
||||
gfx \
|
||||
layout \
|
||||
locale \
|
||||
content \
|
||||
widget \
|
||||
htmlparser \
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
#include "nsISelection.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIAtom.h"
|
||||
|
@ -337,7 +340,7 @@ nsFind::NextNode(nsIDOMRange* aSearchRange,
|
|||
printf(":::::: Got the first node "); DumpNode(dnode);
|
||||
#endif
|
||||
tc = do_QueryInterface(content);
|
||||
if (tc)
|
||||
if (tc && !SkipNode(content))
|
||||
{
|
||||
mIterNode = do_QueryInterface(content);
|
||||
// Also set mIterOffset if appropriate:
|
||||
|
@ -453,6 +456,42 @@ PRBool nsFind::IsTextNode(nsIDOMNode* aNode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsFind::IsVisibleNode(nsIDOMNode *aDOMNode)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
|
||||
if (!content)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
content->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
doc->GetShellAt(0, getter_AddRefs(presShell));
|
||||
if (!presShell)
|
||||
return PR_FALSE;
|
||||
|
||||
nsIFrame *frame = nsnull;
|
||||
presShell->GetPrimaryFrameFor(content, &frame);
|
||||
if (!frame) {
|
||||
// No frame! Not visible then.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
frame->GetStyleContext(getter_AddRefs(styleContext));
|
||||
if (styleContext) {
|
||||
const nsStyleVisibility* vis =
|
||||
(const nsStyleVisibility*)styleContext->GetStyleData(eStyleStruct_Visibility);
|
||||
if (!vis || !vis->IsVisible()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsFind::SkipNode(nsIContent* aContent)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
|
@ -813,16 +852,12 @@ nsFind::Find(const PRUnichar *aPatText, nsIDOMRange* aSearchRange,
|
|||
#endif
|
||||
|
||||
// Make the range:
|
||||
if (aRangeRet)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> startParent;
|
||||
nsCOMPtr<nsIDOMNode> endParent;
|
||||
nsCOMPtr<nsIDOMRange> range (do_CreateInstance(kRangeCID));
|
||||
if (range)
|
||||
{
|
||||
PRInt32 matchStartOffset, matchEndOffset;
|
||||
if (range)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> startParent;
|
||||
nsCOMPtr<nsIDOMNode> endParent;
|
||||
// convert char index to range point:
|
||||
PRInt32 mao = matchAnchorOffset + (mFindBackward ? 1 : 0);
|
||||
if (mFindBackward)
|
||||
|
@ -839,30 +874,37 @@ nsFind::Find(const PRUnichar *aPatText, nsIDOMRange* aSearchRange,
|
|||
matchStartOffset = mao;
|
||||
matchEndOffset = findex+1;
|
||||
}
|
||||
if (startParent && endParent)
|
||||
if (startParent && endParent &&
|
||||
IsVisibleNode(startParent) && IsVisibleNode(endParent))
|
||||
{
|
||||
range->SetStart(startParent, matchStartOffset);
|
||||
range->SetEnd(endParent, matchEndOffset);
|
||||
*aRangeRet = range.get();
|
||||
NS_ADDREF(*aRangeRet);
|
||||
}
|
||||
}
|
||||
else {
|
||||
startParent = nsnull; // This match is no good -- invisible or bad range
|
||||
}
|
||||
}
|
||||
|
||||
if (startParent) {
|
||||
// If startParent == nsnull, we didn't successfully make range
|
||||
// or, we didn't make a range because the start or end node were invisible
|
||||
// Reset the offset to the other end of the found string:
|
||||
mIterOffset = findex + (mFindBackward ? 1 : 0);
|
||||
#ifdef DEBUG_FIND
|
||||
#ifdef DEBUG_FIND
|
||||
printf("mIterOffset = %d, mIterNode = ", mIterOffset);
|
||||
DumpNode(mIterNode);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ResetAll();
|
||||
return NS_OK;
|
||||
}
|
||||
matchAnchorNode = nsnull; // This match is no good, continue on in document
|
||||
}
|
||||
|
||||
if (matchAnchorNode) {
|
||||
// Not done, but still matching.
|
||||
|
||||
// Advance and loop around for the next characters.
|
||||
// But don't advance from a space to a non-space:
|
||||
if (!inWhitespace || DONE_WITH_PINDEX || IsSpace(patStr[pindex+incr]))
|
||||
|
@ -876,6 +918,7 @@ nsFind::Find(const PRUnichar *aPatText, nsIDOMRange* aSearchRange,
|
|||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FIND
|
||||
printf("NOT: %c == %c\n", c, patc);
|
||||
|
|
|
@ -101,6 +101,7 @@ protected:
|
|||
PRBool IsTextNode(nsIDOMNode* aNode);
|
||||
PRBool IsBlockNode(nsIContent* aNode);
|
||||
PRBool SkipNode(nsIContent* aNode);
|
||||
PRBool IsVisibleNode(nsIDOMNode *aNode);
|
||||
|
||||
// Move in the right direction for our search:
|
||||
nsresult NextNode(nsIDOMRange* aSearchRange,
|
||||
|
|
Загрузка…
Ссылка в новой задаче