зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1088489 - Implement ruby pseudo box generation. r=bz
--HG-- extra : rebase_source : 3d722db5a9f896a7083d385e65f0d1d7b694d9e2 extra : source : c7f276c6f764aa28e8b178230f0a9f12372f1db0
This commit is contained in:
Родитель
de448565ef
Коммит
56d367a884
|
@ -9611,6 +9611,248 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
|
||||||
} while (!iter.IsDone());
|
} while (!iter.IsDone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsCSSFrameConstructor::RubyWhitespaceType
|
||||||
|
nsCSSFrameConstructor::ComputeRubyWhitespaceType(uint_fast8_t aPrevDisplay,
|
||||||
|
uint_fast8_t aNextDisplay)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(nsStyleDisplay::IsRubyDisplayType(aPrevDisplay) &&
|
||||||
|
nsStyleDisplay::IsRubyDisplayType(aNextDisplay));
|
||||||
|
if (aPrevDisplay == aNextDisplay &&
|
||||||
|
(aPrevDisplay == NS_STYLE_DISPLAY_RUBY_BASE ||
|
||||||
|
aPrevDisplay == NS_STYLE_DISPLAY_RUBY_TEXT)) {
|
||||||
|
return eRubyInterLeafWhitespace;
|
||||||
|
}
|
||||||
|
if (aNextDisplay == NS_STYLE_DISPLAY_RUBY_TEXT ||
|
||||||
|
aNextDisplay == NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER) {
|
||||||
|
return eRubyInterLevelWhitespace;
|
||||||
|
}
|
||||||
|
return eRubyInterSegmentWhitespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function checks the content from |aStartIter| to |aEndIter|,
|
||||||
|
* determines whether it contains only whitespace, and if yes,
|
||||||
|
* interprets the type of whitespace. This method does not change
|
||||||
|
* any of the iters.
|
||||||
|
*/
|
||||||
|
/* static */ nsCSSFrameConstructor::RubyWhitespaceType
|
||||||
|
nsCSSFrameConstructor::InterpretRubyWhitespace(nsFrameConstructorState& aState,
|
||||||
|
const FCItemIterator& aStartIter,
|
||||||
|
const FCItemIterator& aEndIter)
|
||||||
|
{
|
||||||
|
if (!aStartIter.item().IsWhitespace(aState)) {
|
||||||
|
return eRubyNotWhitespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCItemIterator spaceEndIter(aStartIter);
|
||||||
|
spaceEndIter.SkipWhitespace(aState);
|
||||||
|
if (spaceEndIter != aEndIter) {
|
||||||
|
return eRubyNotWhitespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any leading or trailing whitespace in non-pseudo ruby box
|
||||||
|
// should have been trimmed, hence there should not be any
|
||||||
|
// whitespace at the start or the end.
|
||||||
|
MOZ_ASSERT(!aStartIter.AtStart() && !aEndIter.IsDone());
|
||||||
|
FCItemIterator prevIter(aStartIter);
|
||||||
|
prevIter.Prev();
|
||||||
|
return ComputeRubyWhitespaceType(
|
||||||
|
prevIter.item().mStyleContext->StyleDisplay()->mDisplay,
|
||||||
|
aEndIter.item().mStyleContext->StyleDisplay()->mDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function eats up consecutive items which do not want the current
|
||||||
|
* parent into either a ruby base box or a ruby text box. When it
|
||||||
|
* returns, |aIter| points to the first item it doesn't wrap.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nsCSSFrameConstructor::WrapItemsInPseudoRubyLeafBox(
|
||||||
|
FCItemIterator& aIter,
|
||||||
|
nsStyleContext* aParentStyle, nsIContent* aParentContent)
|
||||||
|
{
|
||||||
|
uint_fast8_t parentDisplay = aParentStyle->StyleDisplay()->mDisplay;
|
||||||
|
ParentType parentType, wrapperType;
|
||||||
|
if (parentDisplay == NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER) {
|
||||||
|
parentType = eTypeRubyTextContainer;
|
||||||
|
wrapperType = eTypeRubyText;
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(parentDisplay == NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER);
|
||||||
|
parentType = eTypeRubyBaseContainer;
|
||||||
|
wrapperType = eTypeRubyBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(aIter.item().DesiredParentType() != parentType,
|
||||||
|
"Should point to something needs to be wrapped.");
|
||||||
|
|
||||||
|
FCItemIterator endIter(aIter);
|
||||||
|
endIter.SkipItemsNotWantingParentType(parentType);
|
||||||
|
|
||||||
|
WrapItemsInPseudoParent(aParentContent, aParentStyle,
|
||||||
|
wrapperType, aIter, endIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function eats up consecutive items into a ruby level container.
|
||||||
|
* It may create zero or one level container. When it returns, |aIter|
|
||||||
|
* points to the first item it doesn't wrap.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nsCSSFrameConstructor::WrapItemsInPseudoRubyLevelContainer(
|
||||||
|
nsFrameConstructorState& aState, FCItemIterator& aIter,
|
||||||
|
nsStyleContext* aParentStyle, nsIContent* aParentContent)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aIter.item().DesiredParentType() != eTypeRuby,
|
||||||
|
"Pointing to a level container?");
|
||||||
|
|
||||||
|
FrameConstructionItem& firstItem = aIter.item();
|
||||||
|
ParentType wrapperType = firstItem.DesiredParentType();
|
||||||
|
if (wrapperType != eTypeRubyTextContainer) {
|
||||||
|
// If the first item is not ruby text,
|
||||||
|
// it should be in a base container.
|
||||||
|
wrapperType = eTypeRubyBaseContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCItemIterator endIter(aIter);
|
||||||
|
do {
|
||||||
|
if (endIter.SkipItemsWantingParentType(wrapperType) ||
|
||||||
|
// If the skipping above stops at some item which wants a
|
||||||
|
// different ruby parent, then we have finished.
|
||||||
|
IsRubyParentType(endIter.item().DesiredParentType())) {
|
||||||
|
// No more items need to be wrapped in this level container.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCItemIterator contentEndIter(endIter);
|
||||||
|
contentEndIter.SkipItemsNotWantingRubyParent();
|
||||||
|
// endIter must be on something doesn't want a ruby parent.
|
||||||
|
MOZ_ASSERT(contentEndIter != endIter);
|
||||||
|
|
||||||
|
// InterpretRubyWhitespace depends on the fact that any leading or
|
||||||
|
// trailing whitespace described in the spec have been trimmed at
|
||||||
|
// this point. With this precondition, it is safe not to check
|
||||||
|
// whether contentEndIter has been done.
|
||||||
|
RubyWhitespaceType whitespaceType =
|
||||||
|
InterpretRubyWhitespace(aState, endIter, contentEndIter);
|
||||||
|
if (whitespaceType == eRubyInterLevelWhitespace) {
|
||||||
|
// Remove inter-level whitespace.
|
||||||
|
bool atStart = (aIter == endIter);
|
||||||
|
endIter.DeleteItemsTo(contentEndIter);
|
||||||
|
if (atStart) {
|
||||||
|
aIter = endIter;
|
||||||
|
}
|
||||||
|
} else if (whitespaceType == eRubyInterSegmentWhitespace) {
|
||||||
|
// If this level container starts with inter-segment whitespaces,
|
||||||
|
// wrap them. Break at contentEndIter. Otherwise, leave it here.
|
||||||
|
// Break at endIter. They will be wrapped when we are here again.
|
||||||
|
if (aIter == endIter) {
|
||||||
|
MOZ_ASSERT(wrapperType == eTypeRubyBaseContainer,
|
||||||
|
"Inter-segment whitespace should be wrapped in rbc");
|
||||||
|
endIter = contentEndIter;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (wrapperType == eTypeRubyTextContainer &&
|
||||||
|
whitespaceType != eRubyInterLeafWhitespace) {
|
||||||
|
// Misparented inline content that's not inter-annotation
|
||||||
|
// whitespace doesn't belong in a pseudo ruby text container.
|
||||||
|
// Break at endIter.
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
endIter = contentEndIter;
|
||||||
|
}
|
||||||
|
} while (!endIter.IsDone());
|
||||||
|
|
||||||
|
// It is possible that everything our parent wants us to wrap is
|
||||||
|
// simply an inter-level whitespace, which has been trimmed, or
|
||||||
|
// an inter-segment whitespace, which will be wrapped later.
|
||||||
|
// In those cases, don't create anything.
|
||||||
|
if (aIter != endIter) {
|
||||||
|
WrapItemsInPseudoParent(aParentContent, aParentStyle,
|
||||||
|
wrapperType, aIter, endIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function trims leading and trailing whitespaces
|
||||||
|
* in the given item list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nsCSSFrameConstructor::TrimLeadingAndTrailingWhitespaces(
|
||||||
|
nsFrameConstructorState& aState,
|
||||||
|
FrameConstructionItemList& aItems)
|
||||||
|
{
|
||||||
|
FCItemIterator iter(aItems);
|
||||||
|
if (!iter.IsDone() &&
|
||||||
|
iter.item().IsWhitespace(aState)) {
|
||||||
|
FCItemIterator spaceEndIter(iter);
|
||||||
|
spaceEndIter.SkipWhitespace(aState);
|
||||||
|
iter.DeleteItemsTo(spaceEndIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter.SetToEnd();
|
||||||
|
if (!iter.AtStart()) {
|
||||||
|
FCItemIterator spaceEndIter(iter);
|
||||||
|
do {
|
||||||
|
iter.Prev();
|
||||||
|
if (iter.AtStart()) {
|
||||||
|
// It's fine to not check the first item, because we
|
||||||
|
// should have trimmed leading whitespaces above.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (iter.item().IsWhitespace(aState));
|
||||||
|
iter.Next();
|
||||||
|
if (iter != spaceEndIter) {
|
||||||
|
iter.DeleteItemsTo(spaceEndIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function walks through the child list (aItems) and creates
|
||||||
|
* needed pseudo ruby boxes to wrap misparented children.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nsCSSFrameConstructor::CreateNeededPseudoInternalRubyBoxes(
|
||||||
|
nsFrameConstructorState& aState,
|
||||||
|
FrameConstructionItemList& aItems,
|
||||||
|
nsIFrame* aParentFrame)
|
||||||
|
{
|
||||||
|
const ParentType ourParentType = GetParentType(aParentFrame);
|
||||||
|
if (!IsRubyParentType(ourParentType) ||
|
||||||
|
aItems.AllWantParentType(ourParentType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleContext* parentStyle = aParentFrame->StyleContext();
|
||||||
|
if (!parentStyle->GetPseudo()) {
|
||||||
|
// Normally, pseudo frames start from and end at some elements,
|
||||||
|
// which means they don't have leading and trailing whitespaces at
|
||||||
|
// all. But there are two cases where they do actually have leading
|
||||||
|
// or trailing whitespaces:
|
||||||
|
// 1. It is an inter-segment whitespace which in an individual ruby
|
||||||
|
// base container.
|
||||||
|
// 2. The pseudo frame starts from or ends at consecutive inline
|
||||||
|
// content, which is not pure whitespace, but includes some.
|
||||||
|
// In either case, the whitespaces are not the leading or trailing
|
||||||
|
// whitespaces defined in the spec, and thus should not be trimmed.
|
||||||
|
TrimLeadingAndTrailingWhitespaces(aState, aItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
FCItemIterator iter(aItems);
|
||||||
|
nsIContent* parentContent = aParentFrame->GetContent();
|
||||||
|
while (!iter.IsDone()) {
|
||||||
|
if (!iter.SkipItemsWantingParentType(ourParentType)) {
|
||||||
|
if (ourParentType == eTypeRuby) {
|
||||||
|
WrapItemsInPseudoRubyLevelContainer(aState, iter, parentStyle,
|
||||||
|
parentContent);
|
||||||
|
} else {
|
||||||
|
WrapItemsInPseudoRubyLeafBox(iter, parentStyle, parentContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function works as follows: we walk through the child list (aItems) and
|
* This function works as follows: we walk through the child list (aItems) and
|
||||||
* find items that cannot have aParentFrame as their parent. We wrap
|
* find items that cannot have aParentFrame as their parent. We wrap
|
||||||
|
@ -9629,7 +9871,8 @@ nsCSSFrameConstructor::CreateNeededPseudoContainers(
|
||||||
nsIFrame* aParentFrame)
|
nsIFrame* aParentFrame)
|
||||||
{
|
{
|
||||||
ParentType ourParentType = GetParentType(aParentFrame);
|
ParentType ourParentType = GetParentType(aParentFrame);
|
||||||
if (aItems.AllWantParentType(ourParentType)) {
|
if (IsRubyParentType(ourParentType) ||
|
||||||
|
aItems.AllWantParentType(ourParentType)) {
|
||||||
// Nothing to do here
|
// Nothing to do here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -9678,70 +9921,18 @@ nsCSSFrameConstructor::CreateNeededPseudoContainers(
|
||||||
!aParentFrame->IsGeneratedContentFrame() &&
|
!aParentFrame->IsGeneratedContentFrame() &&
|
||||||
spaceEndIter.item().IsWhitespace(aState)) {
|
spaceEndIter.item().IsWhitespace(aState)) {
|
||||||
bool trailingSpaces = spaceEndIter.SkipWhitespace(aState);
|
bool trailingSpaces = spaceEndIter.SkipWhitespace(aState);
|
||||||
int nextDisplay = -1;
|
|
||||||
int prevDisplay = -1;
|
|
||||||
|
|
||||||
if (!endIter.AtStart() &&
|
|
||||||
(IsRubyParentType(ourParentType) ||
|
|
||||||
IsRubyParentType(groupingParentType))) {
|
|
||||||
FCItemIterator prevItemIter(endIter);
|
|
||||||
prevItemIter.Prev();
|
|
||||||
prevDisplay =
|
|
||||||
prevItemIter.item().mStyleContext->StyleDisplay()->mDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only need to compute nextDisplay for testing for ruby white
|
|
||||||
// space.
|
|
||||||
if (!spaceEndIter.IsDone() &&
|
|
||||||
(IsRubyParentType(ourParentType) ||
|
|
||||||
IsRubyParentType(groupingParentType))) {
|
|
||||||
nextDisplay =
|
|
||||||
spaceEndIter.item().mStyleContext->StyleDisplay()->mDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ourParentType == eTypeRubyBaseContainer &&
|
|
||||||
prevDisplay == -1 && nextDisplay == -1) {
|
|
||||||
if (aParentFrame->StyleContext()->GetPseudo()) {
|
|
||||||
// We are in a pseudo ruby base container, which has
|
|
||||||
// whitespaces only. This is a special case to handle
|
|
||||||
// inter-segment spaces.
|
|
||||||
endIter = spaceEndIter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We drop the whitespace in the following cases:
|
// We drop the whitespace in the following cases:
|
||||||
// 1) If these are not trailing spaces and the next item wants a table
|
// 1) If these are not trailing spaces and the next item wants a table
|
||||||
// or table-part parent
|
// or table-part parent
|
||||||
// 2) If these are trailing spaces and aParentFrame is a
|
// 2) If these are trailing spaces and aParentFrame is a
|
||||||
// tabular container according to rule 1.3 of CSS 2.1 Sec 17.2.1.
|
// tabular container according to rule 1.3 of CSS 2.1 Sec 17.2.1.
|
||||||
// (Being a tabular container pretty much means
|
// (Being a tabular container pretty much means ourParentType is
|
||||||
// IsTableParentType(ourParentType) besides the eTypeColGroup case,
|
// not eTypeBlock besides the eTypeColGroup case, which won't
|
||||||
// which won't reach here.)
|
// reach here.)
|
||||||
// 3) The whitespace is leading or trailing inside a ruby box, ruby
|
|
||||||
// base container box, or ruby text container box.
|
|
||||||
// 4) The whitespace is classified as inter-level intra-ruby
|
|
||||||
// whitespace according to the spec for CSS ruby.
|
|
||||||
bool isRubyLeadingTrailingParentType =
|
|
||||||
ourParentType == eTypeRuby ||
|
|
||||||
ourParentType == eTypeRubyBaseContainer ||
|
|
||||||
ourParentType == eTypeRubyTextContainer;
|
|
||||||
bool isRubyLeading =
|
|
||||||
prevDisplay == -1 && isRubyLeadingTrailingParentType;
|
|
||||||
bool isRubyTrailing =
|
|
||||||
nextDisplay == -1 && isRubyLeadingTrailingParentType;
|
|
||||||
// There's an implicit condition that we are in a ruby parent or
|
|
||||||
// we are grouping a ruby parent here, because nextDisplay and
|
|
||||||
// prevDisplay are only set if that is true.
|
|
||||||
bool isRubyInterLevel =
|
|
||||||
(nextDisplay == NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER) ||
|
|
||||||
(nextDisplay == NS_STYLE_DISPLAY_RUBY_TEXT &&
|
|
||||||
prevDisplay != NS_STYLE_DISPLAY_RUBY_TEXT);
|
|
||||||
|
|
||||||
if ((!trailingSpaces &&
|
if ((!trailingSpaces &&
|
||||||
IsTableParentType(spaceEndIter.item().DesiredParentType())) ||
|
IsTableParentType(spaceEndIter.item().DesiredParentType())) ||
|
||||||
(trailingSpaces && IsTableParentType(ourParentType)) ||
|
(trailingSpaces && ourParentType != eTypeBlock)) {
|
||||||
isRubyLeading || isRubyTrailing || isRubyInterLevel) {
|
|
||||||
bool updateStart = (iter == endIter);
|
bool updateStart = (iter == endIter);
|
||||||
endIter.DeleteItemsTo(spaceEndIter);
|
endIter.DeleteItemsTo(spaceEndIter);
|
||||||
NS_ASSERTION(trailingSpaces == endIter.IsDone(),
|
NS_ASSERTION(trailingSpaces == endIter.IsDone(),
|
||||||
|
@ -9770,23 +9961,16 @@ nsCSSFrameConstructor::CreateNeededPseudoContainers(
|
||||||
// what it means that this is the group end), so it's OK.
|
// what it means that this is the group end), so it's OK.
|
||||||
// However, when we are grouping a ruby parent, and endIter points to
|
// However, when we are grouping a ruby parent, and endIter points to
|
||||||
// a non-droppable whitespace, if the next non-whitespace item also
|
// a non-droppable whitespace, if the next non-whitespace item also
|
||||||
// wants a ruby parent which is not our parent, the whitespace should
|
// wants a ruby parent, the whitespace should also be included into
|
||||||
// also be included into the current ruby parent.
|
// the current ruby container.
|
||||||
prevParentType = endIter.item().DesiredParentType();
|
prevParentType = endIter.item().DesiredParentType();
|
||||||
if (prevParentType == ourParentType) {
|
if (prevParentType == ourParentType &&
|
||||||
if (endIter == spaceEndIter ||
|
(endIter == spaceEndIter ||
|
||||||
// not grouping a ruby parent
|
spaceEndIter.IsDone() ||
|
||||||
!IsRubyParentType(groupingParentType) ||
|
!IsRubyParentType(groupingParentType) ||
|
||||||
spaceEndIter.IsDone()) {
|
!IsRubyParentType(spaceEndIter.item().DesiredParentType()))) {
|
||||||
// End the group at endIter.
|
// End the group at endIter.
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
ParentType nextParentType = spaceEndIter.item().DesiredParentType();
|
|
||||||
if (nextParentType == ourParentType ||
|
|
||||||
!IsRubyParentType(nextParentType)) {
|
|
||||||
// End the group at endIter.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ourParentType == eTypeTable &&
|
if (ourParentType == eTypeTable &&
|
||||||
|
@ -9797,31 +9981,6 @@ nsCSSFrameConstructor::CreateNeededPseudoContainers(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Break from the boundary between a ruby base container and a
|
|
||||||
// ruby text container, or the boundary between an inter-segment
|
|
||||||
// whitespace and the next ruby segment.
|
|
||||||
if (ourParentType == eTypeRuby) {
|
|
||||||
if ((prevParentType == eTypeRubyBaseContainer &&
|
|
||||||
groupingParentType == eTypeRubyTextContainer) ||
|
|
||||||
(prevParentType == eTypeRubyTextContainer &&
|
|
||||||
groupingParentType == eTypeRubyBaseContainer)) {
|
|
||||||
// Don't group ruby base boxes and
|
|
||||||
// ruby annotation boxes together.
|
|
||||||
break;
|
|
||||||
} else if (groupingParentType == eTypeBlock &&
|
|
||||||
endIter != spaceEndIter) {
|
|
||||||
// We are on inter-segment whitespaces, which we want to
|
|
||||||
// create an independent ruby base container for.
|
|
||||||
endIter = spaceEndIter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// The only case where prevParentType is different from
|
|
||||||
// groupingParentType but we still want to continue, is that
|
|
||||||
// we are on an inter-base or inter-annotation whitespace.
|
|
||||||
MOZ_ASSERT(groupingParentType == prevParentType ||
|
|
||||||
prevParentType == eTypeBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have some whitespace that we were not able to drop and there is
|
// If we have some whitespace that we were not able to drop and there is
|
||||||
// an item after the whitespace that is already properly parented, then
|
// an item after the whitespace that is already properly parented, then
|
||||||
// make sure to include the spaces in our group but stop the group after
|
// make sure to include the spaces in our group but stop the group after
|
||||||
|
@ -9865,23 +10024,6 @@ nsCSSFrameConstructor::CreateNeededPseudoContainers(
|
||||||
break;
|
break;
|
||||||
case eTypeColGroup:
|
case eTypeColGroup:
|
||||||
MOZ_CRASH("Colgroups should be suppresing non-col child items");
|
MOZ_CRASH("Colgroups should be suppresing non-col child items");
|
||||||
case eTypeRuby:
|
|
||||||
if (groupingParentType == eTypeRubyTextContainer) {
|
|
||||||
wrapperType = eTypeRubyTextContainer;
|
|
||||||
} else {
|
|
||||||
NS_ASSERTION(groupingParentType == eTypeRubyBaseContainer ||
|
|
||||||
groupingParentType == eTypeBlock,
|
|
||||||
"It should be either a ruby base container, "
|
|
||||||
"or an inter-segment whitespace");
|
|
||||||
wrapperType = eTypeRubyBaseContainer;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case eTypeRubyBaseContainer:
|
|
||||||
wrapperType = eTypeRubyBase;
|
|
||||||
break;
|
|
||||||
case eTypeRubyTextContainer:
|
|
||||||
wrapperType = eTypeRubyText;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
NS_ASSERTION(ourParentType == eTypeBlock, "Unrecognized parent type");
|
NS_ASSERTION(ourParentType == eTypeBlock, "Unrecognized parent type");
|
||||||
if (IsRubyParentType(groupingParentType)) {
|
if (IsRubyParentType(groupingParentType)) {
|
||||||
|
@ -10015,6 +10157,7 @@ nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState& aSta
|
||||||
{
|
{
|
||||||
CreateNeededPseudoContainers(aState, aItems, aParentFrame);
|
CreateNeededPseudoContainers(aState, aItems, aParentFrame);
|
||||||
CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
|
CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
|
||||||
|
CreateNeededPseudoInternalRubyBoxes(aState, aItems, aParentFrame);
|
||||||
CreateNeededPseudoSiblings(aState, aItems, aParentFrame);
|
CreateNeededPseudoSiblings(aState, aItems, aParentFrame);
|
||||||
|
|
||||||
aItems.SetTriedConstructingFrames();
|
aItems.SetTriedConstructingFrames();
|
||||||
|
@ -12058,6 +12201,20 @@ Iterator::SkipItemsWantingParentType(ParentType aParentType)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
nsCSSFrameConstructor::FrameConstructionItemList::
|
||||||
|
Iterator::SkipItemsNotWantingParentType(ParentType aParentType)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
|
||||||
|
while (item().DesiredParentType() != aParentType) {
|
||||||
|
Next();
|
||||||
|
if (IsDone()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsCSSFrameConstructor::FrameConstructionItem::
|
nsCSSFrameConstructor::FrameConstructionItem::
|
||||||
NeedsAnonFlexOrGridItem(const nsFrameConstructorState& aState)
|
NeedsAnonFlexOrGridItem(const nsFrameConstructorState& aState)
|
||||||
|
@ -12109,6 +12266,20 @@ Iterator::SkipItemsThatDontNeedAnonFlexOrGridItem(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
nsCSSFrameConstructor::FrameConstructionItemList::
|
||||||
|
Iterator::SkipItemsNotWantingRubyParent()
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
|
||||||
|
while (!IsRubyParentType(item().DesiredParentType())) {
|
||||||
|
Next();
|
||||||
|
if (IsDone()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
nsCSSFrameConstructor::FrameConstructionItemList::
|
nsCSSFrameConstructor::FrameConstructionItemList::
|
||||||
Iterator::SkipWhitespace(nsFrameConstructorState& aState)
|
Iterator::SkipWhitespace(nsFrameConstructorState& aState)
|
||||||
|
|
|
@ -919,10 +919,15 @@ private:
|
||||||
}
|
}
|
||||||
void SetToEnd() { mCurrent = mEnd; }
|
void SetToEnd() { mCurrent = mEnd; }
|
||||||
|
|
||||||
|
// Skip over all items that want the given parent type. Return whether
|
||||||
|
// the iterator is done after doing that. The iterator must not be done
|
||||||
|
// when this is called.
|
||||||
|
inline bool SkipItemsWantingParentType(ParentType aParentType);
|
||||||
|
|
||||||
// Skip over all items that want a parent type different from the given
|
// Skip over all items that want a parent type different from the given
|
||||||
// one. Return whether the iterator is done after doing that. The
|
// one. Return whether the iterator is done after doing that. The
|
||||||
// iterator must not be done when this is called.
|
// iterator must not be done when this is called.
|
||||||
inline bool SkipItemsWantingParentType(ParentType aParentType);
|
inline bool SkipItemsNotWantingParentType(ParentType aParentType);
|
||||||
|
|
||||||
// Skip over non-replaced inline frames and positioned frames.
|
// Skip over non-replaced inline frames and positioned frames.
|
||||||
// Return whether the iterator is done after doing that.
|
// Return whether the iterator is done after doing that.
|
||||||
|
@ -936,6 +941,11 @@ private:
|
||||||
inline bool SkipItemsThatDontNeedAnonFlexOrGridItem(
|
inline bool SkipItemsThatDontNeedAnonFlexOrGridItem(
|
||||||
const nsFrameConstructorState& aState);
|
const nsFrameConstructorState& aState);
|
||||||
|
|
||||||
|
// Skip over all items that do not want a ruby parent. Return whether
|
||||||
|
// the iterator is done after doing that. The iterator must not be done
|
||||||
|
// when this is called.
|
||||||
|
inline bool SkipItemsNotWantingRubyParent();
|
||||||
|
|
||||||
// Skip over whitespace. Return whether the iterator is done after doing
|
// Skip over whitespace. Return whether the iterator is done after doing
|
||||||
// that. The iterator must not be done, and must be pointing to a
|
// that. The iterator must not be done, and must be pointing to a
|
||||||
// whitespace item when this is called.
|
// whitespace item when this is called.
|
||||||
|
@ -1166,6 +1176,59 @@ private:
|
||||||
FrameConstructionItemList& aItems,
|
FrameConstructionItemList& aItems,
|
||||||
nsIFrame* aParentFrame);
|
nsIFrame* aParentFrame);
|
||||||
|
|
||||||
|
enum RubyWhitespaceType
|
||||||
|
{
|
||||||
|
eRubyNotWhitespace,
|
||||||
|
eRubyInterLevelWhitespace,
|
||||||
|
// Includes inter-base and inter-annotation whitespace
|
||||||
|
eRubyInterLeafWhitespace,
|
||||||
|
eRubyInterSegmentWhitespace
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to compute the whitespace type according to the display
|
||||||
|
* values of the previous and the next elements.
|
||||||
|
*/
|
||||||
|
static inline RubyWhitespaceType ComputeRubyWhitespaceType(
|
||||||
|
uint_fast8_t aPrevDisplay, uint_fast8_t aNextDisplay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to interpret the type of whitespace between
|
||||||
|
* |aStartIter| and |aEndIter|.
|
||||||
|
*/
|
||||||
|
static inline RubyWhitespaceType InterpretRubyWhitespace(
|
||||||
|
nsFrameConstructorState& aState,
|
||||||
|
const FCItemIterator& aStartIter, const FCItemIterator& aEndIter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to wrap consecutive misparented inline content into
|
||||||
|
* a ruby base box or a ruby text box.
|
||||||
|
*/
|
||||||
|
void WrapItemsInPseudoRubyLeafBox(FCItemIterator& aIter,
|
||||||
|
nsStyleContext* aParentStyle,
|
||||||
|
nsIContent* aParentContent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to wrap consecutive misparented items
|
||||||
|
* into a ruby level container.
|
||||||
|
*/
|
||||||
|
inline void WrapItemsInPseudoRubyLevelContainer(
|
||||||
|
nsFrameConstructorState& aState, FCItemIterator& aIter,
|
||||||
|
nsStyleContext* aParentStyle, nsIContent* aParentContent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to trim leading and trailing whitespaces.
|
||||||
|
*/
|
||||||
|
inline void TrimLeadingAndTrailingWhitespaces(
|
||||||
|
nsFrameConstructorState& aState, FrameConstructionItemList& aItems);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to create internal ruby boxes.
|
||||||
|
*/
|
||||||
|
inline void CreateNeededPseudoInternalRubyBoxes(
|
||||||
|
nsFrameConstructorState& aState,
|
||||||
|
FrameConstructionItemList& aItems, nsIFrame* aParentFrame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to create the pseudo intermediate containers we need.
|
* Function to create the pseudo intermediate containers we need.
|
||||||
* @param aItems the child frame construction items before pseudo creation
|
* @param aItems the child frame construction items before pseudo creation
|
||||||
|
|
Загрузка…
Ссылка в новой задаче