зеркало из https://github.com/mozilla/gecko-dev.git
Bug 372665 ��� Crash [@ PresShell::ScrollFrameIntoView] when focusing br during pageload. (Adding ScrollContentIntoView), r+sr=roc
This commit is contained in:
Родитель
1fc605fca5
Коммит
4e0ebc823d
|
@ -2120,18 +2120,16 @@ nsGenericElement::SetFocus(nsPresContext* aPresContext)
|
|||
// Traditionally focusable elements can take focus as long as they don't set
|
||||
// the disabled attribute
|
||||
|
||||
nsIPresShell *presShell = aPresContext->PresShell();
|
||||
nsCOMPtr<nsIPresShell> presShell = aPresContext->PresShell();
|
||||
if (!presShell) {
|
||||
return;
|
||||
}
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
||||
if (frame && frame->IsFocusable() &&
|
||||
aPresContext->EventStateManager()->SetContentState(this,
|
||||
NS_EVENT_STATE_FOCUS)) {
|
||||
// Reget frame, setting content state can change style which can
|
||||
// cause a frame reconstruction, for example if CSS overflow changes
|
||||
frame = presShell->GetPrimaryFrameFor(this);
|
||||
if (frame) {
|
||||
presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||
}
|
||||
aPresContext->EventStateManager()->SetContentState(this,
|
||||
NS_EVENT_STATE_FOCUS)) {
|
||||
presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1172,28 +1172,17 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Flush all pending notifications so that our frames are up to date. Make
|
||||
// sure to do this first thing, since it may end up destroying our document's
|
||||
// presshell.
|
||||
document->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
// Get the presentation shell
|
||||
nsIPresShell *presShell = document->GetShellAt(0);
|
||||
nsCOMPtr<nsIPresShell> presShell = document->GetShellAt(0);
|
||||
if (!presShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the primary frame for this element
|
||||
nsIFrame *frame = presShell->GetPrimaryFrameFor(this);
|
||||
if (!frame) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRIntn vpercent = aTop ? NS_PRESSHELL_SCROLL_TOP :
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||
|
||||
presShell->ScrollFrameIntoView(frame, vpercent,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
presShell->ScrollContentIntoView(this, vpercent,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -240,20 +240,10 @@ nsHTMLAnchorElement::SetFocus(nsPresContext* aPresContext)
|
|||
nsILinkHandler *handler = aPresContext->GetLinkHandler();
|
||||
if (handler && aPresContext->EventStateManager()->
|
||||
SetContentState(this, NS_EVENT_STATE_FOCUS)) {
|
||||
// Make sure the presentation is up-to-date
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = aPresContext->GetPresShell();
|
||||
if (presShell) {
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
||||
if (frame) {
|
||||
presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
}
|
||||
presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,21 +196,10 @@ nsHTMLAreaElement::SetFocus(nsPresContext* aPresContext)
|
|||
NS_EVENT_STATE_FOCUS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the presentation is up-to-date
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = aPresContext->GetPresShell();
|
||||
if (presShell) {
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
||||
if (frame) {
|
||||
presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2622,17 +2622,10 @@ NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
|||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||
|
||||
// Get the primary frame
|
||||
// Remember Frames aren't ref-counted. They are in their own special little
|
||||
// world.
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(content);
|
||||
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
// tell the pres shell to scroll to the frame
|
||||
NS_ENSURE_SUCCESS(presShell->ScrollFrameIntoView(frame,
|
||||
NS_PRESSHELL_SCROLL_TOP,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE),
|
||||
// Tell the PresShell to scroll to the primary frame of the content.
|
||||
NS_ENSURE_SUCCESS(presShell->ScrollContentIntoView(content,
|
||||
NS_PRESSHELL_SCROLL_TOP,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE),
|
||||
NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -98,12 +98,12 @@ class nsIScrollableFrame;
|
|||
|
||||
typedef short SelectionType;
|
||||
|
||||
// 7C398278-8523-4E5C-8268-4E4BC8B0C5CA
|
||||
//12f7a744-26d8-493e-8072-90123a35f69f
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0x7C398278, 0x8523, 0x4E5C, \
|
||||
{ 0x82, 0x68, 0x4E, 0x4B, 0xC8, 0xB0, 0xC5, 0xCA } }
|
||||
{ 0x12f7a744, 0x26d8, 0x493e, \
|
||||
{ 0x80, 0x72, 0x90, 0x12, 0x3a, 0x35, 0xf6, 0x9f } }
|
||||
|
||||
// Constants uses for ScrollFrameIntoView() function
|
||||
// Constants for ScrollFrameIntoView() and ScrollContentIntoView() functions.
|
||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||
#define NS_PRESSHELL_SCROLL_BOTTOM 100
|
||||
#define NS_PRESSHELL_SCROLL_LEFT 0
|
||||
|
@ -441,6 +441,17 @@ public:
|
|||
PRIntn aVPercent,
|
||||
PRIntn aHPercent) const = 0;
|
||||
|
||||
/**
|
||||
* Otherwise same as the above, but takes an aContent as the first parameter
|
||||
* and after flushing pending notifications tries to find primary frame
|
||||
* for that and then call ScrollFrameIntoView.
|
||||
* @param aContent The content object of which primary frame should be
|
||||
* scrolled into view.
|
||||
*/
|
||||
NS_IMETHOD ScrollContentIntoView(nsIContent* aContent,
|
||||
PRIntn aVPercent,
|
||||
PRIntn aHPercent) const = 0;
|
||||
|
||||
/**
|
||||
* Suppress notification of the frame manager that frames are
|
||||
* being destroyed.
|
||||
|
|
|
@ -859,6 +859,10 @@ public:
|
|||
PRIntn aVPercent,
|
||||
PRIntn aHPercent) const;
|
||||
|
||||
NS_IMETHOD ScrollContentIntoView(nsIContent* aContent,
|
||||
PRIntn aVPercent,
|
||||
PRIntn aHPercent) const;
|
||||
|
||||
NS_IMETHOD SetIgnoreFrameDestruction(PRBool aIgnore);
|
||||
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
||||
|
||||
|
@ -3731,12 +3735,8 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
|
|||
if (content) {
|
||||
// Flush notifications so we scroll to the right place
|
||||
if (aScroll) {
|
||||
mDocument->FlushPendingNotifications(Flush_Layout);
|
||||
// Get the primary frame
|
||||
nsIFrame* frame = GetPrimaryFrameFor(content);
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
rv = ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_TOP,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -4047,6 +4047,19 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::ScrollContentIntoView(nsIContent* aContent,
|
||||
PRIntn aVPercent,
|
||||
PRIntn aHPercent) const
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = aContent; // Keep content alive while flushing.
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
|
||||
nsCOMPtr<nsIDocument> currentDoc = content->GetCurrentDoc();
|
||||
NS_ENSURE_STATE(currentDoc);
|
||||
currentDoc->FlushPendingNotifications(Flush_Layout);
|
||||
return ScrollFrameIntoView(GetPrimaryFrameFor(content), aVPercent, aHPercent);
|
||||
}
|
||||
|
||||
// GetLinkLocation: copy link location to clipboard
|
||||
NS_IMETHODIMP PresShell::GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocationString)
|
||||
{
|
||||
|
|
|
@ -192,14 +192,11 @@ inFlasher::ScrollElementIntoView(nsIDOMElement *aElement)
|
|||
if (!presShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement, presShell);
|
||||
if (!frame) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
presShell->ScrollFrameIntoView(frame,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE /* VPercent */,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE /* HPercent */);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
presShell->ScrollContentIntoView(content,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE /* VPercent */,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE /* HPercent */);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -224,9 +224,7 @@ nsFormFillController::SetPopupOpen(PRBool aPopupOpen)
|
|||
nsCOMPtr<nsIPresShell> presShell;
|
||||
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||
NS_ENSURE_STATE(presShell);
|
||||
nsIFrame *frame = presShell->GetPrimaryFrameFor(content.get());
|
||||
if (frame)
|
||||
presShell->ScrollFrameIntoView(frame,
|
||||
presShell->ScrollContentIntoView(content,
|
||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче