Bug 1085311 - Vertical writing-mode support for single-line <input> fields. r=jfkthame
authorXidorn Quan [:xidorn] <quanxunzhen@gmail.com>
Tue, 04 Nov 2014 15:45:00 +0100
changeset 214091 4845f12212781c8c0ef3e099860c0afe2ec03c97
parent 214090 39fb242f5043c288a640059d5e93af941986026c
child 214092 2f8e7c39573e5e89feb679ac092af1aab2638a74
push id27771
push userryanvm@gmail.com
push dateWed, 05 Nov 2014 19:04:24 +0000
treeherdermozilla-central@305b4fecce99 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1085311
milestone36.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 1085311 - Vertical writing-mode support for single-line <input> fields. r=jfkthame
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
layout/generic/nsTextFrame.cpp
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -138,18 +138,19 @@ nsTextControlFrame::DestroyFrom(nsIFrame
 nsIAtom*
 nsTextControlFrame::GetType() const 
 { 
   return nsGkAtoms::textInputFrame;
 }
 
 nsresult
 nsTextControlFrame::CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
-                                      nsSize&             aIntrinsicSize,
-                                      float               aFontSizeInflation)
+                                      WritingMode aWM,
+                                      LogicalSize& aIntrinsicSize,
+                                      float aFontSizeInflation)
 {
   // Get leading and the Average/MaxAdvance char width 
   nscoord lineHeight  = 0;
   nscoord charWidth   = 0;
   nscoord charMaxAdvance  = 0;
 
   nsRefPtr<nsFontMetrics> fontMet;
   nsresult rv =
@@ -160,71 +161,70 @@ nsTextControlFrame::CalcIntrinsicSize(ns
   lineHeight =
     nsHTMLReflowState::CalcLineHeight(GetContent(), StyleContext(),
                                       NS_AUTOHEIGHT, aFontSizeInflation);
   charWidth = fontMet->AveCharWidth();
   charMaxAdvance = fontMet->MaxAdvance();
 
   // Set the width equal to the width in characters
   int32_t cols = GetCols();
-  aIntrinsicSize.width = cols * charWidth;
+  aIntrinsicSize.ISize(aWM) = cols * charWidth;
 
   // To better match IE, take the maximum character width(in twips) and remove
   // 4 pixels add this on as additional padding(internalPadding). But only do
   // this if we think we have a fixed-width font.
   if (mozilla::Abs(charWidth - charMaxAdvance) > (unsigned)nsPresContext::CSSPixelsToAppUnits(1)) {
     nscoord internalPadding =
       std::max(0, charMaxAdvance - nsPresContext::CSSPixelsToAppUnits(4));
     nscoord t = nsPresContext::CSSPixelsToAppUnits(1); 
    // Round to a multiple of t
     nscoord rest = internalPadding % t; 
     if (rest < t - rest) {
       internalPadding -= rest;
     } else {
       internalPadding += t - rest;
     }
     // Now add the extra padding on (so that small input sizes work well)
-    aIntrinsicSize.width += internalPadding;
+    aIntrinsicSize.ISize(aWM) += internalPadding;
   } else {
     // This is to account for the anonymous <br> having a 1 twip width
     // in Full Standards mode, see BRFrame::Reflow and bug 228752.
     if (PresContext()->CompatibilityMode() == eCompatibility_FullStandards) {
-      aIntrinsicSize.width += 1;
+      aIntrinsicSize.ISize(aWM) += 1;
     }
   }
 
   // Increment width with cols * letter-spacing.
   {
     const nsStyleCoord& lsCoord = StyleText()->mLetterSpacing;
     if (eStyleUnit_Coord == lsCoord.GetUnit()) {
       nscoord letterSpacing = lsCoord.GetCoordValue();
       if (letterSpacing != 0) {
-        aIntrinsicSize.width += cols * letterSpacing;
+        aIntrinsicSize.ISize(aWM) += cols * letterSpacing;
       }
     }
   }
 
   // Set the height equal to total number of rows (times the height of each
   // line, of course)
-  aIntrinsicSize.height = lineHeight * GetRows();
+  aIntrinsicSize.BSize(aWM) = lineHeight * GetRows();
 
   // Add in the size of the scrollbars for textarea
   if (IsTextArea()) {
     nsIFrame* first = GetFirstPrincipalChild();
 
     nsIScrollableFrame *scrollableFrame = do_QueryFrame(first);
     NS_ASSERTION(scrollableFrame, "Child must be scrollable");
 
     if (scrollableFrame) {
       nsMargin scrollbarSizes =
       scrollableFrame->GetDesiredScrollbarSizes(PresContext(), aRenderingContext);
 
-      aIntrinsicSize.width  += scrollbarSizes.LeftRight();
-
-      aIntrinsicSize.height += scrollbarSizes.TopBottom();;
+      aIntrinsicSize.Width(aWM) += scrollbarSizes.LeftRight();
+      aIntrinsicSize.Height(aWM) += scrollbarSizes.TopBottom();
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 nsTextControlFrame::EnsureEditorInitialized()
@@ -420,20 +420,21 @@ nsTextControlFrame::AppendAnonymousConte
 
 nscoord
 nsTextControlFrame::GetPrefISize(nsRenderingContext* aRenderingContext)
 {
     DebugOnly<nscoord> result = 0;
     DISPLAY_PREF_WIDTH(this, result);
 
     float inflation = nsLayoutUtils::FontSizeInflationFor(this);
-    nsSize autoSize;
-    CalcIntrinsicSize(aRenderingContext, autoSize, inflation);
+    WritingMode wm = GetWritingMode();
+    LogicalSize autoSize(wm);
+    CalcIntrinsicSize(aRenderingContext, wm, autoSize, inflation);
 
-    return autoSize.width; 
+    return autoSize.ISize(wm);
 }
 
 nscoord
 nsTextControlFrame::GetMinISize(nsRenderingContext* aRenderingContext)
 {
   // Our min width is just our preferred width if we have auto width.
   nscoord result;
   DISPLAY_MIN_WIDTH(this, result);
@@ -449,39 +450,42 @@ nsTextControlFrame::ComputeAutoSize(nsRe
                                     const LogicalSize& aCBSize,
                                     nscoord aAvailableISize,
                                     const LogicalSize& aMargin,
                                     const LogicalSize& aBorder,
                                     const LogicalSize& aPadding,
                                     bool aShrinkWrap)
 {
   float inflation = nsLayoutUtils::FontSizeInflationFor(this);
-  // XXX CalcIntrinsicSize needs to be updated to use a LogicalSize
-  nsSize autoSize;
-  nsresult rv = CalcIntrinsicSize(aRenderingContext, autoSize, inflation);
+  LogicalSize autoSize(aWM);
+  nsresult rv = CalcIntrinsicSize(aRenderingContext, aWM, autoSize, inflation);
   if (NS_FAILED(rv)) {
     // What now?
-    autoSize.SizeTo(0, 0);
+    autoSize.SizeTo(aWM, 0, 0);
   }
 #ifdef DEBUG
   // Note: Ancestor ComputeAutoSize only computes a width if we're auto-width
-  else if (StylePosition()->mWidth.GetUnit() == eStyleUnit_Auto) {
-    LogicalSize ancestorAutoSize =
-      nsContainerFrame::ComputeAutoSize(aRenderingContext, aWM,
-                                        aCBSize, aAvailableISize,
-                                        aMargin, aBorder,
-                                        aPadding, aShrinkWrap);
-    // Disabled when there's inflation; see comment in GetPrefSize.
-    NS_ASSERTION(inflation != 1.0f ||
-                 ancestorAutoSize.Width(aWM) == autoSize.width,
+  else {
+    const nsStyleCoord& inlineStyleCoord =
+      aWM.IsVertical() ? StylePosition()->mHeight : StylePosition()->mWidth;
+    if (inlineStyleCoord.GetUnit() == eStyleUnit_Auto) {
+      LogicalSize ancestorAutoSize =
+        nsContainerFrame::ComputeAutoSize(aRenderingContext, aWM,
+                                          aCBSize, aAvailableISize,
+                                          aMargin, aBorder,
+                                          aPadding, aShrinkWrap);
+      // Disabled when there's inflation; see comment in GetPrefSize.
+      MOZ_ASSERT(inflation != 1.0f ||
+                 ancestorAutoSize.ISize(aWM) == autoSize.ISize(aWM),
                  "Incorrect size computed by ComputeAutoSize?");
+    }
   }
 #endif
 
-  return LogicalSize(aWM, autoSize);
+  return autoSize;
 }
 
 void
 nsTextControlFrame::Reflow(nsPresContext*   aPresContext,
                            nsHTMLReflowMetrics&     aDesiredSize,
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aStatus)
 {
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -267,18 +267,19 @@ protected:
    * @param aPresContext the current pres context
    */
   void PreDestroy();
 
   // Compute our intrinsic size.  This does not include any borders, paddings,
   // etc.  Just the size of our actual area for the text (and the scrollbars,
   // for <textarea>).
   nsresult CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
-                             nsSize&             aIntrinsicSize,
-                             float               aFontSizeInflation);
+                             mozilla::WritingMode aWM,
+                             mozilla::LogicalSize& aIntrinsicSize,
+                             float aFontSizeInflation);
 
   nsresult ScrollSelectionIntoView() MOZ_OVERRIDE;
 
 private:
   //helper methods
   nsresult SetSelectionInternal(nsIDOMNode *aStartNode, int32_t aStartOffset,
                                 nsIDOMNode *aEndNode, int32_t aEndOffset,
                                 SelectionDirection aDirection = eNone);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3795,19 +3795,23 @@ nsresult
 nsFrame::GetCursor(const nsPoint& aPoint,
                    nsIFrame::Cursor& aCursor)
 {
   FillCursorInformationFromStyle(StyleUserInterface(), aCursor);
   if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
     // If this is editable, I-beam cursor is better for most elements.
     aCursor.mCursor =
       (mContent && mContent->IsEditable())
-      ? GetWritingMode().IsVertical()
-        ? NS_STYLE_CURSOR_VERTICAL_TEXT : NS_STYLE_CURSOR_TEXT
-      : NS_STYLE_CURSOR_DEFAULT;
+      ? NS_STYLE_CURSOR_TEXT : NS_STYLE_CURSOR_DEFAULT;
+  }
+  if (NS_STYLE_CURSOR_TEXT == aCursor.mCursor &&
+      GetWritingMode().IsVertical()) {
+    // Per CSS UI spec, UA may treat value 'text' as
+    // 'vertical-text' for vertical text.
+    aCursor.mCursor = NS_STYLE_CURSOR_VERTICAL_TEXT;
   }
 
   return NS_OK;
 }
 
 // Resize and incremental reflow
 
 /* virtual */ void
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -2473,17 +2473,17 @@ GetNormalLineHeight(nsFontMetrics* aFont
     //case eNoExternalLeading:
     normalLineHeight = emHeight + internalLeading;
   }
   return normalLineHeight;
 }
 
 static inline nscoord
 ComputeLineHeight(nsStyleContext* aStyleContext,
-                  nscoord aBlockHeight,
+                  nscoord aBlockBSize,
                   float aFontSizeInflation)
 {
   const nsStyleCoord& lhCoord = aStyleContext->StyleText()->mLineHeight;
 
   if (lhCoord.GetUnit() == eStyleUnit_Coord) {
     nscoord result = lhCoord.GetCoordValue();
     if (aFontSizeInflation != 1.0f) {
       result = NSToCoordRound(result * aFontSizeInflation);
@@ -2500,49 +2500,49 @@ ComputeLineHeight(nsStyleContext* aStyle
 
   NS_ASSERTION(lhCoord.GetUnit() == eStyleUnit_Normal ||
                lhCoord.GetUnit() == eStyleUnit_Enumerated,
                "bad line-height unit");
   
   if (lhCoord.GetUnit() == eStyleUnit_Enumerated) {
     NS_ASSERTION(lhCoord.GetIntValue() == NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT,
                  "bad line-height value");
-    if (aBlockHeight != NS_AUTOHEIGHT) {
-      return aBlockHeight;
+    if (aBlockBSize != NS_AUTOHEIGHT) {
+      return aBlockBSize;
     }
   }
 
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
                                                getter_AddRefs(fm),
                                                aFontSizeInflation);
   return GetNormalLineHeight(fm);
 }
 
 nscoord
 nsHTMLReflowState::CalcLineHeight() const
 {
-  nscoord blockHeight =
-    nsLayoutUtils::IsNonWrapperBlock(frame) ? ComputedHeight() :
-    (mCBReflowState ? mCBReflowState->ComputedHeight() : NS_AUTOHEIGHT);
+  nscoord blockBSize =
+    nsLayoutUtils::IsNonWrapperBlock(frame) ? ComputedBSize() :
+    (mCBReflowState ? mCBReflowState->ComputedBSize() : NS_AUTOHEIGHT);
 
-  return CalcLineHeight(frame->GetContent(), frame->StyleContext(), blockHeight,
+  return CalcLineHeight(frame->GetContent(), frame->StyleContext(), blockBSize,
                         nsLayoutUtils::FontSizeInflationFor(frame));
 }
 
 /* static */ nscoord
 nsHTMLReflowState::CalcLineHeight(nsIContent* aContent,
                                   nsStyleContext* aStyleContext,
-                                  nscoord aBlockHeight,
+                                  nscoord aBlockBSize,
                                   float aFontSizeInflation)
 {
   NS_PRECONDITION(aStyleContext, "Must have a style context");
 
   nscoord lineHeight =
-    ComputeLineHeight(aStyleContext, aBlockHeight, aFontSizeInflation);
+    ComputeLineHeight(aStyleContext, aBlockBSize, aFontSizeInflation);
 
   NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up");
 
   HTMLInputElement* input = HTMLInputElement::FromContentOrNull(aContent);
   if (input && input->IsSingleLineTextControl()) {
     // For Web-compatibility, single-line text input elements cannot
     // have a line-height smaller than one.
     nscoord lineHeightOne =
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -632,17 +632,17 @@ public:
    *                     line-height:-moz-block-height.
    * @param aFontSizeInflation The result of the appropriate
    *                           nsLayoutUtils::FontSizeInflationFor call,
    *                           or 1.0 if during intrinsic size
    *                           calculation.
    */
   static nscoord CalcLineHeight(nsIContent* aContent,
                                 nsStyleContext* aStyleContext,
-                                nscoord aBlockHeight,
+                                nscoord aBlockBSize,
                                 float aFontSizeInflation);
 
 
   void ComputeContainingBlockRectangle(nsPresContext*          aPresContext,
                                        const nsHTMLReflowState* aContainingBlockRS,
                                        nscoord&                 aContainingBlockWidth,
                                        nscoord&                 aContainingBlockHeight);
 
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4237,19 +4237,20 @@ nsTextFrame::GetCursor(const nsPoint& aP
           int32_t tabIndexVal = tabIndexStr.ToInteger(&rv);
           if (NS_SUCCEEDED(rv) && tabIndexVal >= 0) {
             aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
             break;
           }
         }
       }
     }
-  }
-
-  return NS_OK;
+    return NS_OK;
+  } else {
+    return nsFrame::GetCursor(aPoint, aCursor);
+  }
 }
 
 nsIFrame*
 nsTextFrame::LastInFlow() const
 {
   nsTextFrame* lastInFlow = const_cast<nsTextFrame*>(this);
   while (lastInFlow->GetNextInFlow())  {
     lastInFlow = static_cast<nsTextFrame*>(lastInFlow->GetNextInFlow());