Bug 663365 - Implement the rules for the fallback to the default rendering for the meter element. r=roc
authorMounir Lamouri <mounir.lamouri@gmail.com>
Wed, 16 May 2012 18:31:01 +0200
changeset 100749 34bc8e3d549fc84c2ef41eec9ed98e9654e483d5
parent 100748 0e06a2f6af3a41d6df72316629b0fc875729b510
child 100750 cd74e9324088d2e8985eba3c8f93bca6f6de28c9
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs663365
milestone16.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 663365 - Implement the rules for the fallback to the default rendering for the meter element. r=roc
layout/forms/nsMeterFrame.cpp
layout/forms/nsMeterFrame.h
widget/reftests/meter-fallback-default-style-ref.html
widget/reftests/meter-fallback-default-style.html
widget/reftests/reftest.list
widget/xpwidgets/nsNativeTheme.cpp
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -198,16 +198,17 @@ nsMeterFrame::ReflowBarFrame(nsIFrame*  
   position = position != 0 ? (value - min) / position : 1;
 
   size = NSToCoordRound(size * position);
 
   if (!vertical && GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
     xoffset += aReflowState.ComputedWidth() - size;
   }
 
+  // The bar position is *always* constrained.
   if (vertical) {
     // We want the bar to begin at the bottom.
     yoffset += aReflowState.ComputedHeight() - size;
 
     size -= reflowState.mComputedMargin.TopBottom() +
             reflowState.mComputedBorderPadding.TopBottom();
     size = NS_MAX(size, 0);
     reflowState.SetComputedHeight(size);
@@ -267,8 +268,24 @@ nsMeterFrame::ComputeAutoSize(nsRenderin
   if (GetStyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL) {
     autoSize.height *= 5; // 5em
   } else {
     autoSize.width *= 5; // 5em
   }
   
   return autoSize;
 }
+
+bool
+nsMeterFrame::ShouldUseNativeStyle() const
+{
+  // Use the native style if these conditions are satisfied:
+  // - both frames use the native appearance;
+  // - neither frame has author specified rules setting the border or the
+  //   background.
+  return GetStyleDisplay()->mAppearance == NS_THEME_METERBAR &&
+         mBarDiv->GetPrimaryFrame()->GetStyleDisplay()->mAppearance == NS_THEME_METERBAR_CHUNK &&
+         !PresContext()->HasAuthorSpecifiedRules(const_cast<nsMeterFrame*>(this),
+                                                 NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
+         !PresContext()->HasAuthorSpecifiedRules(mBarDiv->GetPrimaryFrame(),
+                                                 NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
+}
+
--- a/layout/forms/nsMeterFrame.h
+++ b/layout/forms/nsMeterFrame.h
@@ -86,16 +86,21 @@ public:
                                  nsSize aPadding, bool aShrinkWrap);
 
   virtual bool IsFrameOfType(PRUint32 aFlags) const
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
+  /**
+   * Returns whether the frame and its child should use the native style.
+   */
+  bool ShouldUseNativeStyle() const;
+
 protected:
   // Helper function which reflow the anonymous div frame.
   void ReflowBarFrame(nsIFrame*                aBarFrame,
                       nsPresContext*           aPresContext,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus&          aStatus);
   /**
    * The div used to show the meter bar.
copy from widget/reftests/progressbar-fallback-default-style-ref.html
copy to widget/reftests/meter-fallback-default-style-ref.html
--- a/widget/reftests/progressbar-fallback-default-style-ref.html
+++ b/widget/reftests/meter-fallback-default-style-ref.html
@@ -1,66 +1,57 @@
 <!DOCTYPE html>
 <html>
   <style>
-    div.progress-element {
+    div.meter-element {
       /**
        * The purpose of this test is to not show the native style.
-       * -moz-appearance: progressbar;
+       * -moz-appearance: meterbar;
        */
       display: inline-block;
       height: 1em;
-      width: 10em;
+      width: 5em;
       vertical-align: -0.2em;
 
-      /* Default style in case of there is -moz-appearance: none; */
-      border: 2px solid;
-      -moz-border-top-colors: ThreeDShadow #e6e6e6;
-      -moz-border-right-colors: ThreeDHighlight #e6e6e6;
-      -moz-border-bottom-colors: ThreeDHighlight #e6e6e6;
-      -moz-border-left-colors: ThreeDShadow #e6e6e6;
-      background-color: #e6e6e6;
+      background: -moz-linear-gradient(top, #e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
     }
 
-    div.progress-bar {
+    div.meter-bar {
       /**
        * The purpose of this test is to not show the native style.
-       * -moz-appearance: progresschunk;
+       * -moz-appearance: meterchunk;
        */
 
       height: 100%;
       width: 100%;
 
-      -moz-box-sizing: border-box;
-
-      /* Default style in case of there is -moz-appearance: none; */
-      background-color: #0064b4;
+      background: -moz-linear-gradient(top, #ad7, #ad7, #cea 20%, #7a3 45%, #7a3 55%);
     }
 
-    div.progress-element { padding: 5px; }
+    div.meter-element { padding: 5px; }
     body > div:nth-child(1)  { -moz-appearance: none; }
-    body > div:nth-child(2) > .progress-bar { -moz-appearance: none; }
-    body > div:nth-child(3)  { background-color: red; }
-    body > div:nth-child(4) > .progress-bar { background-color: red; }
+    body > div:nth-child(2) > .meter-bar { -moz-appearance: none; }
+    body > div:nth-child(3)  { background: red; }
+    body > div:nth-child(4) > .meter-bar { background: red; }
     body > div:nth-child(5)  { border: 2px solid red; }
-    body > div:nth-child(6) > .progress-bar { border: 5px solid red; }
+    body > div:nth-child(6) > .meter-bar { border: 5px solid red; width: -moz-calc(100% - 10px); }
   </style>
   <body>
-    <div class="progress-element">
-      <div class="progress-bar"></div>
+    <div class="meter-element">
+      <div class="meter-bar"></div>
     </div>
-    <div class="progress-element">
-      <div class="progress-bar"></div>
+    <div class="meter-element">
+      <div class="meter-bar"></div>
     </div>
-    <div class="progress-element">
-      <div class="progress-bar"></div>
+    <div class="meter-element">
+      <div class="meter-bar"></div>
     </div>
-    <div class="progress-element">
-      <div class="progress-bar"></div>
+    <div class="meter-element">
+      <div class="meter-bar"></div>
     </div>
-    <div class="progress-element">
-      <div class="progress-bar"></div>
+    <div class="meter-element">
+      <div class="meter-bar"></div>
     </div>
-    <div class="progress-element">
-      <div class="progress-bar"></div>
+    <div class="meter-element">
+      <div class="meter-bar"></div>
     </div>
   </body>
 </html>
copy from widget/reftests/progressbar-fallback-default-style.html
copy to widget/reftests/meter-fallback-default-style.html
--- a/widget/reftests/progressbar-fallback-default-style.html
+++ b/widget/reftests/meter-fallback-default-style.html
@@ -1,20 +1,20 @@
 <!DOCTYPE html>
 <html>
   <style>
-    progress { padding: 5px }
-    body > progress:nth-child(1) { -moz-appearance: none; }
-    body > progress:nth-child(2)::-moz-progress-bar { -moz-appearance: none; }
-    body > progress:nth-child(3) { background-color: red; }
-    body > progress:nth-child(4)::-moz-progress-bar { background-color: red; }
-    body > progress:nth-child(5) { border: 2px solid red; }
-    body > progress:nth-child(6)::-moz-progress-bar { border: 5px solid red; }
+    meter { padding: 5px }
+    body > meter:nth-child(1) { -moz-appearance: none; }
+    body > meter:nth-child(2)::-moz-meter-bar { -moz-appearance: none; }
+    body > meter:nth-child(3) { background: red; }
+    body > meter:nth-child(4)::-moz-meter-bar { background: red; }
+    body > meter:nth-child(5) { border: 2px solid red; }
+    body > meter:nth-child(6)::-moz-meter-bar { border: 5px solid red; }
   </style>
   <body>
-    <progress></progress>
-    <progress></progress>
-    <progress></progress>
-    <progress></progress>
-    <progress></progress>
-    <progress></progress>
+    <meter value=1></meter>
+    <meter value=1></meter>
+    <meter value=1></meter>
+    <meter value=1></meter>
+    <meter value=1></meter>
+    <meter value=1></meter>
   </body>
 </html>
--- a/widget/reftests/reftest.list
+++ b/widget/reftests/reftest.list
@@ -1,3 +1,4 @@
 skip-if(!cocoaWidget) != 507947.html about:blank
 == progressbar-fallback-default-style.html progressbar-fallback-default-style-ref.html
+== meter-fallback-default-style.html meter-fallback-default-style-ref.html
 load 664925.xhtml
--- a/widget/xpwidgets/nsNativeTheme.cpp
+++ b/widget/xpwidgets/nsNativeTheme.cpp
@@ -14,16 +14,17 @@
 #include "nsString.h"
 #include "nsINameSpaceManager.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMXULMenuListElement.h"
 #include "nsThemeConstants.h"
 #include "nsIComponentManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsProgressFrame.h"
+#include "nsMeterFrame.h"
 #include "nsMenuFrame.h"
 #include "mozilla/dom/Element.h"
 
 nsNativeTheme::nsNativeTheme()
 : mAnimatedContentTimeout(PR_UINT32_MAX)
 {
 }
 
@@ -242,16 +243,29 @@ nsNativeTheme::IsWidgetStyled(nsPresCont
       aWidgetType == NS_THEME_PROGRESSBAR) {
     nsProgressFrame* progressFrame = do_QueryFrame(aWidgetType == NS_THEME_PROGRESSBAR_CHUNK
                                        ? aFrame->GetParent() : aFrame);
     if (progressFrame) {
       return !progressFrame->ShouldUseNativeStyle();
     }
   }
 
+  /**
+   * Meter bar appearance should be the same for the bar and the container
+   * frame. nsMeterFrame owns the logic and will tell us what we should do.
+   */
+  if (aWidgetType == NS_THEME_METERBAR_CHUNK ||
+      aWidgetType == NS_THEME_METERBAR) {
+    nsMeterFrame* meterFrame = do_QueryFrame(aWidgetType == NS_THEME_METERBAR_CHUNK
+                                       ? aFrame->GetParent() : aFrame);
+    if (meterFrame) {
+      return !meterFrame->ShouldUseNativeStyle();
+    }
+  }
+
   return (aWidgetType == NS_THEME_BUTTON ||
           aWidgetType == NS_THEME_TEXTFIELD ||
           aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
           aWidgetType == NS_THEME_LISTBOX ||
           aWidgetType == NS_THEME_DROPDOWN) &&
          aFrame->GetContent()->IsHTML() &&
          aPresContext->HasAuthorSpecifiedRules(aFrame,
                                                NS_AUTHOR_SPECIFIED_BORDER |