Bug 1021952 - Generate anonymous boxes to preserve proper ruby structure r=bz

This commit is contained in:
Susanna Bowen 2014-07-22 19:08:08 -07:00
parent 4e66a798af
commit 4d501abc1e
4 changed files with 142 additions and 20 deletions

View File

@ -1882,6 +1882,15 @@ nsCSSFrameConstructor::GetParentType(nsIAtom* aFrameType)
if (aFrameType == nsGkAtoms::tableColGroupFrame) {
return eTypeColGroup;
}
if (aFrameType == nsGkAtoms::rubyBaseContainerFrame) {
return eTypeRubyBaseContainer;
}
if (aFrameType == nsGkAtoms::rubyTextContainerFrame) {
return eTypeRubyTextContainer;
}
if (aFrameType == nsGkAtoms::rubyFrame) {
return eTypeRuby;
}
return eTypeBlock;
}
@ -2256,7 +2265,7 @@ NeedFrameFor(const nsFrameConstructorState& aState,
// should be considered ignorable just because they evaluate to
// whitespace.
// We could handle all this in CreateNeededTablePseudos or some other place
// We could handle all this in CreateNeededPseudos or some other place
// after we build our frame construction items, but that would involve
// creating frame construction items for whitespace kids of
// eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
@ -4538,13 +4547,17 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
FCDATA_DECL(FCDATA_IS_LINE_PARTICIPANT,
NS_NewRubyFrame) },
{ NS_STYLE_DISPLAY_RUBY_BASE,
SIMPLE_FCDATA(NS_NewRubyBaseFrame) },
FCDATA_DECL(FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyBaseContainer),
NS_NewRubyBaseFrame) },
{ NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER,
SIMPLE_FCDATA(NS_NewRubyBaseContainerFrame) },
FCDATA_DECL(FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby),
NS_NewRubyBaseContainerFrame) },
{ NS_STYLE_DISPLAY_RUBY_TEXT,
SIMPLE_FCDATA(NS_NewRubyTextFrame) },
FCDATA_DECL(FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyTextContainer),
NS_NewRubyTextFrame) },
{ NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER,
SIMPLE_FCDATA(NS_NewRubyTextContainerFrame)},
FCDATA_DECL(FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby),
NS_NewRubyTextContainerFrame) },
{ NS_STYLE_DISPLAY_TABLE,
FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
{ NS_STYLE_DISPLAY_INLINE_TABLE,
@ -9005,6 +9018,41 @@ nsCSSFrameConstructor::sPseudoParentData[eParentTypeCount] = {
FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS,
&nsCSSFrameConstructor::ConstructTable),
&nsCSSAnonBoxes::table
},
{ // Ruby
FCDATA_DECL(FCDATA_IS_LINE_PARTICIPANT |
FCDATA_USE_CHILD_ITEMS |
FCDATA_SKIP_FRAMESET,
NS_NewRubyFrame),
&nsCSSAnonBoxes::ruby
},
{ // Ruby Base
FCDATA_DECL(FCDATA_USE_CHILD_ITEMS |
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyBaseContainer) |
FCDATA_SKIP_FRAMESET,
NS_NewRubyBaseFrame),
&nsCSSAnonBoxes::rubyBase
},
{ // Ruby Base Container
FCDATA_DECL(FCDATA_USE_CHILD_ITEMS |
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby) |
FCDATA_SKIP_FRAMESET,
NS_NewRubyBaseContainerFrame),
&nsCSSAnonBoxes::rubyBaseContainer
},
{ // Ruby Text
FCDATA_DECL(FCDATA_USE_CHILD_ITEMS |
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyTextContainer) |
FCDATA_SKIP_FRAMESET,
NS_NewRubyTextFrame),
&nsCSSAnonBoxes::rubyText
},
{ // Ruby Text Container
FCDATA_DECL(FCDATA_USE_CHILD_ITEMS |
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby) |
FCDATA_SKIP_FRAMESET,
NS_NewRubyTextContainerFrame),
&nsCSSAnonBoxes::rubyTextContainer
}
};
@ -9137,9 +9185,9 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
* contain only items for frames that can be direct kids of aParentFrame.
*/
void
nsCSSFrameConstructor::CreateNeededTablePseudos(nsFrameConstructorState& aState,
FrameConstructionItemList& aItems,
nsIFrame* aParentFrame)
nsCSSFrameConstructor::CreateNeededPseudos(nsFrameConstructorState& aState,
FrameConstructionItemList& aItems,
nsIFrame* aParentFrame)
{
ParentType ourParentType = GetParentType(aParentFrame);
if (aItems.AllWantParentType(ourParentType)) {
@ -9200,6 +9248,7 @@ nsCSSFrameConstructor::CreateNeededTablePseudos(nsFrameConstructorState& aState,
if ((trailingSpaces && ourParentType != eTypeBlock) ||
(!trailingSpaces && spaceEndIter.item().DesiredParentType() !=
eTypeBlock)) {
//TODO: Add whitespace handling for ruby
bool updateStart = (iter == endIter);
endIter.DeleteItemsTo(spaceEndIter);
NS_ASSERTION(trailingSpaces == endIter.IsDone(), "These should match");
@ -9239,6 +9288,13 @@ nsCSSFrameConstructor::CreateNeededTablePseudos(nsFrameConstructorState& aState,
break;
}
// Don't group ruby base boxes and ruby annotation boxes together
if (ourParentType == eTypeRuby &&
(prevParentType == eTypeRubyTextContainer) !=
(groupingParentType == eTypeRubyTextContainer)) {
break;
}
// Include the whitespace we didn't drop (if any) in the group, since
// this is not the end of the group. Note that this doesn't change
// prevParentType, since if we didn't drop the whitespace then we ended
@ -9258,9 +9314,6 @@ nsCSSFrameConstructor::CreateNeededTablePseudos(nsFrameConstructorState& aState,
// parent type to use depends on ourParentType.
ParentType wrapperType;
switch (ourParentType) {
case eTypeBlock:
wrapperType = eTypeTable;
break;
case eTypeRow:
// The parent type for a cell is eTypeBlock, since that's what a cell
// looks like to its kids.
@ -9274,8 +9327,30 @@ nsCSSFrameConstructor::CreateNeededTablePseudos(nsFrameConstructorState& aState,
wrapperType = groupingParentType == eTypeColGroup ?
eTypeColGroup : eTypeRowGroup;
break;
default:
case eTypeColGroup:
MOZ_CRASH("Colgroups should be suppresing non-col child items");
case eTypeRuby:
if (groupingParentType == eTypeRubyTextContainer) {
wrapperType = eTypeRubyTextContainer;
} else {
wrapperType = eTypeRubyBaseContainer;
}
break;
case eTypeRubyBaseContainer:
wrapperType = eTypeRubyBase;
break;
case eTypeRubyTextContainer:
wrapperType = eTypeRubyText;
break;
default:
NS_ASSERTION(ourParentType == eTypeBlock, "Unrecognized parent type");
if (IsRubyParentType(groupingParentType)) {
wrapperType = eTypeRuby;
} else {
NS_ASSERTION(IsTableParentType(groupingParentType),
"groupingParentType should be either Ruby or table");
wrapperType = eTypeTable;
}
}
const PseudoParentData& pseudoData = sPseudoParentData[wrapperType];
@ -9284,7 +9359,10 @@ nsCSSFrameConstructor::CreateNeededTablePseudos(nsFrameConstructorState& aState,
nsIContent* parentContent = aParentFrame->GetContent();
if (pseudoType == nsCSSAnonBoxes::table &&
parentStyle->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_INLINE) {
(parentStyle->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_INLINE ||
IsRubyParentType(ourParentType) ||
parentStyle->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_RUBY_BASE ||
parentStyle->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_RUBY_TEXT)) {
pseudoType = nsCSSAnonBoxes::inlineTable;
}
@ -9340,7 +9418,7 @@ nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState& aSta
nsContainerFrame* aParentFrame,
nsFrameItems& aFrameItems)
{
CreateNeededTablePseudos(aState, aItems, aParentFrame);
CreateNeededPseudos(aState, aItems, aParentFrame);
CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
aItems.SetTriedConstructingFrames();

View File

@ -415,18 +415,24 @@ private:
nsFrameItems& aFrameItems);
private:
/* An enum of possible parent types for anonymous table object construction */
/* An enum of possible parent types for anonymous table or ruby object
construction */
enum ParentType {
eTypeBlock = 0, /* This includes all non-table-related frames */
eTypeRow,
eTypeRowGroup,
eTypeColGroup,
eTypeTable,
eTypeRuby,
eTypeRubyBase,
eTypeRubyBaseContainer,
eTypeRubyText,
eTypeRubyTextContainer,
eParentTypeCount
};
/* 3 bits is enough to handle our ParentType values */
#define FCDATA_PARENT_TYPE_OFFSET 29
/* 4 bits is enough to handle our ParentType values */
#define FCDATA_PARENT_TYPE_OFFSET 28
/* Macro to get the desired parent type out of an mBits member of
FrameConstructionData */
#define FCDATA_DESIRED_PARENT_TYPE(_bits) \
@ -443,6 +449,21 @@ private:
/* Get the parent type for the given nsIFrame type atom */
static ParentType GetParentType(nsIAtom* aFrameType);
static bool IsRubyParentType(ParentType aParentType) {
return (aParentType == eTypeRuby ||
aParentType == eTypeRubyBase ||
aParentType == eTypeRubyBaseContainer ||
aParentType == eTypeRubyText ||
aParentType == eTypeRubyTextContainer);
}
static bool IsTableParentType(ParentType aParentType) {
return (aParentType == eTypeTable ||
aParentType == eTypeRow ||
aParentType == eTypeRowGroup ||
aParentType == eTypeColGroup);
}
/* A constructor function that just creates an nsIFrame object. The caller
is responsible for initializing the object, adding it to frame lists,
constructing frames for the children, etc.
@ -1041,9 +1062,9 @@ private:
* @param aItems the child frame construction items before pseudo creation
* @param aParentFrame the parent frame we're creating pseudos for
*/
inline void CreateNeededTablePseudos(nsFrameConstructorState& aState,
FrameConstructionItemList& aItems,
nsIFrame* aParentFrame);
inline void CreateNeededPseudos(nsFrameConstructorState& aState,
FrameConstructionItemList& aItems,
nsIFrame* aParentFrame);
/**
* Function to adjust aParentFrame to deal with captions.

View File

@ -70,6 +70,12 @@ CSS_ANON_BOX(anonymousFlexItem, ":-moz-anonymous-flex-item")
// an anonymous block, which is then treated as a grid item.
CSS_ANON_BOX(anonymousGridItem, ":-moz-anonymous-grid-item")
CSS_ANON_BOX(ruby, ":-moz-ruby")
CSS_ANON_BOX(rubyBase, ":-moz-ruby-base")
CSS_ANON_BOX(rubyBaseContainer, ":-moz-ruby-base-container")
CSS_ANON_BOX(rubyText, ":-moz-ruby-text")
CSS_ANON_BOX(rubyTextContainer, ":-moz-ruby-text-container")
#ifdef MOZ_XUL
CSS_ANON_BOX(moztreecolumn, ":-moz-tree-column")
CSS_ANON_BOX(moztreerow, ":-moz-tree-row")

View File

@ -72,6 +72,23 @@
white-space: inherit;
}
/* Ruby */
*|*::-moz-ruby {
display: ruby;
}
*|*::-moz-ruby-base {
display: ruby-base;
}
*|*::-moz-ruby-text {
display: ruby-text;
}
*|*::-moz-ruby-base-container {
display: ruby-base-container;
}
*|*::-moz-ruby-text-container {
display: ruby-text-container;
}
/* Lists */
*|*::-moz-list-bullet, *|*::-moz-list-number {