зеркало из 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
|
// Traditionally focusable elements can take focus as long as they don't set
|
||||||
// the disabled attribute
|
// the disabled attribute
|
||||||
|
|
||||||
nsIPresShell *presShell = aPresContext->PresShell();
|
nsCOMPtr<nsIPresShell> presShell = aPresContext->PresShell();
|
||||||
|
if (!presShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
||||||
if (frame && frame->IsFocusable() &&
|
if (frame && frame->IsFocusable() &&
|
||||||
aPresContext->EventStateManager()->SetContentState(this,
|
aPresContext->EventStateManager()->SetContentState(this,
|
||||||
NS_EVENT_STATE_FOCUS)) {
|
NS_EVENT_STATE_FOCUS)) {
|
||||||
// Reget frame, setting content state can change style which can
|
presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||||
// cause a frame reconstruction, for example if CSS overflow changes
|
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||||
frame = presShell->GetPrimaryFrameFor(this);
|
|
||||||
if (frame) {
|
|
||||||
presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
|
||||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1172,28 +1172,17 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop)
|
||||||
return NS_OK;
|
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
|
// Get the presentation shell
|
||||||
nsIPresShell *presShell = document->GetShellAt(0);
|
nsCOMPtr<nsIPresShell> presShell = document->GetShellAt(0);
|
||||||
if (!presShell) {
|
if (!presShell) {
|
||||||
return NS_OK;
|
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 :
|
PRIntn vpercent = aTop ? NS_PRESSHELL_SCROLL_TOP :
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE;
|
NS_PRESSHELL_SCROLL_ANYWHERE;
|
||||||
|
|
||||||
presShell->ScrollFrameIntoView(frame, vpercent,
|
presShell->ScrollContentIntoView(this, vpercent,
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,20 +240,10 @@ nsHTMLAnchorElement::SetFocus(nsPresContext* aPresContext)
|
||||||
nsILinkHandler *handler = aPresContext->GetLinkHandler();
|
nsILinkHandler *handler = aPresContext->GetLinkHandler();
|
||||||
if (handler && aPresContext->EventStateManager()->
|
if (handler && aPresContext->EventStateManager()->
|
||||||
SetContentState(this, NS_EVENT_STATE_FOCUS)) {
|
SetContentState(this, NS_EVENT_STATE_FOCUS)) {
|
||||||
// Make sure the presentation is up-to-date
|
nsCOMPtr<nsIPresShell> presShell = aPresContext->GetPresShell();
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
|
||||||
if (doc) {
|
|
||||||
doc->FlushPendingNotifications(Flush_Layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
|
||||||
|
|
||||||
if (presShell) {
|
if (presShell) {
|
||||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||||
if (frame) {
|
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||||
presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_ANYWHERE,
|
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,21 +196,10 @@ nsHTMLAreaElement::SetFocus(nsPresContext* aPresContext)
|
||||||
NS_EVENT_STATE_FOCUS)) {
|
NS_EVENT_STATE_FOCUS)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
nsCOMPtr<nsIPresShell> presShell = aPresContext->GetPresShell();
|
||||||
// Make sure the presentation is up-to-date
|
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
|
||||||
if (doc) {
|
|
||||||
doc->FlushPendingNotifications(Flush_Layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
|
||||||
|
|
||||||
if (presShell) {
|
if (presShell) {
|
||||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
presShell->ScrollContentIntoView(this, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||||
if (frame) {
|
|
||||||
presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_ANYWHERE,
|
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2622,17 +2622,10 @@ NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
|
||||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
// Get the primary frame
|
// Tell the PresShell to scroll to the primary frame of the content.
|
||||||
// Remember Frames aren't ref-counted. They are in their own special little
|
NS_ENSURE_SUCCESS(presShell->ScrollContentIntoView(content,
|
||||||
// world.
|
NS_PRESSHELL_SCROLL_TOP,
|
||||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(content);
|
NS_PRESSHELL_SCROLL_ANYWHERE),
|
||||||
|
|
||||||
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),
|
|
||||||
NS_ERROR_FAILURE);
|
NS_ERROR_FAILURE);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,12 +98,12 @@ class nsIScrollableFrame;
|
||||||
|
|
||||||
typedef short SelectionType;
|
typedef short SelectionType;
|
||||||
|
|
||||||
// 7C398278-8523-4E5C-8268-4E4BC8B0C5CA
|
//12f7a744-26d8-493e-8072-90123a35f69f
|
||||||
#define NS_IPRESSHELL_IID \
|
#define NS_IPRESSHELL_IID \
|
||||||
{ 0x7C398278, 0x8523, 0x4E5C, \
|
{ 0x12f7a744, 0x26d8, 0x493e, \
|
||||||
{ 0x82, 0x68, 0x4E, 0x4B, 0xC8, 0xB0, 0xC5, 0xCA } }
|
{ 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_TOP 0
|
||||||
#define NS_PRESSHELL_SCROLL_BOTTOM 100
|
#define NS_PRESSHELL_SCROLL_BOTTOM 100
|
||||||
#define NS_PRESSHELL_SCROLL_LEFT 0
|
#define NS_PRESSHELL_SCROLL_LEFT 0
|
||||||
|
@ -441,6 +441,17 @@ public:
|
||||||
PRIntn aVPercent,
|
PRIntn aVPercent,
|
||||||
PRIntn aHPercent) const = 0;
|
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
|
* Suppress notification of the frame manager that frames are
|
||||||
* being destroyed.
|
* being destroyed.
|
||||||
|
|
|
@ -859,6 +859,10 @@ public:
|
||||||
PRIntn aVPercent,
|
PRIntn aVPercent,
|
||||||
PRIntn aHPercent) const;
|
PRIntn aHPercent) const;
|
||||||
|
|
||||||
|
NS_IMETHOD ScrollContentIntoView(nsIContent* aContent,
|
||||||
|
PRIntn aVPercent,
|
||||||
|
PRIntn aHPercent) const;
|
||||||
|
|
||||||
NS_IMETHOD SetIgnoreFrameDestruction(PRBool aIgnore);
|
NS_IMETHOD SetIgnoreFrameDestruction(PRBool aIgnore);
|
||||||
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
@ -3731,12 +3735,8 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
|
||||||
if (content) {
|
if (content) {
|
||||||
// Flush notifications so we scroll to the right place
|
// Flush notifications so we scroll to the right place
|
||||||
if (aScroll) {
|
if (aScroll) {
|
||||||
mDocument->FlushPendingNotifications(Flush_Layout);
|
rv = ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_TOP,
|
||||||
// Get the primary frame
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||||
nsIFrame* frame = GetPrimaryFrameFor(content);
|
|
||||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
|
||||||
rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP,
|
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4047,6 +4047,19 @@ PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
|
||||||
return NS_OK;
|
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
|
// GetLinkLocation: copy link location to clipboard
|
||||||
NS_IMETHODIMP PresShell::GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocationString)
|
NS_IMETHODIMP PresShell::GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocationString)
|
||||||
{
|
{
|
||||||
|
|
|
@ -192,14 +192,11 @@ inFlasher::ScrollElementIntoView(nsIDOMElement *aElement)
|
||||||
if (!presShell) {
|
if (!presShell) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement, presShell);
|
|
||||||
if (!frame) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
presShell->ScrollFrameIntoView(frame,
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE /* VPercent */,
|
presShell->ScrollContentIntoView(content,
|
||||||
NS_PRESSHELL_SCROLL_ANYWHERE /* HPercent */);
|
NS_PRESSHELL_SCROLL_ANYWHERE /* VPercent */,
|
||||||
|
NS_PRESSHELL_SCROLL_ANYWHERE /* HPercent */);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,9 +224,7 @@ nsFormFillController::SetPopupOpen(PRBool aPopupOpen)
|
||||||
nsCOMPtr<nsIPresShell> presShell;
|
nsCOMPtr<nsIPresShell> presShell;
|
||||||
docShell->GetPresShell(getter_AddRefs(presShell));
|
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||||
NS_ENSURE_STATE(presShell);
|
NS_ENSURE_STATE(presShell);
|
||||||
nsIFrame *frame = presShell->GetPrimaryFrameFor(content.get());
|
presShell->ScrollContentIntoView(content,
|
||||||
if (frame)
|
|
||||||
presShell->ScrollFrameIntoView(frame,
|
|
||||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
|
||||||
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче