Bug 866588 - Check that the frame IsBidiSplittable before changing a fluid continuation to non-fluid. r=smontagu
authorMats Palmgren <matspal@gmail.com>
Tue, 30 Apr 2013 12:37:07 +0200
changeset 130323 1b5ab2426f16ff3b4f58b9cc07ae4278d1dc4611
parent 130322 1f73f3b8a2449ec6c142826f01d453f057573d7d
child 130324 2aed3055baf607398585cdb178b587a1046b5886
push id24611
push userryanvm@gmail.com
push dateTue, 30 Apr 2013 17:34:15 +0000
treeherdermozilla-central@45c053246b2a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmontagu
bugs866588
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 866588 - Check that the frame IsBidiSplittable before changing a fluid continuation to non-fluid. r=smontagu
layout/base/crashtests/866588.html
layout/base/crashtests/crashtests.list
layout/base/nsBidiPresUtils.cpp
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/866588.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<style>
+
+body { white-space: pre-wrap; width: 1ch; font-family: monospace }
+body:first-line { }
+
+</style>
+
+<script>
+
+function boom()
+{
+  document.body.textContent = "\n\u202AX ";
+  document.documentElement.offsetHeight;
+  document.body.appendChild(document.createTextNode("Y"));
+  document.documentElement.offsetHeight;
+}
+
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -390,8 +390,9 @@ load 763223-1.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) load 763702.xhtml
 load 770381-1.html
 load 795646.html
 load 813372-1.html
 load 836990-1.html
 load 860579-1.html
 pref(layers.force-active,true) load 859526-1.html
 pref(layers.force-active,true) load 859630-1.html
+load 866588.html
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -389,18 +389,20 @@ struct BidiLineData {
 
 /* Some helper methods for Resolve() */
 
 // Should this frame be split between text runs?
 static bool
 IsBidiSplittable(nsIFrame* aFrame)
 {
   // Bidi inline containers should be split, unless they're line frames.
-  return aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer)
-    && aFrame->GetType() != nsGkAtoms::lineFrame;
+  nsIAtom* frameType = aFrame->GetType();
+  return (aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer) &&
+          frameType != nsGkAtoms::lineFrame) ||
+         frameType == nsGkAtoms::textFrame;
 }
 
 // Should this frame be treated as a leaf (e.g. when building mLogicalFrames)?
 static bool
 IsBidiLeaf(nsIFrame* aFrame)
 {
   nsIFrame* kid = aFrame->GetFirstPrincipalChild();
   return !kid || !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer);
@@ -809,18 +811,17 @@ nsBidiPresUtils::ResolveParagraph(nsBloc
              */
             nsIFrame* next = frame->GetNextInFlow();
             if (next) {
               nsIFrame* parent = frame;
               nsIFrame* nextParent = next;
               while (parent && nextParent) {
                 if (parent == nextParent ||
                     nextParent != parent->GetNextInFlow() ||
-                    !parent->IsFrameOfType(nsIFrame::eLineParticipant) ||
-                    !nextParent->IsFrameOfType(nsIFrame::eLineParticipant)) {
+                    !IsBidiSplittable(parent)) {
                   break;
                 }
                 parent->SetNextContinuation(nextParent);
                 nextParent->SetPrevContinuation(parent);
 
                 parent = parent->GetParent();
                 nextParent = nextParent->GetParent();
               }
@@ -1601,17 +1602,17 @@ nsBidiPresUtils::RemoveBidiContinuation(
     }
   }
 
   // Make sure that the last continuation we made fluid does not itself have a
   // fluid continuation (this can happen when re-resolving after dynamic changes
   // to content)
   nsIFrame* lastFrame = aBpd->FrameAt(aLastIndex);
   nsIFrame* next = lastFrame->GetNextInFlow();
-  if (next) {
+  if (next && IsBidiSplittable(lastFrame)) {
     lastFrame->SetNextContinuation(next);
     next->SetPrevContinuation(lastFrame);
   }
 }
 
 nsresult
 nsBidiPresUtils::FormatUnicodeText(nsPresContext*  aPresContext,
                                    PRUnichar*       aText,