mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
Bug 1413361: EnsureFrameForTextNode shouldn't reconstruct synchronously without up-to-date styles. r=bz
MozReview-Commit-ID: IzpcdCdcPjr
This commit is contained in:
parent
e333168b51
commit
75916bf75c
@ -3212,21 +3212,26 @@ static void ExtractRectFromOffset(nsIFrame* aFrame,
|
||||
static nsTextFrame*
|
||||
GetTextFrameForContent(nsIContent* aContent, bool aFlushLayout)
|
||||
{
|
||||
nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
|
||||
if (presShell) {
|
||||
presShell->FrameConstructor()->EnsureFrameForTextNode(
|
||||
static_cast<nsGenericDOMDataNode*>(aContent));
|
||||
|
||||
if (aFlushLayout) {
|
||||
aContent->OwnerDoc()->FlushPendingNotifications(FlushType::Layout);
|
||||
}
|
||||
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (frame && frame->IsTextFrame()) {
|
||||
return static_cast<nsTextFrame*>(frame);
|
||||
}
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
if (!presShell) {
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
const bool frameWillBeUnsuppressed =
|
||||
presShell->FrameConstructor()->EnsureFrameForTextNodeIsCreatedAfterFlush(
|
||||
static_cast<nsGenericDOMDataNode*>(aContent));
|
||||
if (aFlushLayout) {
|
||||
doc->FlushPendingNotifications(FlushType::Layout);
|
||||
} else if (frameWillBeUnsuppressed) {
|
||||
doc->FlushPendingNotifications(FlushType::Frames);
|
||||
}
|
||||
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (!frame || !frame->IsTextFrame()) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<nsTextFrame*>(frame);
|
||||
}
|
||||
|
||||
static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
|
||||
|
@ -35,18 +35,18 @@ static nsIFrame*
|
||||
GetFrameForNode(nsINode* aNode, GeometryNodeType aType)
|
||||
{
|
||||
nsIDocument* doc = aNode->OwnerDoc();
|
||||
doc->FlushPendingNotifications(FlushType::Layout);
|
||||
switch (aType) {
|
||||
case GEOMETRY_NODE_ELEMENT:
|
||||
return aNode->AsContent()->GetPrimaryFrame();
|
||||
case GEOMETRY_NODE_TEXT: {
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
if (presShell) {
|
||||
return presShell->FrameConstructor()->EnsureFrameForTextNode(
|
||||
if (aType == GEOMETRY_NODE_TEXT) {
|
||||
if (nsIPresShell* shell = doc->GetShell()) {
|
||||
shell->FrameConstructor()->EnsureFrameForTextNodeIsCreatedAfterFlush(
|
||||
static_cast<nsGenericDOMDataNode*>(aNode));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
doc->FlushPendingNotifications(FlushType::Layout);
|
||||
|
||||
switch (aType) {
|
||||
case GEOMETRY_NODE_TEXT:
|
||||
case GEOMETRY_NODE_ELEMENT:
|
||||
return aNode->AsContent()->GetPrimaryFrame();
|
||||
case GEOMETRY_NODE_DOCUMENT: {
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
return presShell ? presShell->GetRootFrame() : nullptr;
|
||||
|
@ -8955,22 +8955,31 @@ InvalidateCanvasIfNeeded(nsIPresShell* presShell, nsIContent* node)
|
||||
rootFrame->InvalidateFrameSubtree();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::EnsureFrameForTextNode(nsGenericDOMDataNode* aContent)
|
||||
bool
|
||||
nsCSSFrameConstructor::EnsureFrameForTextNodeIsCreatedAfterFlush(
|
||||
nsGenericDOMDataNode* aContent)
|
||||
{
|
||||
if (aContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE) &&
|
||||
!mAlwaysCreateFramesForIgnorableWhitespace) {
|
||||
// Text frame may have been suppressed. Disable suppression and signal
|
||||
// that a flush should be performed. We do this on a document-wide
|
||||
// basis so that pages that repeatedly query metrics for
|
||||
// collapsed-whitespace text nodes don't trigger pathological behavior.
|
||||
mAlwaysCreateFramesForIgnorableWhitespace = true;
|
||||
nsAutoScriptBlocker blocker;
|
||||
BeginUpdate();
|
||||
ReconstructDocElementHierarchy(InsertionKind::Sync);
|
||||
EndUpdate();
|
||||
if (!aContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE)) {
|
||||
return false;
|
||||
}
|
||||
return aContent->GetPrimaryFrame();
|
||||
|
||||
if (mAlwaysCreateFramesForIgnorableWhitespace) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Text frame may have been suppressed. Disable suppression and signal that a
|
||||
// flush should be performed. We do this on a document-wide basis so that
|
||||
// pages that repeatedly query metrics for collapsed-whitespace text nodes
|
||||
// don't trigger pathological behavior.
|
||||
mAlwaysCreateFramesForIgnorableWhitespace = true;
|
||||
Element* root = mDocument->GetRootElement();
|
||||
if (!root) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RestyleManager()->PostRestyleEvent(
|
||||
root, nsRestyleHint(0), nsChangeHint_ReconstructFrame);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -317,11 +317,12 @@ public:
|
||||
CharacterDataChangeInfo* aInfo);
|
||||
|
||||
// If aContent is a text node that has been optimized away due to being
|
||||
// whitespace next to a block boundary (or for some other reason), stop
|
||||
// doing that and create a frame for it if it should have one. This recreates
|
||||
// frames so be careful (although this should not change actual layout).
|
||||
// Returns the frame for aContent if there is one.
|
||||
nsIFrame* EnsureFrameForTextNode(nsGenericDOMDataNode* aContent);
|
||||
// whitespace next to a block boundary (or for some other reason), ensure that
|
||||
// a frame for it is created the next time frames are flushed, if it can
|
||||
// possibly have a frame at all.
|
||||
//
|
||||
// Returns whether there are chances for the frame to be unsuppressed.
|
||||
bool EnsureFrameForTextNodeIsCreatedAfterFlush(nsGenericDOMDataNode* aContent);
|
||||
|
||||
// Generate the child frames and process bindings
|
||||
void GenerateChildFrames(nsContainerFrame* aFrame);
|
||||
|
8
layout/style/crashtests/1413361.html
Normal file
8
layout/style/crashtests/1413361.html
Normal file
@ -0,0 +1,8 @@
|
||||
<script>
|
||||
function go() {
|
||||
window.getSelection().selectAllChildren(document.body.firstChild);
|
||||
document.createElement("body").aLink = "-moz-mac-menuselect";
|
||||
window.getSelection().getRangeAt(0).getClientRects();
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
@ -259,3 +259,4 @@ load 1410226-2.html
|
||||
load 1411143.html
|
||||
load 1411478.html
|
||||
load 1413288.html
|
||||
load 1413361.html
|
||||
|
Loading…
Reference in New Issue
Block a user