Bug 1233135 - Do not touch display value of anonymous box for ruby.
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1860,23 +1860,17 @@ IsTablePseudo(nsIFrame* aFrame)
nsCSSAnonBoxes::table ||
aFrame->GetFirstPrincipalChild()->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::inlineTable)));
}
static bool
IsRubyPseudo(nsIFrame* aFrame)
{
- nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo();
- return pseudoType &&
- (pseudoType == nsCSSAnonBoxes::ruby ||
- pseudoType == nsCSSAnonBoxes::rubyBase ||
- pseudoType == nsCSSAnonBoxes::rubyText ||
- pseudoType == nsCSSAnonBoxes::rubyBaseContainer ||
- pseudoType == nsCSSAnonBoxes::rubyTextContainer);
+ return RubyUtils::IsRubyPseudo(aFrame->StyleContext()->GetPseudo());
}
static bool
IsTableOrRubyPseudo(nsIFrame* aFrame)
{
return IsTablePseudo(aFrame) || IsRubyPseudo(aFrame);
}
--- a/layout/generic/RubyUtils.h
+++ b/layout/generic/RubyUtils.h
@@ -4,16 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_RubyUtils_h_
#define mozilla_RubyUtils_h_
#include "nsTArray.h"
#include "nsGkAtoms.h"
+#include "nsCSSAnonBoxes.h"
#define RTC_ARRAY_SIZE 1
class nsRubyFrame;
class nsRubyBaseFrame;
class nsRubyTextFrame;
class nsRubyContentFrame;
class nsRubyBaseContainerFrame;
@@ -72,16 +73,25 @@ public:
}
static inline bool IsExpandableRubyBox(nsIFrame* aFrame)
{
nsIAtom* type = aFrame->GetType();
return IsRubyContentBox(type) || IsRubyContainerBox(type);
}
+ static inline bool IsRubyPseudo(nsIAtom* aPseudo)
+ {
+ return aPseudo == nsCSSAnonBoxes::ruby ||
+ aPseudo == nsCSSAnonBoxes::rubyBase ||
+ aPseudo == nsCSSAnonBoxes::rubyText ||
+ aPseudo == nsCSSAnonBoxes::rubyBaseContainer ||
+ aPseudo == nsCSSAnonBoxes::rubyTextContainer;
+ }
+
static void SetReservedISize(nsIFrame* aFrame, nscoord aISize);
static void ClearReservedISize(nsIFrame* aFrame);
static nscoord GetReservedISize(nsIFrame* aFrame);
};
/**
* This array stores all ruby text containers of the ruby segment
* of the given ruby base container.
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1233135-1.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+ fieldset, input, select {
+ display: ruby;
+ }
+</style>
+<fieldset></fieldset>
+<input type="color">
+<input type="file">
+<input type="number">
+<input type="range">
+<select></select>
+<select size="2"></select>
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1233135-2.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<ruby>
+ <fieldset></fieldset>
+ <input type="color">
+ <input type="file">
+ <input type="number">
+ <input type="range">
+ <select></select>
+ <select size="2"></select>
+ <span style="display: block; overflow: scroll"></span>
+</ruby>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -128,13 +128,15 @@ load 1167782-1.html
load 1186768-1.xhtml
load 1200568-1.html
load 1206105-1.html
load 1223688-1.html
load 1223694-1.html
load 1226400-1.html
load 1227501-1.html
load 1230408-1.html
+load 1233135-1.html
+load 1233135-2.html
load 1238660-1.html
load border-image-visited-link.html
load font-face-truncated-src.html
load large_border_image_width.html
load long-url-list-stack-overflow.html
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -19,16 +19,17 @@
#include "nsIPresShell.h"
#include "nsRuleNode.h"
#include "nsStyleContext.h"
#include "mozilla/StyleAnimationValue.h"
#include "GeckoProfiler.h"
#include "nsIDocument.h"
#include "nsPrintfCString.h"
+#include "RubyUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/ArenaObjectID.h"
#ifdef DEBUG
// #define NOISY_DEBUG
#endif
using namespace mozilla;
@@ -506,22 +507,33 @@ nsStyleContext::SetStyle(nsStyleStructID
dataSlot = &mCachedInheritedData.mStyleStructs[aSID];
}
NS_ASSERTION(!*dataSlot || (mBits & nsCachedStyleData::GetBitForSID(aSID)),
"Going to leak style data");
*dataSlot = aStruct;
}
static bool
-ShouldSuppressLineBreak(const nsStyleDisplay* aStyleDisplay,
+ShouldSuppressLineBreak(const nsStyleContext* aContext,
+ const nsStyleDisplay* aDisplay,
const nsStyleContext* aParentContext,
const nsStyleDisplay* aParentDisplay)
{
// The display change should only occur for "in-flow" children
- if (aStyleDisplay->IsOutOfFlowStyle()) {
+ if (aDisplay->IsOutOfFlowStyle()) {
+ return false;
+ }
+ // Display value of any anonymous box should not be touched. In most
+ // cases, anonymous boxes are actually not in ruby frame, but instead,
+ // some other frame with a ruby display value. Non-element pseudos
+ // which represents text frames, as well as ruby pseudos are excluded
+ // because we still want to set the flag for them.
+ if (aContext->GetPseudoType() == nsCSSPseudoElements::ePseudo_AnonBox &&
+ aContext->GetPseudo() != nsCSSAnonBoxes::mozNonElement &&
+ !RubyUtils::IsRubyPseudo(aContext->GetPseudo())) {
return false;
}
if (aParentContext->ShouldSuppressLineBreak()) {
// Line break suppressing bit is propagated to any children of
// line participants, which include inline, contents, and inline
// ruby boxes.
if (aParentDisplay->mDisplay == NS_STYLE_DISPLAY_INLINE ||
aParentDisplay->mDisplay == NS_STYLE_DISPLAY_CONTENTS ||
@@ -545,22 +557,22 @@ ShouldSuppressLineBreak(const nsStyleDis
// any, won't be able to break the line its ruby ancestor lays; and
// 3. their parent frame is always a ruby content frame (due to
// anonymous ruby box generation), which makes line layout suppress
// any optional line break around this frame.
// However, there is one special case which is BR tag, because it
// directly affects the line layout. This case is handled by the BR
// frame which checks the flag of its parent frame instead of itself.
if ((aParentDisplay->IsRubyDisplayType() &&
- aStyleDisplay->mDisplay != NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER &&
- aStyleDisplay->mDisplay != NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER) ||
+ aDisplay->mDisplay != NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER &&
+ aDisplay->mDisplay != NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER) ||
// Since ruby base and ruby text may exist themselves without any
// non-anonymous frame outside, we should also check them.
- aStyleDisplay->mDisplay == NS_STYLE_DISPLAY_RUBY_BASE ||
- aStyleDisplay->mDisplay == NS_STYLE_DISPLAY_RUBY_TEXT) {
+ aDisplay->mDisplay == NS_STYLE_DISPLAY_RUBY_BASE ||
+ aDisplay->mDisplay == NS_STYLE_DISPLAY_RUBY_TEXT) {
return true;
}
return false;
}
void
nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup)
{
@@ -709,17 +721,17 @@ nsStyleContext::ApplyStyleFixups(bool aS
}
// Set the NS_STYLE_IN_DISPLAY_NONE_SUBTREE bit
if ((mParent && mParent->IsInDisplayNoneSubtree()) ||
disp->mDisplay == NS_STYLE_DISPLAY_NONE) {
mBits |= NS_STYLE_IN_DISPLAY_NONE_SUBTREE;
}
- if (mParent && ::ShouldSuppressLineBreak(disp, mParent,
+ if (mParent && ::ShouldSuppressLineBreak(this, disp, mParent,
mParent->StyleDisplay())) {
mBits |= NS_STYLE_SUPPRESS_LINEBREAK;
uint8_t displayVal = disp->mDisplay;
nsRuleNode::EnsureInlineDisplay(displayVal);
if (displayVal != disp->mDisplay) {
nsStyleDisplay* mutable_display =
static_cast<nsStyleDisplay*>(GetUniqueStyleData(eStyleStruct_Display));
disp = mutable_display;