Bug 1083004 - Create anonymous ruby base container when necessary. r=bz
authorXidorn Quan <quanxunzhen@gmail.com>
Wed, 26 Nov 2014 15:52:07 +1100
changeset 217613 1ff07cb9adaf44b95e81bdc26e07de6bc1b69237
parent 217612 8bd4630ddd4547632761d5f3f7b8c90c6fd91e65
child 217614 0a32c681cb05e63fd6158f64aeb5a9cf52f4520e
push id10183
push userryanvm@gmail.com
push dateThu, 27 Nov 2014 02:44:16 +0000
treeherderfx-team@679466398b30 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1083004
milestone36.0a1
Bug 1083004 - Create anonymous ruby base container when necessary. r=bz
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2253,18 +2253,18 @@ NeedFrameFor(const nsFrameConstructorSta
 
   // don't create a whitespace frame if aParentFrame doesn't want it.
   // always create frames for children in generated content. counter(),
   // quotes, and attr() content can easily change dynamically and we don't
   // want to be reconstructing frames. It's not even clear that these
   // should be considered ignorable just because they evaluate to
   // whitespace.
 
-  // We could handle all this in CreateNeededPseudos or some other place
-  // after we build our frame construction items, but that would involve
+  // We could handle all this in CreateNeededPseudoContainers 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
   // all anyway, and involve an extra walk down the frame construction item
   // list.
   if ((aParentFrame &&
        (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
         aParentFrame->IsGeneratedContentFrame())) ||
       !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
@@ -9613,19 +9613,20 @@ nsCSSFrameConstructor::CreateNeededAnonF
  * gets them closer to their desired parents.  For example, a run of non-row
  * children of a row-group will get wrapped in a row.  When we later construct
  * the frame for this wrapper (in this case for the row), it'll be the correct
  * parent for the cells in the set of items we wrapped or we'll wrap cells
  * around everything else.  At the end of this method, aItems is guaranteed to
  * contain only items for frames that can be direct kids of aParentFrame.
  */
 void
-nsCSSFrameConstructor::CreateNeededPseudos(nsFrameConstructorState& aState,
-                                           FrameConstructionItemList& aItems,
-                                           nsIFrame* aParentFrame)
+nsCSSFrameConstructor::CreateNeededPseudoContainers(
+    nsFrameConstructorState& aState,
+    FrameConstructionItemList& aItems,
+    nsIFrame* aParentFrame)
 {
   ParentType ourParentType = GetParentType(aParentFrame);
   if (aItems.AllWantParentType(ourParentType)) {
     // Nothing to do here
     return;
   }
 
   FCItemIterator iter(aItems);
@@ -9941,24 +9942,65 @@ nsCSSFrameConstructor::CreateNeededPseud
     iter.InsertItem(newItem);
 
     // Now |iter| points to the item that was the first one we didn't wrap;
     // loop and see whether we need to skip it or wrap it in something
     // different.
   } while (!iter.IsDone());
 }
 
+void nsCSSFrameConstructor::CreateNeededPseudoSiblings(
+    nsFrameConstructorState& aState,
+    FrameConstructionItemList& aItems,
+    nsIFrame* aParentFrame)
+{
+  if (aItems.IsEmpty() ||
+      GetParentType(aParentFrame) != eTypeRuby) {
+    return;
+  }
+
+  FCItemIterator iter(aItems);
+  int firstDisplay = iter.item().mStyleContext->StyleDisplay()->mDisplay;
+  if (firstDisplay == NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER) {
+    return;
+  }
+  NS_ASSERTION(firstDisplay == NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER,
+               "Child of ruby frame should either a rbc or a rtc");
+
+  const PseudoParentData& pseudoData =
+    sPseudoParentData[eTypeRubyBaseContainer];
+  already_AddRefed<nsStyleContext> pseudoStyle = mPresShell->StyleSet()->
+    ResolveAnonymousBoxStyle(*pseudoData.mPseudoType,
+                             aParentFrame->StyleContext());
+  FrameConstructionItem* newItem =
+    new FrameConstructionItem(&pseudoData.mFCData,
+                              // Use the content of the parent frame
+                              aParentFrame->GetContent(),
+                              // Tag type
+                              *pseudoData.mPseudoType,
+                              // Use the namespace of the rtc frame
+                              iter.item().mNameSpaceID,
+                              // no pending binding
+                              nullptr,
+                              pseudoStyle,
+                              true, nullptr);
+  newItem->mIsAllInline = true;
+  newItem->mChildItems.SetParentHasNoXBLChildren(true);
+  iter.InsertItem(newItem);
+}
+
 inline void
 nsCSSFrameConstructor::ConstructFramesFromItemList(nsFrameConstructorState& aState,
                                                    FrameConstructionItemList& aItems,
                                                    nsContainerFrame* aParentFrame,
                                                    nsFrameItems& aFrameItems)
 {
-  CreateNeededPseudos(aState, aItems, aParentFrame);
+  CreateNeededPseudoContainers(aState, aItems, aParentFrame);
   CreateNeededAnonFlexOrGridItems(aState, aItems, aParentFrame);
+  CreateNeededPseudoSiblings(aState, aItems, aParentFrame);
 
   aItems.SetTriedConstructingFrames();
   for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
     NS_ASSERTION(iter.item().DesiredParentType() == GetParentType(aParentFrame),
                  "Needed pseudos didn't get created; expect bad things");
     ConstructFramesFromItem(aState, iter, aParentFrame, aFrameItems);
   }
 
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -1155,23 +1155,30 @@ private:
    * @param aItems the child frame construction items before pseudo creation
    * @param aParentFrame the parent frame
    */
   void CreateNeededAnonFlexOrGridItems(nsFrameConstructorState& aState,
                                        FrameConstructionItemList& aItems,
                                        nsIFrame* aParentFrame);
 
   /**
-   * Function to create the table pseudo items we need.
+   * Function to create the pseudo intermediate containers we need.
    * @param aItems the child frame construction items before pseudo creation
    * @param aParentFrame the parent frame we're creating pseudos for
    */
-  inline void CreateNeededPseudos(nsFrameConstructorState& aState,
-                                  FrameConstructionItemList& aItems,
-                                  nsIFrame* aParentFrame);
+  inline void CreateNeededPseudoContainers(nsFrameConstructorState& aState,
+                                           FrameConstructionItemList& aItems,
+                                           nsIFrame* aParentFrame);
+
+  /**
+   * Function to create the pseudo siblings we need.
+   */
+  inline void CreateNeededPseudoSiblings(nsFrameConstructorState& aState,
+                                         FrameConstructionItemList& aItems,
+                                         nsIFrame* aParentFrame);
 
   /**
    * Function to adjust aParentFrame to deal with captions.
    * @param aParentFrame the frame we think should be the parent.  This will be
    *        adjusted to point to the right parent frame.
    * @param aFCData the FrameConstructionData that would be used for frame
    *        construction.
    * @param aStyleContext the style context for aChildContent