mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1413834 - part 1: Limit frame traversal and getting of next tabindex inside scope owned by document root, r=smaug
--HG-- extra : rebase_source : 6a9bca46f5e98311b0179b8b44bebe59bb77e676
This commit is contained in:
parent
6cfd4299c2
commit
8e8a01efb7
@ -13,8 +13,8 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsIContentParent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIDOMElement.h"
|
||||
@ -2603,7 +2603,8 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
true, // aFollowOOFs
|
||||
false // aSkipPopupChecks
|
||||
false, // aSkipPopupChecks
|
||||
false // aSkipShadow
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -3119,7 +3120,8 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
true, // aFollowOOFs
|
||||
aForDocumentNavigation // aSkipPopupChecks
|
||||
aForDocumentNavigation, // aSkipPopupChecks
|
||||
nsDocument::IsShadowDOMEnabled(aRootContent) // aSkipShadow
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -3408,9 +3410,16 @@ nsFocusManager::GetNextTabIndex(nsIContent* aParent,
|
||||
for (nsIContent* child = aParent->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
|
||||
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
|
||||
MOZ_ASSERT(!child->IsHTMLElement(nsGkAtoms::slot),
|
||||
"Slots shouldn't appear in light DOM");
|
||||
|
||||
// Skip child's descendants if child is a shadow host, as they are
|
||||
// in the focus navigation scope owned by child's shadow root
|
||||
if (!(nsDocument::IsShadowDOMEnabled(aParent) && child->GetShadowRoot())) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
|
||||
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString tabIndexStr;
|
||||
@ -3429,10 +3438,17 @@ nsFocusManager::GetNextTabIndex(nsIContent* aParent,
|
||||
for (nsIContent* child = aParent->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
|
||||
(childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
|
||||
tabIndex = childTabIndex;
|
||||
MOZ_ASSERT(!child->IsHTMLElement(nsGkAtoms::slot),
|
||||
"Slots shouldn't appear in light DOM");
|
||||
|
||||
// Skip child's descendants if child is a shadow host, as they are
|
||||
// in the focus navigation scope owned by child's shadow root
|
||||
if (!(nsDocument::IsShadowDOMEnabled(aParent) && child->GetShadowRoot())) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
|
||||
(childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
|
||||
tabIndex = childTabIndex;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString tabIndexStr;
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
|
||||
nsIteratorType aType, bool aLockScroll, bool aFollowOOFs,
|
||||
bool aSkipPopupChecks);
|
||||
bool aSkipPopupChecks, bool aSkipShadow);
|
||||
|
||||
protected:
|
||||
virtual ~nsFrameIterator() {}
|
||||
@ -94,6 +94,7 @@ protected:
|
||||
const bool mLockScroll;
|
||||
const bool mFollowOOFs;
|
||||
const bool mSkipPopupChecks;
|
||||
const bool mSkipShadow;
|
||||
const nsIteratorType mType;
|
||||
|
||||
private:
|
||||
@ -111,8 +112,10 @@ class nsVisualIterator: public nsFrameIterator
|
||||
public:
|
||||
nsVisualIterator(nsPresContext* aPresContext, nsIFrame *aStart,
|
||||
nsIteratorType aType, bool aLockScroll,
|
||||
bool aFollowOOFs, bool aSkipPopupChecks) :
|
||||
nsFrameIterator(aPresContext, aStart, aType, aLockScroll, aFollowOOFs, aSkipPopupChecks) {}
|
||||
bool aFollowOOFs, bool aSkipPopupChecks,
|
||||
bool aSkipShadow) :
|
||||
nsFrameIterator(aPresContext, aStart, aType, aLockScroll,
|
||||
aFollowOOFs, aSkipPopupChecks, aSkipShadow) {}
|
||||
|
||||
protected:
|
||||
nsIFrame* GetFirstChildInner(nsIFrame* aFrame) override;
|
||||
@ -143,7 +146,8 @@ NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
|
||||
bool aVisual,
|
||||
bool aLockInScrollView,
|
||||
bool aFollowOOFs,
|
||||
bool aSkipPopupChecks)
|
||||
bool aSkipPopupChecks,
|
||||
bool aSkipShadow)
|
||||
{
|
||||
if (!aEnumerator || !aStart)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
@ -155,10 +159,12 @@ NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
|
||||
nsCOMPtr<nsIFrameEnumerator> trav;
|
||||
if (aVisual) {
|
||||
trav = new nsVisualIterator(aPresContext, aStart, aType,
|
||||
aLockInScrollView, aFollowOOFs, aSkipPopupChecks);
|
||||
aLockInScrollView, aFollowOOFs,
|
||||
aSkipPopupChecks, aSkipShadow);
|
||||
} else {
|
||||
trav = new nsFrameIterator(aPresContext, aStart, aType,
|
||||
aLockInScrollView, aFollowOOFs, aSkipPopupChecks);
|
||||
aLockInScrollView, aFollowOOFs,
|
||||
aSkipPopupChecks, aSkipShadow);
|
||||
}
|
||||
trav.forget(aEnumerator);
|
||||
return NS_OK;
|
||||
@ -187,7 +193,8 @@ NS_IMETHODIMP
|
||||
{
|
||||
return NS_NewFrameTraversal(aEnumerator, aPresContext, aStart,
|
||||
static_cast<nsIteratorType>(aType),
|
||||
aVisual, aLockInScrollView, aFollowOOFs, aSkipPopupChecks);
|
||||
aVisual, aLockInScrollView, aFollowOOFs,
|
||||
aSkipPopupChecks, false /* aSkipShadow */);
|
||||
}
|
||||
|
||||
// nsFrameIterator implementation
|
||||
@ -196,11 +203,13 @@ NS_IMPL_ISUPPORTS(nsFrameIterator, nsIFrameEnumerator)
|
||||
|
||||
nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
|
||||
nsIteratorType aType, bool aLockInScrollView,
|
||||
bool aFollowOOFs, bool aSkipPopupChecks)
|
||||
bool aFollowOOFs, bool aSkipPopupChecks,
|
||||
bool aSkipShadow)
|
||||
: mPresContext(aPresContext),
|
||||
mLockScroll(aLockInScrollView),
|
||||
mFollowOOFs(aFollowOOFs),
|
||||
mSkipPopupChecks(aSkipPopupChecks),
|
||||
mSkipShadow(aSkipShadow),
|
||||
mType(aType),
|
||||
mStart(aStart),
|
||||
mCurrent(aStart),
|
||||
@ -402,6 +411,15 @@ nsFrameIterator::GetParentFrameNotPopup(nsIFrame* aFrame)
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetFirstChild(nsIFrame* aFrame)
|
||||
{
|
||||
if (mSkipShadow) {
|
||||
// Skip frames rendered from contents in shadow tree,
|
||||
// primarily for focus navigation
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (content && content->GetShadowRoot()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* result = GetFirstChildInner(aFrame);
|
||||
if (mLockScroll && result && result->IsScrollFrame())
|
||||
return nullptr;
|
||||
@ -417,6 +435,15 @@ nsFrameIterator::GetFirstChild(nsIFrame* aFrame)
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetLastChild(nsIFrame* aFrame)
|
||||
{
|
||||
if (mSkipShadow) {
|
||||
// Skip frames rendered from contents in shadow tree,
|
||||
// primarily for focus navigation
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (content && content->GetShadowRoot()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* result = GetLastChildInner(aFrame);
|
||||
if (mLockScroll && result && result->IsScrollFrame())
|
||||
return nullptr;
|
||||
|
@ -18,7 +18,8 @@ nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
|
||||
bool aVisual,
|
||||
bool aLockInScrollView,
|
||||
bool aFollowOOFs,
|
||||
bool aSkipPopupChecks);
|
||||
bool aSkipPopupChecks,
|
||||
bool aSkipShadow);
|
||||
|
||||
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
|
||||
|
||||
|
@ -8148,7 +8148,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
false, // aVisual
|
||||
aPos->mScrollViewStop,
|
||||
false, // aFollowOOFs
|
||||
false // aSkipPopupChecks
|
||||
false, // aSkipPopupChecks
|
||||
false // aSkipShadow
|
||||
);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
@ -8245,7 +8246,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
false, // aVisual
|
||||
aPos->mScrollViewStop,
|
||||
false, // aFollowOOFs
|
||||
false // aSkipPopupChecks
|
||||
false, // aSkipPopupChecks
|
||||
false // aSkipShadow
|
||||
);
|
||||
}
|
||||
while ( !found ){
|
||||
@ -9036,7 +9038,8 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, bool aVisual,
|
||||
aVisual && presContext->BidiEnabled(),
|
||||
aScrollViewStop,
|
||||
true, // aFollowOOFs
|
||||
false // aSkipPopupChecks
|
||||
false, // aSkipPopupChecks
|
||||
false // aSkipShadow
|
||||
);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user