Bug 396367. Make sure that we have flushed content notifications anytime we process restyles that might cause frame construction. r=bzbarsky

--HG--
extra : rebase_source : c6aa412247ab70f5bf3a4688f262edcccd2d6fdd
This commit is contained in:
Timothy Nikkel 2009-12-22 18:09:10 -06:00
Родитель 841fb7e959
Коммит b0273ee72c
5 изменённых файлов: 134 добавлений и 17 удалений

Просмотреть файл

@ -11057,8 +11057,6 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint)
if (!mPresShell || !mPresShell->GetRootFrame()) if (!mPresShell || !mPresShell->GetRootFrame())
return; return;
nsAutoScriptBlocker scriptBlocker;
// Make sure that the viewmanager will outlive the presshell // Make sure that the viewmanager will outlive the presshell
nsIViewManager::UpdateViewBatch batch(mPresShell->GetViewManager()); nsIViewManager::UpdateViewBatch batch(mPresShell->GetViewManager());
@ -11066,6 +11064,12 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint)
// the parent frame and thus destroys the pres shell. // the parent frame and thus destroys the pres shell.
nsCOMPtr<nsIPresShell> kungFuDeathGrip(mPresShell); nsCOMPtr<nsIPresShell> kungFuDeathGrip(mPresShell);
// We may reconstruct frames below and hence process anything that is in the
// tree. We don't want to get notified to process those items again after.
mPresShell->GetDocument()->FlushPendingNotifications(Flush_ContentAndNotify);
nsAutoScriptBlocker scriptBlocker;
// Tell the style set to get the old rule tree out of the way // Tell the style set to get the old rule tree out of the way
// so we can recalculate while maintaining rule tree immutability // so we can recalculate while maintaining rule tree immutability
nsresult rv = mPresShell->StyleSet()->BeginReconstruct(); nsresult rv = mPresShell->StyleSet()->BeginReconstruct();

Просмотреть файл

@ -2650,6 +2650,10 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
{ {
nsIViewManager::UpdateViewBatch batch(mViewManager); nsIViewManager::UpdateViewBatch batch(mViewManager);
// Have to make sure that the content notifications are flushed before we
// start messing with the frame model; otherwise we can get content doubling.
mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
// Make sure style is up to date // Make sure style is up to date
{ {
nsAutoScriptBlocker scriptBlocker; nsAutoScriptBlocker scriptBlocker;
@ -5019,6 +5023,12 @@ PresShell::ContentRemoved(nsIDocument *aDocument,
nsresult nsresult
PresShell::ReconstructFrames(void) PresShell::ReconstructFrames(void)
{ {
nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
// Have to make sure that the content notifications are flushed before we
// start messing with the frame model; otherwise we can get content doubling.
mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
nsAutoCauseReflowNotifier crNotifier(this); nsAutoCauseReflowNotifier crNotifier(this);
mFrameConstructor->BeginUpdate(); mFrameConstructor->BeginUpdate();
nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy(); nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy();
@ -7544,23 +7554,29 @@ PresShell::Observe(nsISupports* aSubject,
NS_ASSERTION(mViewManager, "View manager must exist"); NS_ASSERTION(mViewManager, "View manager must exist");
nsIViewManager::UpdateViewBatch batch(mViewManager); nsIViewManager::UpdateViewBatch batch(mViewManager);
WalkFramesThroughPlaceholders(mPresContext, rootFrame, nsWeakFrame weakRoot(rootFrame);
&ReResolveMenusAndTrees, nsnull); // Have to make sure that the content notifications are flushed before we
// start messing with the frame model; otherwise we can get content doubling.
mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
// Because "chrome:" URL equality is messy, reframe image box if (weakRoot.IsAlive()) {
// frames (hack!). WalkFramesThroughPlaceholders(mPresContext, rootFrame,
nsStyleChangeList changeList; &ReResolveMenusAndTrees, nsnull);
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
ReframeImageBoxes, &changeList); // Because "chrome:" URL equality is messy, reframe image box
// Mark ourselves as not safe to flush while we're doing frame // frames (hack!).
// construction. nsStyleChangeList changeList;
{ WalkFramesThroughPlaceholders(mPresContext, rootFrame,
nsAutoScriptBlocker scriptBlocker; ReframeImageBoxes, &changeList);
++mChangeNestCount; // Mark ourselves as not safe to flush while we're doing frame
mFrameConstructor->ProcessRestyledFrames(changeList); // construction.
--mChangeNestCount; {
nsAutoScriptBlocker scriptBlocker;
++mChangeNestCount;
mFrameConstructor->ProcessRestyledFrames(changeList);
--mChangeNestCount;
}
} }
batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY
InvalidateAccessibleSubtree(nsnull); InvalidateAccessibleSubtree(nsnull);

Просмотреть файл

@ -46,6 +46,8 @@ include $(topsrcdir)/config/rules.mk
_CHROME_FILES = \ _CHROME_FILES = \
test_bug396024.xul \ test_bug396024.xul \
bug396024_helper.xul \ bug396024_helper.xul \
test_bug396367-1.html \
test_bug396367-2.html \
test_bug482976.xul \ test_bug482976.xul \
bug482976_helper.xul \ bug482976_helper.xul \
test_bug504311.xul \ test_bug504311.xul \

Просмотреть файл

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=396367
-->
<head>
<title>Test for Bug 396367</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script>
SimpleTest.waitForExplicitFinish();
function finish() {
ok(true, "didn't crash");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396367">Mozilla Bug 396367</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<input>
<script>document.body.setAttribute('style', 'display: -moz-box; overflow: scroll;');</script>
<script>
//netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var navigator1 = top.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebNavigation);
var docShell = navigator1.QueryInterface(Components.interfaces.nsIDocShell);
var docviewer = docShell.contentViewer.QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);
docviewer.textZoom=Math.floor(10*Math.random())/4+0.2;
document.documentElement.offsetHeight;
setTimeout(finish,10);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=396367
-->
<head>
<title>Test for Bug 396367</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<style>select::after { content:"m"; }</style>
<script>
SimpleTest.waitForExplicitFinish();
function finish() {
ok(true, "didn't crash");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396367">Mozilla Bug 396367</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<div style="overflow: scroll; float: left;">
<select></select>
<li style="display: table-cell;">
<script>
//netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var navigator1 = top.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebNavigation);
var docShell = navigator1.QueryInterface(Components.interfaces.nsIDocShell);
var docviewer = docShell.contentViewer.QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);
docviewer.textZoom=Math.floor(10*Math.random())/4+0.2;
document.documentElement.offsetHeight;
setTimeout(finish,10);
</script>
</li>
</div>
</pre>
</body>
</html>