From 4577efd50f8361ffa787d7fcba5f5894438f826c Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Thu, 17 Aug 2017 20:21:38 +0200 Subject: Implement DOM page onvisibilitychange. --- dom/base/nsGkAtomList.h | 1 + dom/events/EventNameList.h | 4 ++++ dom/webidl/Document.webidl | 3 ++- testing/web-platform/tests/page-visibility/idlharness.html | 6 +++++- widget/EventMessageList.h | 3 +++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 0b76b2bea..86a6fa99c 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -950,6 +950,7 @@ GK_ATOM(onupdateready, "onupdateready") GK_ATOM(onupgradeneeded, "onupgradeneeded") GK_ATOM(onussdreceived, "onussdreceived") GK_ATOM(onversionchange, "onversionchange") +GK_ATOM(onvisibilitychange, "onvisibilitychange") GK_ATOM(onvoicechange, "onvoicechange") GK_ATOM(onvoiceschanged, "onvoiceschanged") GK_ATOM(onvrdisplayconnect, "onvrdisplayconnect") diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h index b1be6dd76..ba2427623 100644 --- a/dom/events/EventNameList.h +++ b/dom/events/EventNameList.h @@ -674,6 +674,10 @@ DOCUMENT_ONLY_EVENT(selectionchange, eSelectionChange, EventNameType_HTMLXUL, eBasicEventClass) +DOCUMENT_ONLY_EVENT(visibilitychange, + eVisibilityChange, + EventNameType_HTMLXUL, + eBasicEventClass) NON_IDL_EVENT(MozMouseHittest, eMouseHitTest, diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl index c895fad39..f05656e84 100644 --- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -275,10 +275,11 @@ partial interface Document { object registerElement(DOMString name, optional ElementRegistrationOptions options); }; -// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#sec-document-interface +// https://w3c.github.io/page-visibility/#extensions-to-the-document-interface partial interface Document { readonly attribute boolean hidden; readonly attribute VisibilityState visibilityState; + attribute EventHandler onvisibilitychange; }; // http://dev.w3.org/csswg/cssom/#extensions-to-the-document-interface diff --git a/testing/web-platform/tests/page-visibility/idlharness.html b/testing/web-platform/tests/page-visibility/idlharness.html index c8086a1bc..257546080 100644 --- a/testing/web-platform/tests/page-visibility/idlharness.html +++ b/testing/web-platform/tests/page-visibility/idlharness.html @@ -4,7 +4,7 @@ Page Visibility IDL tests - + @@ -16,6 +16,10 @@
diff --git a/widget/EventMessageList.h b/widget/EventMessageList.h
index 55fc7375e..7fe642637 100644
--- a/widget/EventMessageList.h
+++ b/widget/EventMessageList.h
@@ -448,6 +448,9 @@ NS_EVENT_MESSAGE(eEditorInput)
 NS_EVENT_MESSAGE(eSelectStart)
 NS_EVENT_MESSAGE(eSelectionChange)
 
+// visibility change
+NS_EVENT_MESSAGE(eVisibilityChange)
+
 // Details element events.
 NS_EVENT_MESSAGE(eToggle)
 
-- 
cgit v1.2.3


From b736f53a13af48de08026b7c7e64275122af66e2 Mon Sep 17 00:00:00 2001
From: janekptacijarabaci 
Date: Thu, 17 Aug 2017 20:27:14 +0200
Subject: SVG - support radialGradient fr attribute

---
 dom/base/nsGkAtomList.h                           |  1 +
 dom/svg/SVGGradientElement.cpp                    |  9 +++++++-
 dom/svg/SVGGradientElement.h                      |  7 +++---
 dom/webidl/SVGRadialGradientElement.webidl        |  4 +++-
 layout/reftests/svg/radialGradient-fr-01.svg      | 27 ++++++++++++++++++++++
 layout/reftests/svg/radialGradient-fr-02-ref.svg  | 28 +++++++++++++++++++++++
 layout/reftests/svg/radialGradient-fr-02.svg      | 27 ++++++++++++++++++++++
 layout/reftests/svg/reftest.list                  |  2 ++
 layout/svg/nsSVGGradientFrame.cpp                 |  5 ++--
 testing/web-platform/meta/svg/interfaces.html.ini |  6 -----
 10 files changed, 103 insertions(+), 13 deletions(-)
 create mode 100644 layout/reftests/svg/radialGradient-fr-01.svg
 create mode 100644 layout/reftests/svg/radialGradient-fr-02-ref.svg
 create mode 100644 layout/reftests/svg/radialGradient-fr-02.svg

diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
index 86a6fa99c..91427fabb 100644
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -1450,6 +1450,7 @@ GK_ATOM(font_style, "font-style")
 GK_ATOM(font_variant, "font-variant")
 GK_ATOM(foreignObject, "foreignObject")
 GK_ATOM(fractalNoise, "fractalNoise")
+GK_ATOM(fr, "fr")
 GK_ATOM(fx, "fx")
 GK_ATOM(fy, "fy")
 GK_ATOM(G, "G")
diff --git a/dom/svg/SVGGradientElement.cpp b/dom/svg/SVGGradientElement.cpp
index 1bcac67e6..93767c934 100644
--- a/dom/svg/SVGGradientElement.cpp
+++ b/dom/svg/SVGGradientElement.cpp
@@ -198,13 +198,14 @@ SVGRadialGradientElement::WrapNode(JSContext* aCx, JS::Handle aGivenP
   return SVGRadialGradientElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
-nsSVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[5] =
+nsSVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[6] =
 {
   { &nsGkAtoms::cx, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
   { &nsGkAtoms::cy, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
   { &nsGkAtoms::r, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::XY },
   { &nsGkAtoms::fx, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
   { &nsGkAtoms::fy, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
+  { &nsGkAtoms::fr, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::XY },
 };
 
 //----------------------------------------------------------------------
@@ -252,6 +253,12 @@ SVGRadialGradientElement::Fy()
   return mLengthAttributes[ATTR_FY].ToDOMAnimatedLength(this);
 }
 
+already_AddRefed
+SVGRadialGradientElement::Fr()
+{
+  return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this);
+}
+
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
diff --git a/dom/svg/SVGGradientElement.h b/dom/svg/SVGGradientElement.h
index 7b2c6b220..ce9f3b4b1 100644
--- a/dom/svg/SVGGradientElement.h
+++ b/dom/svg/SVGGradientElement.h
@@ -139,13 +139,14 @@ public:
   already_AddRefed R();
   already_AddRefed Fx();
   already_AddRefed Fy();
+  already_AddRefed Fr();
 protected:
 
   virtual LengthAttributesInfo GetLengthInfo() override;
 
-  enum { ATTR_CX, ATTR_CY, ATTR_R, ATTR_FX, ATTR_FY };
-  nsSVGLength2 mLengthAttributes[5];
-  static LengthInfo sLengthInfo[5];
+  enum { ATTR_CX, ATTR_CY, ATTR_R, ATTR_FX, ATTR_FY, ATTR_FR };
+  nsSVGLength2 mLengthAttributes[6];
+  static LengthInfo sLengthInfo[6];
 };
 
 } // namespace dom
diff --git a/dom/webidl/SVGRadialGradientElement.webidl b/dom/webidl/SVGRadialGradientElement.webidl
index d4a3724f6..8d7ce9016 100644
--- a/dom/webidl/SVGRadialGradientElement.webidl
+++ b/dom/webidl/SVGRadialGradientElement.webidl
@@ -21,5 +21,7 @@ interface SVGRadialGradientElement : SVGGradientElement {
   readonly attribute SVGAnimatedLength fx;
   [Constant]
   readonly attribute SVGAnimatedLength fy;
-  // readonly attribute SVGAnimatedLength fr;
+  // XXX: Bug 1242048
+  // [SameObject]
+  readonly attribute SVGAnimatedLength fr;
 };
diff --git a/layout/reftests/svg/radialGradient-fr-01.svg b/layout/reftests/svg/radialGradient-fr-01.svg
new file mode 100644
index 000000000..2f28d3aba
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-fr-01.svg
@@ -0,0 +1,27 @@
+
+
+  Test gradient fr attribute
+  
+    
+      
+      
+    
+    
+    
+  
+  
+
+  
+
+  
+
+
diff --git a/layout/reftests/svg/radialGradient-fr-02-ref.svg b/layout/reftests/svg/radialGradient-fr-02-ref.svg
new file mode 100644
index 000000000..c256f72a2
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-fr-02-ref.svg
@@ -0,0 +1,28 @@
+
+
+  Test gradient fr attribute
+  
+    
+      
+      
+      
+    
+    
+  
+  
+
+  
+  
+
+
diff --git a/layout/reftests/svg/radialGradient-fr-02.svg b/layout/reftests/svg/radialGradient-fr-02.svg
new file mode 100644
index 000000000..1933203be
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-fr-02.svg
@@ -0,0 +1,27 @@
+
+
+  Test gradient fr attribute
+  
+    
+      
+      
+    
+    
+  
+  
+
+  
+  
+
+
diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list
index e596feae8..520adc9e6 100644
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -290,6 +290,8 @@ fuzzy-if(skiaContent,3,5) == pattern-scale-01c.svg pattern-scale-01-ref.svg
 == radialGradient-basic-02.svg pass.svg
 fuzzy-if(cocoaWidget,4,15982) fuzzy-if(winWidget,4,92) fuzzy-if(skiaContent,4,60) == radialGradient-basic-03.svg radialGradient-basic-03-ref.svg
 == radialGradient-basic-04.svg pass.svg
+== radialGradient-fr-01.svg pass.svg
+fuzzy(1,3235) fuzzy-if(winWidget,1,6704) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg
 fuzzy-if(skiaContent,1,3600) == rect-01.svg pass.svg
 == rect-02.svg pass.svg
 == rect-03.svg pass.svg
diff --git a/layout/svg/nsSVGGradientFrame.cpp b/layout/svg/nsSVGGradientFrame.cpp
index 217ab8c4a..2d7684f5a 100644
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -623,7 +623,7 @@ nsSVGRadialGradientFrame::GradientVectorLengthIsZero()
 already_AddRefed
 nsSVGRadialGradientFrame::CreateGradient()
 {
-  float cx, cy, r, fx, fy;
+  float cx, cy, r, fx, fy, fr;
 
   cx = GetLengthValue(dom::SVGRadialGradientElement::ATTR_CX);
   cy = GetLengthValue(dom::SVGRadialGradientElement::ATTR_CY);
@@ -631,6 +631,7 @@ nsSVGRadialGradientFrame::CreateGradient()
   // If fx or fy are not set, use cx/cy instead
   fx = GetLengthValue(dom::SVGRadialGradientElement::ATTR_FX, cx);
   fy = GetLengthValue(dom::SVGRadialGradientElement::ATTR_FY, cy);
+  fr = GetLengthValue(dom::SVGRadialGradientElement::ATTR_FR);
 
   if (fx != cx || fy != cy) {
     // The focal point (fFx and fFy) must be clamped to be *inside* - not on -
@@ -651,7 +652,7 @@ nsSVGRadialGradientFrame::CreateGradient()
     }
   }
 
-  RefPtr pattern = new gfxPattern(fx, fy, 0, cx, cy, r);
+  RefPtr pattern = new gfxPattern(fx, fy, fr, cx, cy, r);
   return pattern.forget();
 }
 
diff --git a/testing/web-platform/meta/svg/interfaces.html.ini b/testing/web-platform/meta/svg/interfaces.html.ini
index f3f7f6b5c..1162695c8 100644
--- a/testing/web-platform/meta/svg/interfaces.html.ini
+++ b/testing/web-platform/meta/svg/interfaces.html.ini
@@ -820,12 +820,6 @@
   [SVGElement interface: linearGradient must inherit property "onsort" with the proper type (62)]
     expected: FAIL
 
-  [SVGRadialGradientElement interface: attribute fr]
-    expected: FAIL
-
-  [SVGRadialGradientElement interface: radialGradient must inherit property "fr" with the proper type (5)]
-    expected: FAIL
-
   [SVGElement interface: radialGradient must inherit property "onautocomplete" with the proper type (8)]
     expected: FAIL
 
-- 
cgit v1.2.3


From 017797de494cffd76e31e62dbec3234ecabfb75b Mon Sep 17 00:00:00 2001
From: janekptacijarabaci 
Date: Thu, 17 Aug 2017 20:30:45 +0200
Subject: CSS - Grid - fit-content unexpectedly reserves space for full clamp
 size in repeat()

---
 layout/style/nsCSSParser.cpp           | 4 ++++
 layout/style/test/property_database.js | 5 +++++
 2 files changed, 9 insertions(+)

diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index 1108ce5b5..cd996230e 100644
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -8918,6 +8918,10 @@ CSSParserImpl::ParseGridTrackSize(nsCSSValue& aValue,
     return CSSParseResult::NotFound;
   }
   if (mToken.mIdent.LowerCaseEqualsLiteral("fit-content")) {
+    if (requireFixedSize) {
+      UngetToken();
+      return CSSParseResult::Error;
+    }
     nsCSSValue::Array* func = aValue.InitFunction(eCSSKeyword_fit_content, 1);
     if (ParseGridTrackBreadth(func->Item(1)) == CSSParseResult::Ok &&
         func->Item(1).IsLengthPercentCalcUnit() &&
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index 9c69e7d10..4389d0cd0 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -6270,6 +6270,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) {
       "repeat(auto-fill,minmax(1%,auto))",
       "repeat(auto-fill,minmax(1em,min-content)) minmax(min-content,0)",
       "repeat(auto-fill,minmax(max-content,1mm))",
+      "repeat(2, fit-content(1px))",
       "fit-content(1px) 1fr",
       "[a] fit-content(calc(1px - 99%)) [b]",
       "[a] fit-content(10%) [b c] fit-content(1em)",
@@ -6314,6 +6315,8 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) {
       "repeat(1, repeat(1, 20px))",
       "repeat(auto-fill, auto)",
       "repeat(auto-fit,auto)",
+      "repeat(auto-fill, fit-content(1px))",
+      "repeat(auto-fit, fit-content(1px))",
       "repeat(auto-fit,[])",
       "repeat(auto-fill, 0) repeat(auto-fit, 0) ",
       "repeat(auto-fit, 0) repeat(auto-fill, 0) ",
@@ -6335,6 +6338,8 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) {
       "fit-content(-1px)",
       "fit-content(auto)",
       "fit-content(min-content)",
+      "fit-content(1px) repeat(auto-fit, 1px)",
+      "fit-content(1px) repeat(auto-fill, 1px)",
     ],
     unbalanced_values: [
       "(foo] 40px",
-- 
cgit v1.2.3


From 505edf1ba4f6907c236b4876eefea606fa7b9cd0 Mon Sep 17 00:00:00 2001
From: janekptacijarabaci 
Date: Thu, 17 Aug 2017 20:34:01 +0200
Subject: [draft] CSS - linear-gradient - zero (0) angle value without degree
 unit is not correctly interpreted

---
 layout/style/nsCSSParser.cpp           | 3 ++-
 layout/style/test/property_database.js | 9 +++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index cd996230e..b361cf0c2 100644
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -10404,7 +10404,8 @@ CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue,
     UngetToken();
 
     //  ,
-    if (ParseSingleTokenVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) &&
+    if (ParseSingleTokenVariant(cssGradient->mAngle,
+                                VARIANT_ANGLE_OR_ZERO, nullptr) &&
         !ExpectSymbol(',', true)) {
       SkipUntil(')');
       return false;
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index 4389d0cd0..62d413d98 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -132,6 +132,9 @@ var validGradientAndElementValues = [
   "linear-gradient(to right bottom, red, 50%, green 50%, 50%, blue)",
   "linear-gradient(to right bottom, red, 0%, green 50%, 100%, blue)",
 
+  /* Unitless 0 is valid as an  */
+  "linear-gradient(0, red, blue)",
+
   "-moz-linear-gradient(red, blue)",
   "-moz-linear-gradient(red, yellow, blue)",
   "-moz-linear-gradient(red 1px, yellow 20%, blue 24em, green)",
@@ -388,10 +391,8 @@ var invalidGradientAndElementValues = [
   "-moz-linear-gradient(10 10px -45deg, red, blue) repeat",
   "-moz-linear-gradient(10px 10 -45deg, red, blue) repeat",
   "linear-gradient(red -99, yellow, green, blue 120%)",
-  /* Unitless 0 is invalid as an  */
-  "-moz-linear-gradient(top left 0, red, blue)",
-  "-moz-linear-gradient(5px 5px 0, red, blue)",
-  "linear-gradient(0, red, blue)",
+  /* Unitless nonzero numbers are valid as an  */
+  "linear-gradient(30, red, blue)",
   /* Invalid color, calc() or -moz-image-rect() function */
   "linear-gradient(red, rgb(0, rubbish, 0) 50%, red)",
   "linear-gradient(red, red calc(50% + rubbish), red)",
-- 
cgit v1.2.3


From 920519e7c56a08f743e5230e8db30f635f5f7cf5 Mon Sep 17 00:00:00 2001
From: janekptacijarabaci 
Date: Thu, 17 Aug 2017 20:46:41 +0200
Subject: CSS - Grid - intristic content with overflow:auto overlaps in grid

---
 layout/generic/ReflowInput.cpp                     | 12 +++
 layout/generic/ReflowInput.h                       |  4 +
 layout/generic/nsFrame.cpp                         |  2 +-
 layout/generic/nsGridContainerFrame.cpp            | 41 +++++++---
 layout/generic/nsIFrame.h                          |  8 ++
 .../grid-item-overflow-stretch-001-ref.html        | 78 +++++++++++++++++++
 .../css-grid/grid-item-overflow-stretch-001.html   | 74 ++++++++++++++++++
 .../grid-item-overflow-stretch-002-ref.html        | 79 +++++++++++++++++++
 .../css-grid/grid-item-overflow-stretch-002.html   | 75 ++++++++++++++++++
 .../grid-item-overflow-stretch-003-ref.html        | 84 +++++++++++++++++++++
 .../css-grid/grid-item-overflow-stretch-003.html   | 75 ++++++++++++++++++
 .../grid-item-overflow-stretch-004-ref.html        | 88 ++++++++++++++++++++++
 .../css-grid/grid-item-overflow-stretch-004.html   | 82 ++++++++++++++++++++
 .../grid-item-overflow-stretch-005-ref.html        | 83 ++++++++++++++++++++
 .../css-grid/grid-item-overflow-stretch-005.html   | 77 +++++++++++++++++++
 .../grid-item-overflow-stretch-006-ref.html        | 54 +++++++++++++
 .../css-grid/grid-item-overflow-stretch-006.html   | 56 ++++++++++++++
 layout/reftests/css-grid/reftest.list              |  6 ++
 18 files changed, 965 insertions(+), 13 deletions(-)
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-001.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-002.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-003.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-004.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-005.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html
 create mode 100644 layout/reftests/css-grid/grid-item-overflow-stretch-006.html

diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index 42f4a24b5..a8756cea2 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -93,6 +93,9 @@ ReflowInput::ReflowInput(nsPresContext*       aPresContext,
   if (aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE) {
     mFlags.mBClampMarginBoxMinSize = true;
   }
+  if (aFlags & I_APPLY_AUTO_MIN_SIZE) {
+    mFlags.mApplyAutoMinSize = true;
+  }
 
   if (!(aFlags & CALLER_WILL_INIT)) {
     Init(aPresContext);
@@ -242,6 +245,7 @@ ReflowInput::ReflowInput(
   mFlags.mIOffsetsNeedCSSAlign = mFlags.mBOffsetsNeedCSSAlign = false;
   mFlags.mIClampMarginBoxMinSize = !!(aFlags & I_CLAMP_MARGIN_BOX_MIN_SIZE);
   mFlags.mBClampMarginBoxMinSize = !!(aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE);
+  mFlags.mApplyAutoMinSize = !!(aFlags & I_APPLY_AUTO_MIN_SIZE);
 
   mDiscoveredClearance = nullptr;
   mPercentBSizeObserver = (aParentReflowInput.mPercentBSizeObserver &&
@@ -1662,6 +1666,10 @@ ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext,
     computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
                          ComputeSizeFlags::eBClampMarginBoxMinSize);
   }
+  if (mFlags.mApplyAutoMinSize) {
+    computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
+                         ComputeSizeFlags::eIApplyAutoMinSize);
+  }
   if (mFlags.mShrinkWrap) {
     computeSizeFlags =
       ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
@@ -2375,6 +2383,10 @@ ReflowInput::InitConstraints(nsPresContext*     aPresContext,
         computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
                              ComputeSizeFlags::eBClampMarginBoxMinSize);
       }
+      if (mFlags.mApplyAutoMinSize) {
+        computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
+                             ComputeSizeFlags::eIApplyAutoMinSize);
+      }
       if (mFlags.mShrinkWrap) {
         computeSizeFlags =
           ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
index e42508646..09c980b72 100644
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -220,6 +220,7 @@ public:
     uint32_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag
     uint32_t mIClampMarginBoxMinSize:1; // the I_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag
     uint32_t mBClampMarginBoxMinSize:1; // the B_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag
+    uint32_t mApplyAutoMinSize : 1;       // the I_APPLY_AUTO_MIN_SIZE ctor flag
 
     // If set, the following two flags indicate that:
     // (1) this frame is absolutely-positioned (or fixed-positioned).
@@ -738,6 +739,9 @@ public:
 
     // Pass ComputeSizeFlags::eBClampMarginBoxMinSize to ComputeSize().
     B_CLAMP_MARGIN_BOX_MIN_SIZE = (1<<6),
+
+    // Pass ComputeSizeFlags::eIApplyAutoMinSize to ComputeSize().
+    I_APPLY_AUTO_MIN_SIZE = (1<<7),
   };
 
   // This method initializes various data members. It is automatically
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 69791d5c5..418fa16b7 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4781,7 +4781,7 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext,
       ComputeISizeValue(aRenderingContext, aCBSize.ISize(aWM),
                         boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
                         minISizeCoord, aFlags);
-  } else if (MOZ_UNLIKELY(isGridItem)) {
+  } else if (MOZ_UNLIKELY(aFlags & eIApplyAutoMinSize)) {
     // This implements "Implied Minimum Size of Grid Items".
     // https://drafts.csswg.org/css-grid/#min-size-auto
     minISize = std::min(maxISize, GetMinISize(aRenderingContext));
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index 71d5bba21..f3e28acc4 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -818,8 +818,11 @@ struct nsGridContainerFrame::GridItemInfo
     // Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline.
     eContentBaseline =       0x10,
     eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline,
+    // Should apply Automatic Minimum Size per:
+    // https://drafts.csswg.org/css-grid/#min-size-auto
+    eApplyAutoMinSize =      0x20,
     // Clamp per https://drafts.csswg.org/css-grid/#min-size-auto
-    eClampMarginBoxMinSize = 0x20,
+    eClampMarginBoxMinSize = 0x40,
   };
 
   explicit GridItemInfo(nsIFrame* aFrame,
@@ -851,11 +854,11 @@ struct nsGridContainerFrame::GridItemInfo
     return aAlign;
   }
 
-  // Return true if we should we clamp this item's Automatic Minimum Size.
+  // Return true if we should apply Automatic Minimum Size to this item.
   // https://drafts.csswg.org/css-grid/#min-size-auto
-  bool ShouldClampMinSize(WritingMode aContainerWM,
-                          LogicalAxis aContainerAxis,
-                          nscoord aPercentageBasis) const
+  bool ShouldApplyAutoMinSize(WritingMode aContainerWM,
+                              LogicalAxis aContainerAxis,
+                              nscoord aPercentageBasis) const
   {
     const auto pos = mFrame->StylePosition();
     const auto& size = aContainerAxis == eLogicalAxisInline ?
@@ -3977,9 +3980,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1(
   WritingMode wm = aState.mWM;
   // Calculate data for "Automatic Minimum Size" clamping, if needed.
   bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) ||
-                 aConstraint == SizingConstraint::eNoConstraint);
-  if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState) &&
-      aGridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+                 aConstraint == SizingConstraint::eNoConstraint) &&
+                (aGridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
+  if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState)) {
     if (sz.mState & TrackSize::eIntrinsicMinSizing) {
       auto maxCoord = aFunctions.MaxSizingFor(aRange.mStart);
       cache.mMinSizeClamp =
@@ -4382,6 +4385,14 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
   iter.Reset();
   for (; !iter.AtEnd(); iter.Next()) {
     auto& gridItem = aGridItems[iter.GridItemIndex()];
+
+    // Check if we need to apply "Automatic Minimum Size" and cache it.
+    MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
+               "Why is eApplyAutoMinSize set already?");
+    if (gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
+      gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
+    }
+
     const GridArea& area = gridItem.mArea;
     const LineRange& lineRange = area.*aRange;
     uint32_t span = lineRange.Extent();
@@ -4407,9 +4418,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
         CachedIntrinsicSizes cache;
         // Calculate data for "Automatic Minimum Size" clamping, if needed.
         bool needed = ((state & TrackSize::eIntrinsicMinSizing) ||
-                       aConstraint == SizingConstraint::eNoConstraint);
-        if (needed && TrackSize::IsDefiniteMaxSizing(state) &&
-            gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+                       aConstraint == SizingConstraint::eNoConstraint) &&
+                      (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
+        if (needed && TrackSize::IsDefiniteMaxSizing(state)) {
           nscoord minSizeClamp = 0;
           for (auto i = lineRange.mStart, end = lineRange.mEnd; i < end; ++i) {
             auto maxCoord = aFunctions.MaxSizingFor(i);
@@ -4445,11 +4456,14 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
           gridItem.mState[mAxis] |= ItemState::eIsFlexing;
         } else if (aConstraint == SizingConstraint::eNoConstraint &&
                    TrackSize::IsDefiniteMaxSizing(state) &&
-                   gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+                   (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize)) {
           gridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize;
         }
       }
     }
+    MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eClampMarginBoxMinSize) ||
+               (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
+               "clamping only applies to Automatic Minimum Size");
   }
 
   // Step 2.
@@ -5231,6 +5245,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame*              aChild,
     } else {
       aChild->Properties().Delete(BClampMarginBoxMinSizeProperty());
     }
+    if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) {
+      flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE;
+    }
   }
 
   if (!isConstrainedBSize) {
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 50eb958e0..2acafa882 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2105,6 +2105,14 @@ public:
      */
     eIClampMarginBoxMinSize = 1 << 2, // clamp in our inline axis
     eBClampMarginBoxMinSize = 1 << 3, // clamp in our block axis
+    /**
+     * The frame is stretching (per CSS Box Alignment) and doesn't have an
+     * Automatic Minimum Size in the indicated axis.
+     * (may be used for both flex/grid items, but currently only used for Grid)
+     * https://drafts.csswg.org/css-grid/#min-size-auto
+     * https://drafts.csswg.org/css-align-3/#valdef-justify-self-stretch
+     */
+    eIApplyAutoMinSize = 1 << 4, // only has an effect when eShrinkWrap is false
   };
 
   /**
diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html
new file mode 100644
index 000000000..463bbb4e6
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html
@@ -0,0 +1,78 @@
+
+
+
+  
+  CSS Grid Reference: stretching overflow!=visible items
+  
+  
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-001.html b/layout/reftests/css-grid/grid-item-overflow-stretch-001.html new file mode 100644 index 000000000..4f6259abe --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-001.html @@ -0,0 +1,74 @@ + + + + + CSS Grid Test: stretching overflow!=visible items + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html new file mode 100644 index 000000000..a9690a54e --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html @@ -0,0 +1,79 @@ + + + + + CSS Grid Reference: stretching overflow!=visible vertical-rl items + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-002.html b/layout/reftests/css-grid/grid-item-overflow-stretch-002.html new file mode 100644 index 000000000..520eed911 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-002.html @@ -0,0 +1,75 @@ + + + + + CSS Grid Test: stretching overflow!=visible vertical-rl items + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html new file mode 100644 index 000000000..c082e6be4 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html @@ -0,0 +1,84 @@ + + + + + CSS Grid Reference: margin:auto stretch items + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-003.html b/layout/reftests/css-grid/grid-item-overflow-stretch-003.html new file mode 100644 index 000000000..8bcd79d9b --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-003.html @@ -0,0 +1,75 @@ + + + + + CSS Grid Test: margin:auto stretch items + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html new file mode 100644 index 000000000..71ed28d7c --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html @@ -0,0 +1,88 @@ + + + + + CSS Grid Reference: stretching items + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-004.html b/layout/reftests/css-grid/grid-item-overflow-stretch-004.html new file mode 100644 index 000000000..b983b5184 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-004.html @@ -0,0 +1,82 @@ + + + + + CSS Grid Test: stretching items + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html new file mode 100644 index 000000000..e7d353c8b --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html @@ -0,0 +1,83 @@ + + + + + CSS Grid Reference: stretching overflow!=visible items + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-005.html b/layout/reftests/css-grid/grid-item-overflow-stretch-005.html new file mode 100644 index 000000000..33fe468d7 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-005.html @@ -0,0 +1,77 @@ + + + + + CSS Grid Test: stretching overflow!=visible items + + + + + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html new file mode 100644 index 000000000..71d4d4f54 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html @@ -0,0 +1,54 @@ + + + + + CSS Grid Reference: stretching overflow visible items + + + + + +
+
+
+ +
+ +
+ +
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-006.html b/layout/reftests/css-grid/grid-item-overflow-stretch-006.html new file mode 100644 index 000000000..015c50fcc --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-006.html @@ -0,0 +1,56 @@ + + + + + CSS Grid Test: stretching overflow visible items + + + + + + +
+
+
+ +
+ +
+ +
+
+
+ +
+ +
+ + + diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list index d85eefbd0..093e2faee 100644 --- a/layout/reftests/css-grid/reftest.list +++ b/layout/reftests/css-grid/reftest.list @@ -116,6 +116,12 @@ skip-if(Android) == grid-auto-min-sizing-percent-001.html grid-auto-min-sizing-p == grid-item-auto-min-size-clamp-005.html grid-item-auto-min-size-clamp-005-ref.html == grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html == grid-item-auto-min-size-clamp-007.html grid-item-auto-min-size-clamp-007-ref.html +== grid-item-overflow-stretch-001.html grid-item-overflow-stretch-001-ref.html +== grid-item-overflow-stretch-002.html grid-item-overflow-stretch-002-ref.html +== grid-item-overflow-stretch-003.html grid-item-overflow-stretch-003-ref.html +== grid-item-overflow-stretch-004.html grid-item-overflow-stretch-004-ref.html +== grid-item-overflow-stretch-005.html grid-item-overflow-stretch-005-ref.html +== grid-item-overflow-stretch-006.html grid-item-overflow-stretch-006-ref.html == grid-item-canvas-001.html grid-item-canvas-001-ref.html skip-if(Android) == grid-item-button-001.html grid-item-button-001-ref.html == grid-item-table-stretch-001.html grid-item-table-stretch-001-ref.html -- cgit v1.2.3 From 76e1c016a32cb8cee6f5a0a0012fe512570da1eb Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Thu, 17 Aug 2017 20:56:20 +0200 Subject: CSS - Grid - transferred min-size contribution of percentage size grid item with an intrinsic ratio --- layout/base/nsLayoutUtils.cpp | 151 ++++++++++++++++++--- layout/base/nsLayoutUtils.h | 5 + layout/generic/nsGridContainerFrame.cpp | 68 ++++++++-- ...to-min-sizing-min-content-min-size-004-ref.html | 2 +- ...d-auto-min-sizing-transferred-size-004-ref.html | 2 +- ...ontent-min-sizing-transferred-size-004-ref.html | 2 +- 6 files changed, 199 insertions(+), 31 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 789c91f50..c8c91b251 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -4637,6 +4637,63 @@ GetPercentBSize(const nsStyleCoord& aStyle, return true; } +// Return true if aStyle can be resolved to a definite value and if so +// return that value in aResult. +static bool +GetDefiniteSize(const nsStyleCoord& aStyle, + nsIFrame* aFrame, + bool aIsInlineAxis, + const Maybe& aPercentageBasis, + nscoord* aResult) +{ + switch (aStyle.GetUnit()) { + case eStyleUnit_Coord: + *aResult = aStyle.GetCoordValue(); + return true; + case eStyleUnit_Percent: { + if (aPercentageBasis.isNothing()) { + return false; + } + auto wm = aFrame->GetWritingMode(); + nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) + : aPercentageBasis.value().BSize(wm); + if (pb != NS_UNCONSTRAINEDSIZE) { + nscoord p = NSToCoordFloorClamped(pb * aStyle.GetPercentValue()); + *aResult = std::max(nscoord(0), p); + return true; + } + return false; + } + case eStyleUnit_Calc: { + nsStyleCoord::Calc* calc = aStyle.GetCalcValue(); + if (calc->mPercent != 0.0f) { + if (aPercentageBasis.isNothing()) { + return false; + } + auto wm = aFrame->GetWritingMode(); + nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) + : aPercentageBasis.value().BSize(wm); + if (pb == NS_UNCONSTRAINEDSIZE) { + // XXXmats given that we're calculating an intrinsic size here, + // maybe we should back-compute the calc-size using AddPercents? + return false; + } + *aResult = std::max(0, calc->mLength + + NSToCoordFloorClamped(pb * calc->mPercent)); + } else { + *aResult = std::max(0, calc->mLength); + } + return true; + } + default: + return false; + } +} + +// +// NOTE: this function will be replaced by GetDefiniteSizeTakenByBoxSizing (bug 1363918). +// Please do not add new uses of this function. +// // Get the amount of vertical space taken out of aFrame's content area due to // its borders and paddings given the box-sizing value in aBoxSizing. We don't // get aBoxSizing from the frame because some callers want to compute this for @@ -4681,6 +4738,54 @@ GetBSizeTakenByBoxSizing(StyleBoxSizing aBoxSizing, return bSizeTakenByBoxSizing; } +// Get the amount of space taken out of aFrame's content area due to its +// borders and paddings given the box-sizing value in aBoxSizing. We don't +// get aBoxSizing from the frame because some callers want to compute this for +// specific box-sizing values. +// aIsInlineAxis is true if we're computing for aFrame's inline axis. +// aIgnorePadding is true if padding should be ignored. +static nscoord +GetDefiniteSizeTakenByBoxSizing(StyleBoxSizing aBoxSizing, + nsIFrame* aFrame, + bool aIsInlineAxis, + bool aIgnorePadding, + const Maybe& aPercentageBasis) +{ + nscoord sizeTakenByBoxSizing = 0; + if (MOZ_UNLIKELY(aBoxSizing == StyleBoxSizing::Border)) { + const bool isHorizontalAxis = + aIsInlineAxis == !aFrame->GetWritingMode().IsVertical(); + const nsStyleBorder* styleBorder = aFrame->StyleBorder(); + sizeTakenByBoxSizing = + isHorizontalAxis ? styleBorder->GetComputedBorder().LeftRight() + : styleBorder->GetComputedBorder().TopBottom(); + if (!aIgnorePadding) { + const nsStyleSides& stylePadding = aFrame->StylePadding()->mPadding; + const nsStyleCoord& pStart = + stylePadding.Get(isHorizontalAxis ? eSideLeft : eSideTop); + const nsStyleCoord& pEnd = + stylePadding.Get(isHorizontalAxis ? eSideRight : eSideBottom); + nscoord pad; + // XXXbz Calling GetPercentBSize on padding values looks bogus, since + // percent padding is always a percentage of the inline-size of the + // containing block. We should perhaps just treat non-absolute paddings + // here as 0 instead, except that in some cases the width may in fact be + // known. See bug 1231059. + if (GetDefiniteSize(pStart, aFrame, aIsInlineAxis, aPercentageBasis, &pad) || + (aPercentageBasis.isNothing() && + GetPercentBSize(pStart, aFrame, isHorizontalAxis, pad))) { + sizeTakenByBoxSizing += pad; + } + if (GetDefiniteSize(pEnd, aFrame, aIsInlineAxis, aPercentageBasis, &pad) || + (aPercentageBasis.isNothing() && + GetPercentBSize(pEnd, aFrame, isHorizontalAxis, pad))) { + sizeTakenByBoxSizing += pad; + } + } + } + return sizeTakenByBoxSizing; +} + // Handles only -moz-max-content and -moz-min-content, and // -moz-fit-content for min-width and max-width, since the others // (-moz-fit-content for width, and -moz-available) have no effect on @@ -4940,17 +5045,21 @@ AddStateBitToAncestors(nsIFrame* aFrame, nsFrameState aBit) } /* static */ nscoord -nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, - nsRenderingContext* aRenderingContext, - nsIFrame* aFrame, - IntrinsicISizeType aType, - uint32_t aFlags, - nscoord aMarginBoxMinSizeClamp) +nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, + nsRenderingContext* aRenderingContext, + nsIFrame* aFrame, + IntrinsicISizeType aType, + const Maybe& aPercentageBasis, + uint32_t aFlags, + nscoord aMarginBoxMinSizeClamp) { NS_PRECONDITION(aFrame, "null frame"); NS_PRECONDITION(aFrame->GetParent(), "IntrinsicForAxis called on frame not in tree"); NS_PRECONDITION(aType == MIN_ISIZE || aType == PREF_ISIZE, "bad type"); + MOZ_ASSERT(aFrame->GetParent()->Type() != LayoutFrameType::GridContainer || + aPercentageBasis.isSome(), + "grid layout should always pass a percentage basis"); const bool horizontalAxis = MOZ_LIKELY(aAxis == eAxisHorizontal); #ifdef DEBUG_INTRINSIC_WIDTH @@ -5014,6 +5123,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, PhysicalAxis ourInlineAxis = aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline); + const bool isInlineAxis = aAxis == ourInlineAxis; // If we have a specified width (or a specified 'min-width' greater // than the specified 'max-width', which works out to the same thing), // don't even bother getting the frame's intrinsic width, because in @@ -5043,7 +5153,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, // constraint is the max-content contribution which we shouldn't clamp. aMarginBoxMinSizeClamp = NS_MAXSIZE; } - if (MOZ_UNLIKELY(aAxis != ourInlineAxis)) { + if (MOZ_UNLIKELY(!isInlineAxis)) { IntrinsicSize intrinsicSize = aFrame->GetIntrinsicSize(); const nsStyleCoord intrinsicBCoord = horizontalAxis ? intrinsicSize.width : intrinsicSize.height; @@ -5105,21 +5215,23 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE); nscoord bSizeTakenByBoxSizing = - GetBSizeTakenByBoxSizing(boxSizing, aFrame, horizontalAxis, - aFlags & IGNORE_PADDING); - + GetDefiniteSizeTakenByBoxSizing(boxSizing, aFrame, !isInlineAxis, + aFlags & IGNORE_PADDING, + aPercentageBasis); // NOTE: This is only the minContentSize if we've been passed MIN_INTRINSIC_ISIZE // (which is fine, because this should only be used inside a check for that flag). nscoord minContentSize = result; nscoord h; - if (GetAbsoluteCoord(styleBSize, h) || - GetPercentBSize(styleBSize, aFrame, horizontalAxis, h)) { + if (GetDefiniteSize(styleBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) || + (aPercentageBasis.isNothing() && + GetPercentBSize(styleBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); result = NSCoordMulDiv(h, ratioISize, ratioBSize); } - if (GetAbsoluteCoord(styleMaxBSize, h) || - GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h)) { + if (GetDefiniteSize(styleMaxBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) || + (aPercentageBasis.isNothing() && + GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); nscoord maxISize = NSCoordMulDiv(h, ratioISize, ratioBSize); if (maxISize < result) { @@ -5130,8 +5242,9 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, } } - if (GetAbsoluteCoord(styleMinBSize, h) || - GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h)) { + if (GetDefiniteSize(styleMinBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) || + (aPercentageBasis.isNothing() && + GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); nscoord minISize = NSCoordMulDiv(h, ratioISize, ratioBSize); if (minISize > result) { @@ -5158,8 +5271,8 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, } nsIFrame::IntrinsicISizeOffsetData offsets = - MOZ_LIKELY(aAxis == ourInlineAxis) ? aFrame->IntrinsicISizeOffsets() - : aFrame->IntrinsicBSizeOffsets(); + MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets() + : aFrame->IntrinsicBSizeOffsets(); nscoord contentBoxSize = result; result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType, boxSizing, result, min, styleISize, @@ -5196,7 +5309,7 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext* aRenderingContext, // We want the size aFrame will contribute to its parent's inline-size. PhysicalAxis axis = aFrame->GetParent()->GetWritingMode().PhysicalAxis(eLogicalAxisInline); - return IntrinsicForAxis(axis, aRenderingContext, aFrame, aType, aFlags); + return IntrinsicForAxis(axis, aRenderingContext, aFrame, aType, Nothing(), aFlags); } /* static */ nscoord diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index d9580a3df..97fc410b0 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1378,6 +1378,10 @@ public: * width, its 'width', 'min-width', and 'max-width' properties (or 'height' * variations if that's what matches aAxis) and its padding, border and margin * in the corresponding dimension. + * @param aPercentageBasis an optional percentage basis (in aFrame's WM). + * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. + * If you pass Nothing() a percentage basis will be calculated from aFrame's + * ancestors' computed size in the relevant axis, if needed. * @param aMarginBoxMinSizeClamp make the result fit within this margin-box * size by reducing the *content size* (flooring at zero). This is used for: * https://drafts.csswg.org/css-grid/#min-size-auto @@ -1396,6 +1400,7 @@ public: nsRenderingContext* aRenderingContext, nsIFrame* aFrame, IntrinsicISizeType aType, + const mozilla::Maybe& aPercentageBasis = mozilla::Nothing(), uint32_t aFlags = 0, nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE); /** diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index f3e28acc4..8f117b5ab 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -2092,6 +2092,18 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput LogicalSize& aContentBox, SizingConstraint aConstraint); + /** + * Return the percentage basis for a grid item in its writing-mode. + * If aAxis is eLogicalAxisInline then we return NS_UNCONSTRAINEDSIZE in + * both axes since we know all track sizes are indefinite at this point + * (we calculate column sizes before row sizes). Otherwise, assert that + * column sizes are known and calculate the size for aGridItem.mArea.mCols + * and use NS_UNCONSTRAINEDSIZE in the other axis. + * @param aAxis the axis we're currently calculating track sizes for + */ + LogicalSize PercentageBasisFor(LogicalAxis aAxis, + const GridItemInfo& aGridItem) const; + /** * Return the containing block for a grid item occupying aArea. */ @@ -3734,18 +3746,20 @@ MeasuringReflow(nsIFrame* aChild, * the child's margin-box) in aAxis. */ static nscoord -ContentContribution(const GridItemInfo& aGridItem, - const GridReflowInput& aState, - nsRenderingContext* aRC, - WritingMode aCBWM, - LogicalAxis aAxis, - IntrinsicISizeType aConstraint, - nscoord aMinSizeClamp = NS_MAXSIZE, - uint32_t aFlags = 0) +ContentContribution(const GridItemInfo& aGridItem, + const GridReflowInput& aState, + nsRenderingContext* aRC, + WritingMode aCBWM, + LogicalAxis aAxis, + const Maybe& aPercentageBasis, + IntrinsicISizeType aConstraint, + nscoord aMinSizeClamp = NS_MAXSIZE, + uint32_t aFlags = 0) { nsIFrame* child = aGridItem.mFrame; PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis)); nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint, + aPercentageBasis, aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED | nsLayoutUtils::ADD_PERCENTS, aMinSizeClamp); @@ -3815,6 +3829,10 @@ struct CachedIntrinsicSizes Maybe mMinSize; Maybe mMinContentContribution; Maybe mMaxContentContribution; + + // The item's percentage basis for intrinsic sizing purposes. + Maybe mPercentageBasis; + // "if the grid item spans only grid tracks that have a fixed max track // sizing function, its automatic minimum size in that dimension is // further clamped to less than or equal to the size necessary to fit its @@ -3835,7 +3853,11 @@ MinContentContribution(const GridItemInfo& aGridItem, if (aCache->mMinContentContribution.isSome()) { return aCache->mMinContentContribution.value(); } + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } nscoord s = ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, + aCache->mPercentageBasis, nsLayoutUtils::MIN_ISIZE, aCache->mMinSizeClamp); aCache->mMinContentContribution.emplace(s); @@ -3853,7 +3875,11 @@ MaxContentContribution(const GridItemInfo& aGridItem, if (aCache->mMaxContentContribution.isSome()) { return aCache->mMaxContentContribution.value(); } + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } nscoord s = ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, + aCache->mPercentageBasis, nsLayoutUtils::PREF_ISIZE, aCache->mMinSizeClamp); aCache->mMaxContentContribution.emplace(s); @@ -3907,7 +3933,11 @@ MinSize(const GridItemInfo& aGridItem, child->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)) { // Now calculate the "content size" part and return whichever is smaller. MOZ_ASSERT(unit != eStyleUnit_Enumerated || sz == NS_UNCONSTRAINEDSIZE); + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, + aCache->mPercentageBasis, nsLayoutUtils::MIN_ISIZE, aCache->mMinSizeClamp, nsLayoutUtils::MIN_INTRINSIC_ISIZE)); @@ -4721,7 +4751,8 @@ nsGridContainerFrame::Tracks::FindUsedFlexFraction( const GridItemInfo& item = aGridItems[iter.GridItemIndex()]; if (item.mState[mAxis] & ItemState::eIsFlexing) { // XXX optimize: bug 1194446 - nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis, + auto pb = Some(aState.PercentageBasisFor(mAxis, item)); + nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis, pb, nsLayoutUtils::PREF_ISIZE); if (spaceToFill <= 0) { continue; @@ -5052,6 +5083,25 @@ nsGridContainerFrame::LineRange::ToPositionAndLengthForAbsPos( } } +LogicalSize +nsGridContainerFrame::GridReflowInput::PercentageBasisFor( + LogicalAxis aAxis, + const GridItemInfo& aGridItem) const +{ + auto wm = aGridItem.mFrame->GetWritingMode(); + if (aAxis == eLogicalAxisInline) { + return LogicalSize(wm, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + } + // Note: for now, we only resolve transferred percentages to row sizing. + // We may need to adjust these assertions once we implement bug 1300366. + MOZ_ASSERT(mCols.mCanResolveLineRangeSize); + MOZ_ASSERT(!mRows.mCanResolveLineRangeSize); + nscoord colSize = aGridItem.mArea.mCols.ToLength(mCols.mSizes); + nscoord rowSize = NS_UNCONSTRAINEDSIZE; + return !wm.IsOrthogonalTo(mWM) ? + LogicalSize(wm, colSize, rowSize) : LogicalSize(wm, rowSize, colSize); +} + LogicalRect nsGridContainerFrame::GridReflowInput::ContainingBlockFor(const GridArea& aArea) const { diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html index fc74cd214..caef8b031 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "24px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html index c5d8a68ff..36a2d4920 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "24px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html b/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html index 5fa60b3b5..04d047b83 100644 --- a/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html +++ b/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "24px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "312px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" -- cgit v1.2.3 From 092c61f6e68971a62822532e12dc45ba54c9a713 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Thu, 17 Aug 2017 21:08:44 +0200 Subject: CSS: inline-block with a display:block child element has a wrong baseline (HTML forms) --- image/DrawResult.h | 1 + layout/forms/nsFieldSetFrame.cpp | 71 +++++++++++---- layout/forms/nsFieldSetFrame.h | 9 +- layout/forms/nsHTMLButtonControlFrame.cpp | 41 +++++++++ layout/forms/nsHTMLButtonControlFrame.h | 7 ++ layout/forms/nsLegendFrame.h | 5 +- layout/forms/nsTextControlFrame.cpp | 11 +-- layout/forms/nsTextControlFrame.h | 35 ++++++++ layout/reftests/bugs/315920-17.html | 15 +++- .../forms/display-block-baselines-1-ref.html | 91 +++++++++++++++++++ .../reftests/forms/display-block-baselines-1.html | 92 +++++++++++++++++++ .../forms/display-block-baselines-2-ref.html | 100 +++++++++++++++++++++ .../reftests/forms/display-block-baselines-2.html | 100 +++++++++++++++++++++ .../forms/display-block-baselines-3-ref.html | 72 +++++++++++++++ .../reftests/forms/display-block-baselines-3.html | 73 +++++++++++++++ .../forms/display-block-baselines-4-ref.html | 73 +++++++++++++++ .../reftests/forms/display-block-baselines-4.html | 74 +++++++++++++++ .../forms/display-block-baselines-5-ref.html | 72 +++++++++++++++ .../reftests/forms/display-block-baselines-5.html | 72 +++++++++++++++ layout/reftests/forms/reftest.list | 5 ++ 20 files changed, 990 insertions(+), 29 deletions(-) create mode 100644 layout/reftests/forms/display-block-baselines-1-ref.html create mode 100644 layout/reftests/forms/display-block-baselines-1.html create mode 100644 layout/reftests/forms/display-block-baselines-2-ref.html create mode 100644 layout/reftests/forms/display-block-baselines-2.html create mode 100644 layout/reftests/forms/display-block-baselines-3-ref.html create mode 100644 layout/reftests/forms/display-block-baselines-3.html create mode 100644 layout/reftests/forms/display-block-baselines-4-ref.html create mode 100644 layout/reftests/forms/display-block-baselines-4.html create mode 100644 layout/reftests/forms/display-block-baselines-5-ref.html create mode 100644 layout/reftests/forms/display-block-baselines-5.html diff --git a/image/DrawResult.h b/image/DrawResult.h index 8240ede26..912f59dc3 100644 --- a/image/DrawResult.h +++ b/image/DrawResult.h @@ -6,6 +6,7 @@ #ifndef mozilla_image_DrawResult_h #define mozilla_image_DrawResult_h +#include // for uint8_t #include "mozilla/Attributes.h" #include "mozilla/Likely.h" diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index befd41ee2..fc9f0571b 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -5,26 +5,22 @@ #include "nsFieldSetFrame.h" +#include #include "mozilla/gfx/2D.h" +#include "mozilla/Likely.h" +#include "mozilla/Maybe.h" #include "nsCSSAnonBoxes.h" -#include "nsLayoutUtils.h" -#include "nsLegendFrame.h" #include "nsCSSRendering.h" -#include -#include "nsIFrame.h" -#include "nsPresContext.h" -#include "mozilla/RestyleManager.h" -#include "nsGkAtoms.h" -#include "nsStyleConsts.h" #include "nsDisplayList.h" +#include "nsGkAtoms.h" +#include "nsIFrameInlines.h" +#include "nsLayoutUtils.h" +#include "nsLegendFrame.h" #include "nsRenderingContext.h" -#include "nsIScrollableFrame.h" -#include "mozilla/Likely.h" -#include "mozilla/Maybe.h" +#include "nsStyleConsts.h" using namespace mozilla; using namespace mozilla::gfx; -using namespace mozilla::image; using namespace mozilla::layout; nsContainerFrame* @@ -126,7 +122,7 @@ void nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { - DrawResult result = static_cast(mFrame)-> + image::DrawResult result = static_cast(mFrame)-> PaintBorder(aBuilder, *aCtx, ToReferenceFrame(), mVisibleRect); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); @@ -210,7 +206,7 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, contentDisplayItems.MoveTo(aLists); } -DrawResult +image::DrawResult nsFieldSetFrame::PaintBorder( nsDisplayListBuilder* aBuilder, nsRenderingContext& aRenderingContext, @@ -695,9 +691,50 @@ nsFieldSetFrame::AccessibleType() #endif nscoord -nsFieldSetFrame::GetLogicalBaseline(WritingMode aWritingMode) const +nsFieldSetFrame::GetLogicalBaseline(WritingMode aWM) const +{ + switch (StyleDisplay()->mDisplay) { + case mozilla::StyleDisplay::Grid: + case mozilla::StyleDisplay::InlineGrid: + case mozilla::StyleDisplay::Flex: + case mozilla::StyleDisplay::InlineFlex: + return BaselineBOffset(aWM, BaselineSharingGroup::eFirst, + AlignmentContext::eInline); + default: + return BSize(aWM) - BaselineBOffset(aWM, BaselineSharingGroup::eLast, + AlignmentContext::eInline); + } +} + +bool +nsFieldSetFrame::GetVerticalAlignBaseline(WritingMode aWM, + nscoord* aBaseline) const { nsIFrame* inner = GetInner(); - return inner->BStart(aWritingMode, GetParent()->GetSize()) + - inner->GetLogicalBaseline(aWritingMode); + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { + return false; + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + *aBaseline += innerBStart; + return true; +} + +bool +nsFieldSetFrame::GetNaturalBaselineBOffset(WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const +{ + nsIFrame* inner = GetInner(); + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { + return false; + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline += innerBStart; + } else { + *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); + } + return true; } diff --git a/layout/forms/nsFieldSetFrame.h b/layout/forms/nsFieldSetFrame.h index 54eaf678f..39d862278 100644 --- a/layout/forms/nsFieldSetFrame.h +++ b/layout/forms/nsFieldSetFrame.h @@ -7,7 +7,7 @@ #define nsFieldSetFrame_h___ #include "mozilla/Attributes.h" -#include "imgIContainer.h" +#include "DrawResult.h" #include "nsContainerFrame.h" class nsFieldSetFrame final : public nsContainerFrame @@ -46,6 +46,13 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override; + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override; + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index ef9459ef2..2e4fa9f67 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -418,6 +418,47 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, aButtonDesiredSize.SetOverflowAreasToDesiredBounds(); } +bool +nsHTMLButtonControlFrame::GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const +{ + nsIFrame* inner = mFrames.FirstChild(); + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { + return false; + } + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { + // has an empty block frame as inner frame + *aBaseline = inner-> + SynthesizeBaselineBOffsetFromBorderBox(aWM, BaselineSharingGroup::eFirst); + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + *aBaseline += innerBStart; + return true; +} + +bool +nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const +{ + nsIFrame* inner = mFrames.FirstChild(); + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { + return false; + } + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { + // has an empty block frame as inner frame + *aBaseline = inner-> + SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup); + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline += innerBStart; + } else { + *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); + } + return true; +} + nsresult nsHTMLButtonControlFrame::SetFormProperty(nsIAtom* aName, const nsAString& aValue) { if (nsGkAtoms::value == aName) { diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 96ad0f366..432afa12c 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -39,6 +39,13 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override; + + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override; + virtual nsresult HandleEvent(nsPresContext* aPresContext, mozilla::WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) override; diff --git a/layout/forms/nsLegendFrame.h b/layout/forms/nsLegendFrame.h index 5f5e1e03e..a9e11cbbe 100644 --- a/layout/forms/nsLegendFrame.h +++ b/layout/forms/nsLegendFrame.h @@ -9,7 +9,8 @@ #include "mozilla/Attributes.h" #include "nsBlockFrame.h" -class nsLegendFrame : public nsBlockFrame { +class nsLegendFrame final : public nsBlockFrame +{ public: NS_DECL_QUERYFRAME_TARGET(nsLegendFrame) NS_DECL_QUERYFRAME @@ -30,7 +31,7 @@ public: virtual nsresult GetFrameName(nsAString& aResult) const override; #endif - int32_t GetLogicalAlign(WritingMode aCBWM); + int32_t GetLogicalAlign(mozilla::WritingMode aCBWM); }; diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index f85bc2a80..a7f7d40a8 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -106,6 +106,7 @@ private: nsTextControlFrame::nsTextControlFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) + , mFirstBaseline(NS_INTRINSIC_WIDTH_UNKNOWN) , mEditorHasBeenInitialized(false) , mIsProcessing(false) #ifdef DEBUG @@ -538,20 +539,20 @@ nsTextControlFrame::Reflow(nsPresContext* aPresContext, aReflowInput.ComputedLogicalBorderPadding().BStartEnd(wm)); aDesiredSize.SetSize(wm, finalSize); - // computation of the ascent wrt the input height + // Calculate the baseline and store it in mFirstBaseline. nscoord lineHeight = aReflowInput.ComputedBSize(); float inflation = nsLayoutUtils::FontSizeInflationFor(this); if (!IsSingleLineTextControl()) { lineHeight = ReflowInput::CalcLineHeight(GetContent(), StyleContext(), - NS_AUTOHEIGHT, inflation); + NS_AUTOHEIGHT, inflation); } RefPtr fontMet = nsLayoutUtils::GetFontMetricsForFrame(this, inflation); - // now adjust for our borders and padding - aDesiredSize.SetBlockStartAscent( + mFirstBaseline = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight, wm.IsLineInverted()) + - aReflowInput.ComputedLogicalBorderPadding().BStart(wm)); + aReflowInput.ComputedLogicalBorderPadding().BStart(wm); + aDesiredSize.SetBlockStartAscent(mFirstBaseline); // overflow handling aDesiredSize.SetOverflowAreasToDesiredBounds(); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index a76cba514..9d4d0b77c 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -62,6 +62,29 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override + { + return GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::eFirst, aBaseline); + } + + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override + { + if (!IsSingleLineTextControl()) { + return false; + } + NS_ASSERTION(mFirstBaseline != NS_INTRINSIC_WIDTH_UNKNOWN, + "please call Reflow before asking for the baseline"); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline = mFirstBaseline; + } else { + *aBaseline = BSize(aWM) - mFirstBaseline; + } + return true; + } + virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual bool IsXULCollapsed() override; @@ -87,6 +110,14 @@ public: ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); } +#ifdef DEBUG + void MarkIntrinsicISizesDirty() override + { + // Need another Reflow to have a correct baseline value again. + mFirstBaseline = NS_INTRINSIC_WIDTH_UNKNOWN; + } +#endif + // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) override; virtual void AppendAnonymousContentTo(nsTArray& aElements, @@ -300,6 +331,10 @@ private: } private: + // Our first baseline, or NS_INTRINSIC_WIDTH_UNKNOWN if we have a pending + // Reflow. + nscoord mFirstBaseline; + // these packed bools could instead use the high order bits on mState, saving 4 bytes bool mEditorHasBeenInitialized; bool mIsProcessing; diff --git a/layout/reftests/bugs/315920-17.html b/layout/reftests/bugs/315920-17.html index 1681754a5..6d9180144 100644 --- a/layout/reftests/bugs/315920-17.html +++ b/layout/reftests/bugs/315920-17.html @@ -1,5 +1,5 @@ - + - +

@@ -19,5 +17,14 @@
+ diff --git a/layout/reftests/forms/display-block-baselines-1-ref.html b/layout/reftests/forms/display-block-baselines-1-ref.html new file mode 100644 index 000000000..d01c086b5 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-1-ref.html @@ -0,0 +1,91 @@ + + + + + Reference: Testcase #1 for bug 1330962 + + + + +
+
+ A +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A
+
+
+ B +
+ +
+
+ A
+
+
+ B +
+ +
+
+ A
+
+
+ B +
+ +
+
+ A
+
+
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-1.html b/layout/reftests/forms/display-block-baselines-1.html new file mode 100644 index 000000000..96ebdad71 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-1.html @@ -0,0 +1,92 @@ + + + + + Testcase #1 for bug 1330962 + + + + +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-2-ref.html b/layout/reftests/forms/display-block-baselines-2-ref.html new file mode 100644 index 000000000..441a927b4 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-2-ref.html @@ -0,0 +1,100 @@ + + + + + Reference: Testcase #2 for bug 1330962 + + + + +
+
+ A
+
+
+ B +
+ +
+
+ A
+
+
+ B +
+ +
+
+ A
+
+
+ B +
+ +
+
+ A
+ +
+ B +
button-first
button-last
+
+ +
+
+ A
+ +
+ B +
button-firstbutton-last
+
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-2.html b/layout/reftests/forms/display-block-baselines-2.html new file mode 100644 index 000000000..78253fe4c --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-2.html @@ -0,0 +1,100 @@ + + + + + Testcase #2 for bug 1330962 + + + + +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B + +
+ +
+
+ A + +
+ B + +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-3-ref.html b/layout/reftests/forms/display-block-baselines-3-ref.html new file mode 100644 index 000000000..ce277b50c --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-3-ref.html @@ -0,0 +1,72 @@ + + + + + Reference: Testcase #3 for bug 1330962 + + + + +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A
+
fieldset-first
fieldset-last
+
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-3.html b/layout/reftests/forms/display-block-baselines-3.html new file mode 100644 index 000000000..9f3c2b110 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-3.html @@ -0,0 +1,73 @@ + + + + + Testcase #3 for bug 1330962 + + + + +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A +
fieldset-first
fieldset-last
+
+ B +
+ + + + diff --git a/layout/reftests/forms/display-block-baselines-4-ref.html b/layout/reftests/forms/display-block-baselines-4-ref.html new file mode 100644 index 000000000..5015d50c4 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-4-ref.html @@ -0,0 +1,73 @@ + + + + + Reference: Testcase #4 for bug 1330962 + + + + +
+
+ A
+
legend +fieldset-first
fieldset-last
+
+ B +
+ +
+
+ A
+
grid-fieldset-firstgrid-fieldset-last
+
+ B +
+ +
+
+ A
+
fieldset-first
fieldset-last
+
+ B +
+ +
+
+ A
+
fieldset-first
fieldset-last
+
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-4.html b/layout/reftests/forms/display-block-baselines-4.html new file mode 100644 index 000000000..1bfd344b0 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-4.html @@ -0,0 +1,74 @@ + + + + + Testcase #4 for bug 1330962 + + + + +
+
+ A +
legend +fieldset-first
fieldset-last
+
+ B +
+ +
+
+ A +
grid-fieldset-lastgrid-fieldset-first
+
+ B +
+ +
+
+ A +
fieldset-first
fieldset-last
+
+ B +
+ +
+
+ A +
fieldset-first
fieldset-last
+
+ B +
+ + + + diff --git a/layout/reftests/forms/display-block-baselines-5-ref.html b/layout/reftests/forms/display-block-baselines-5-ref.html new file mode 100644 index 000000000..0dce47f59 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-5-ref.html @@ -0,0 +1,72 @@ + + + + + Reference: Testcase #5 for bug 1330962 + + + + +
+
+ A
+ +
+ B +
+ +
+
+ A
+ +
+ B +
+ +
+
+ A
+ +
+ B +
+ +
+
+ A
+ +
+ B +
+ + + diff --git a/layout/reftests/forms/display-block-baselines-5.html b/layout/reftests/forms/display-block-baselines-5.html new file mode 100644 index 000000000..0359c8a6f --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-5.html @@ -0,0 +1,72 @@ + + + + + Testcase #5 for bug 1330962 + + + + +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ +
+
+ A + +
+ B +
+ + + diff --git a/layout/reftests/forms/reftest.list b/layout/reftests/forms/reftest.list index d45db276f..c7532077b 100644 --- a/layout/reftests/forms/reftest.list +++ b/layout/reftests/forms/reftest.list @@ -1,4 +1,9 @@ fuzzy-if(skiaContent,1,10) HTTP(..) == text-control-baseline-1.html text-control-baseline-1-ref.html +fuzzy-if(cocoaWidget,16,64) fuzzy-if(Android,52,64) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),104,224) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),57,400) == display-block-baselines-1.html display-block-baselines-1-ref.html # anti-aliasing issues +== display-block-baselines-2.html display-block-baselines-2-ref.html +== display-block-baselines-3.html display-block-baselines-3-ref.html +== display-block-baselines-4.html display-block-baselines-4-ref.html +fuzzy-if(Android,4,8) == display-block-baselines-5.html display-block-baselines-5-ref.html # button element include button/reftest.list -- cgit v1.2.3 From 1df7811e8e7943bf94ca7164c7c173a5c622db7b Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 12 Mar 2018 09:52:05 +0100 Subject: Bump Goanna version for CSS improvements. --- config/milestone.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/milestone.txt b/config/milestone.txt index 05d41f934..27f2d007f 100644 --- a/config/milestone.txt +++ b/config/milestone.txt @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -4.1.0 +4.1.1 -- cgit v1.2.3 From 93f8e06bb8d8656e868679d584c7c8771ff8e42f Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Thu, 17 Aug 2017 20:37:46 +0200 Subject: JS - RegExp - match updated spec for `/\b/iu` and `/\B/iu` --- js/src/irregexp/RegExpEngine.cpp | 25 ++++++++++++++++------ js/src/irregexp/RegExpEngine.h | 8 +++++-- .../RegExp/unicode-ignoreCase-word-boundary.js | 25 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js diff --git a/js/src/irregexp/RegExpEngine.cpp b/js/src/irregexp/RegExpEngine.cpp index 2e19065fd..7116ff1e5 100644 --- a/js/src/irregexp/RegExpEngine.cpp +++ b/js/src/irregexp/RegExpEngine.cpp @@ -2358,7 +2358,10 @@ void BoyerMoorePositionInfo::SetInterval(const Interval& interval) { s_ = AddRange(s_, kSpaceRanges, kSpaceRangeCount, interval); - w_ = AddRange(w_, kWordRanges, kWordRangeCount, interval); + if (unicode_ignore_case_) + w_ = AddRange(w_, kIgnoreCaseWordRanges, kIgnoreCaseWordRangeCount, interval); + else + w_ = AddRange(w_, kWordRanges, kWordRangeCount, interval); d_ = AddRange(d_, kDigitRanges, kDigitRangeCount, interval); surrogate_ = AddRange(surrogate_, kSurrogateRanges, kSurrogateRangeCount, interval); @@ -2395,11 +2398,12 @@ BoyerMoorePositionInfo::SetAll() BoyerMooreLookahead::BoyerMooreLookahead(LifoAlloc* alloc, size_t length, RegExpCompiler* compiler) : length_(length), compiler_(compiler), bitmaps_(*alloc) { + bool unicode_ignore_case = compiler->unicode() && compiler->ignore_case(); max_char_ = MaximumCharacter(compiler->ascii()); bitmaps_.reserve(length); for (size_t i = 0; i < length; i++) - bitmaps_.append(alloc->newInfallible(alloc)); + bitmaps_.append(alloc->newInfallible(alloc, unicode_ignore_case)); } // Find the longest range of lookahead that has the fewest number of different @@ -3065,15 +3069,22 @@ EmitNotInSurrogatePair(RegExpCompiler* compiler, RegExpNode* on_success, Trace* // Check for [0-9A-Z_a-z]. static void EmitWordCheck(RegExpMacroAssembler* assembler, - jit::Label* word, jit::Label* non_word, bool fall_through_on_word) + jit::Label* word, jit::Label* non_word, bool fall_through_on_word, + bool unicode_ignore_case) { - if (assembler->CheckSpecialCharacterClass(fall_through_on_word ? 'w' : 'W', + if (!unicode_ignore_case && + assembler->CheckSpecialCharacterClass(fall_through_on_word ? 'w' : 'W', fall_through_on_word ? non_word : word)) { // Optimized implementation available. return; } + if (unicode_ignore_case) { + assembler->CheckCharacter(0x017F, word); + assembler->CheckCharacter(0x212A, word); + } + assembler->CheckCharacterGT('z', non_word); assembler->CheckCharacterLT('0', non_word); assembler->CheckCharacterGT('a' - 1, word); @@ -3122,7 +3133,8 @@ AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word); } // Fall through on non-word. - EmitWordCheck(assembler, &before_word, &before_non_word, false); + EmitWordCheck(assembler, &before_word, &before_non_word, false, + compiler->unicode() && compiler->ignore_case()); // Next character is not a word character. assembler->Bind(&before_non_word); jit::Label ok; @@ -3162,7 +3174,8 @@ AssertionNode::BacktrackIfPrevious(RegExpCompiler* compiler, // We already checked that we are not at the start of input so it must be // OK to load the previous character. assembler->LoadCurrentCharacter(new_trace.cp_offset() - 1, &dummy, false); - EmitWordCheck(assembler, word, non_word, backtrack_if_previous == kIsNonWord); + EmitWordCheck(assembler, word, non_word, backtrack_if_previous == kIsNonWord, + compiler->unicode() && compiler->ignore_case()); assembler->Bind(&fall_through); on_success()->Emit(compiler, &new_trace); diff --git a/js/src/irregexp/RegExpEngine.h b/js/src/irregexp/RegExpEngine.h index 78c784aaf..1a8fd4b22 100644 --- a/js/src/irregexp/RegExpEngine.h +++ b/js/src/irregexp/RegExpEngine.h @@ -1195,13 +1195,14 @@ AddRange(ContainedInLattice a, class BoyerMoorePositionInfo { public: - explicit BoyerMoorePositionInfo(LifoAlloc* alloc) + explicit BoyerMoorePositionInfo(LifoAlloc* alloc, bool unicode_ignore_case) : map_(*alloc), map_count_(0), w_(kNotYet), s_(kNotYet), d_(kNotYet), - surrogate_(kNotYet) + surrogate_(kNotYet), + unicode_ignore_case_(unicode_ignore_case) { map_.reserve(kMapSize); for (int i = 0; i < kMapSize; i++) @@ -1228,6 +1229,9 @@ class BoyerMoorePositionInfo ContainedInLattice s_; // The \s character class. ContainedInLattice d_; // The \d character class. ContainedInLattice surrogate_; // Surrogate UTF-16 code units. + + // True if the RegExp has unicode and ignoreCase flags. + bool unicode_ignore_case_; }; typedef InfallibleVector BoyerMoorePositionInfoVector; diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js new file mode 100644 index 000000000..c1a04bd3d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js @@ -0,0 +1,25 @@ +var BUGNUMBER = 1338373; +var summary = "Word boundary should match U+017F and U+212A in unicode+ignoreCase."; + +assertEq(/\b/iu.test('\u017F'), true); +assertEq(/\b/i.test('\u017F'), false); +assertEq(/\b/u.test('\u017F'), false); +assertEq(/\b/.test('\u017F'), false); + +assertEq(/\b/iu.test('\u212A'), true); +assertEq(/\b/i.test('\u212A'), false); +assertEq(/\b/u.test('\u212A'), false); +assertEq(/\b/.test('\u212A'), false); + +assertEq(/\B/iu.test('\u017F'), false); +assertEq(/\B/i.test('\u017F'), true); +assertEq(/\B/u.test('\u017F'), true); +assertEq(/\B/.test('\u017F'), true); + +assertEq(/\B/iu.test('\u212A'), false); +assertEq(/\B/i.test('\u212A'), true); +assertEq(/\B/u.test('\u212A'), true); +assertEq(/\B/.test('\u212A'), true); + +if (typeof reportCompare === "function") + reportCompare(true, true); -- cgit v1.2.3 From 6be9e507077bfdd2b8c82c203cf70f010ecce086 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Fri, 18 Aug 2017 06:04:15 +0200 Subject: HTML - implement the labels attribute --- dom/base/FragmentOrElement.cpp | 4 + dom/base/FragmentOrElement.h | 6 + dom/base/nsContentList.cpp | 143 ++++++++++++-- dom/base/nsContentList.h | 40 +++- dom/base/nsGkAtomList.h | 1 + dom/base/test/test_bug1375050.html | 33 ++++ dom/html/HTMLInputElement.cpp | 10 + dom/html/HTMLInputElement.h | 2 + dom/html/HTMLLabelElement.cpp | 23 ++- dom/html/nsGenericHTMLElement.cpp | 40 ++++ dom/html/nsGenericHTMLElement.h | 6 + .../forms/test_button_attributes_reflection.html | 9 +- dom/webidl/HTMLButtonElement.webidl | 3 +- dom/webidl/HTMLInputElement.webidl | 2 +- dom/webidl/HTMLMeterElement.webidl | 5 +- dom/webidl/HTMLOutputElement.webidl | 3 +- dom/webidl/HTMLProgressElement.webidl | 6 +- dom/webidl/HTMLSelectElement.webidl | 2 +- dom/webidl/HTMLTextAreaElement.webidl | 2 +- .../the-label-element/label-attributes.html.ini | 17 -- .../the-label-element/labelable-elements.html.ini | 24 +-- .../Forms/contents/Forms/button_labels.html.ini | 5 - .../Forms/contents/Forms/input_labels.html.ini | 5 - .../the-label-element/iframe-label-attributes.html | 8 + .../forms/the-label-element/label-attributes.html | 212 ++++++++++++++++++++- 25 files changed, 516 insertions(+), 95 deletions(-) create mode 100644 dom/base/test/test_bug1375050.html delete mode 100644 testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini delete mode 100644 testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/button_labels.html.ini delete mode 100644 testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/input_labels.html.ini create mode 100644 testing/web-platform/tests/html/semantics/forms/the-label-element/iframe-label-attributes.html diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 293177ce7..3112515ff 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -574,6 +574,9 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList"); cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList)); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mLabelsList"); + cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mLabelsList)); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList"); cb.NoteXPCOMChild(mClassList.get()); @@ -602,6 +605,7 @@ FragmentOrElement::nsDOMSlots::Unlink(bool aIsXUL) mShadowRoot = nullptr; mContainingShadow = nullptr; mChildrenList = nullptr; + mLabelsList = nullptr; mCustomElementData = nullptr; mClassList = nullptr; } diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h index 3cb5575fe..1cd8033bb 100644 --- a/dom/base/FragmentOrElement.h +++ b/dom/base/FragmentOrElement.h @@ -24,6 +24,7 @@ class ContentUnbinder; class nsContentList; +class nsLabelsNodeList; class nsDOMAttributeMap; class nsDOMTokenList; class nsIControllers; @@ -313,6 +314,11 @@ public: */ RefPtr mClassList; + /* + * An object implementing the .labels property for this element. + */ + RefPtr mLabelsList; + /** * ShadowRoot bound to the element. */ diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp index 09e949009..43e65777d 100644 --- a/dom/base/nsContentList.cpp +++ b/dom/base/nsContentList.cpp @@ -254,19 +254,6 @@ const nsCacheableFuncStringContentList::ContentListType nsCacheableFuncStringHTMLCollection::sType = nsCacheableFuncStringContentList::eHTMLCollection; #endif -JSObject* -nsCacheableFuncStringNodeList::WrapObject(JSContext *cx, JS::Handle aGivenProto) -{ - return NodeListBinding::Wrap(cx, this, aGivenProto); -} - - -JSObject* -nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle aGivenProto) -{ - return HTMLCollectionBinding::Wrap(cx, this, aGivenProto); -} - // Hashtable for storing nsCacheableFuncStringContentList static PLDHashTable* gFuncStringContentListHashTable; @@ -379,6 +366,7 @@ NS_GetFuncStringHTMLCollection(nsINode* aRootNode, aString); } +//----------------------------------------------------- // nsContentList implementation nsContentList::nsContentList(nsINode* aRootNode, @@ -660,7 +648,7 @@ nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement, const nsAttrValue* aOldValue) { NS_PRECONDITION(aElement, "Must have a content node to work with"); - + if (!mFunc || !mFuncMayDependOnAttr || mState == LIST_DIRTY || !MayContainRelevantNodes(aElement->GetParentNode()) || !nsContentUtils::IsInSameAnonymousTree(mRootNode, aElement)) { @@ -806,7 +794,7 @@ nsContentList::ContentInserted(nsIDocument *aDocument, ASSERT_IN_SYNC; } - + void nsContentList::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer, @@ -1075,3 +1063,128 @@ nsContentList::AssertInSync() NS_ASSERTION(cnt == mElements.Length(), "Too few elements"); } #endif + +//----------------------------------------------------- +// nsCacheableFuncStringNodeList + +JSObject* +nsCacheableFuncStringNodeList::WrapObject(JSContext *cx, JS::Handle aGivenProto) +{ + return NodeListBinding::Wrap(cx, this, aGivenProto); +} + +//----------------------------------------------------- +// nsCacheableFuncStringHTMLCollection + +JSObject* +nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle aGivenProto) +{ + return HTMLCollectionBinding::Wrap(cx, this, aGivenProto); +} + +//----------------------------------------------------- +// nsLabelsNodeList + +JSObject* +nsLabelsNodeList::WrapObject(JSContext *cx, JS::Handle aGivenProto) +{ + return NodeListBinding::Wrap(cx, this, aGivenProto); +} + +void +nsLabelsNodeList::AttributeChanged(nsIDocument* aDocument, Element* aElement, + int32_t aNameSpaceID, nsIAtom* aAttribute, + int32_t aModType, + const nsAttrValue* aOldValue) +{ + MOZ_ASSERT(aElement, "Must have a content node to work with"); + if (mState == LIST_DIRTY || + !nsContentUtils::IsInSameAnonymousTree(mRootNode, aElement)) { + return; + } + + // We need to handle input type changes to or from "hidden". + if (aElement->IsHTMLElement(nsGkAtoms::input) && + aAttribute == nsGkAtoms::type && aNameSpaceID == kNameSpaceID_None) { + SetDirty(); + return; + } +} + +void +nsLabelsNodeList::ContentAppended(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aFirstNewContent, + int32_t aNewIndexInContainer) +{ + // If a labelable element is moved to outside or inside of + // nested associated labels, we're gonna have to modify + // the content list. + if (mState != LIST_DIRTY || + nsContentUtils::IsInSameAnonymousTree(mRootNode, aContainer)) { + SetDirty(); + return; + } +} + +void +nsLabelsNodeList::ContentInserted(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + int32_t aIndexInContainer) +{ + // If a labelable element is moved to outside or inside of + // nested associated labels, we're gonna have to modify + // the content list. + if (mState != LIST_DIRTY || + nsContentUtils::IsInSameAnonymousTree(mRootNode, aChild)) { + SetDirty(); + return; + } +} + +void +nsLabelsNodeList::ContentRemoved(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + int32_t aIndexInContainer, + nsIContent* aPreviousSibling) +{ + // If a labelable element is removed, we're gonna have to clean + // the content list. + if (mState != LIST_DIRTY || + nsContentUtils::IsInSameAnonymousTree(mRootNode, aChild)) { + SetDirty(); + return; + } +} + +void +nsLabelsNodeList::MaybeResetRoot(nsINode* aRootNode) +{ + MOZ_ASSERT(aRootNode, "Must have root"); + if (mRootNode == aRootNode) { + return; + } + + if (mRootNode) { + mRootNode->RemoveMutationObserver(this); + } + mRootNode = aRootNode; + mRootNode->AddMutationObserver(this); + SetDirty(); +} + +void +nsLabelsNodeList::PopulateSelf(uint32_t aNeededLength) +{ + MOZ_ASSERT(mRootNode, "Must have root"); + + // Start searching at the root. + nsINode* cur = mRootNode; + if (mElements.IsEmpty() && cur->IsElement() && Match(cur->AsElement())) { + mElements.AppendElement(cur->AsElement()); + } + + nsContentList::PopulateSelf(aNeededLength); +} diff --git a/dom/base/nsContentList.h b/dom/base/nsContentList.h index 3878074b2..83d27da95 100644 --- a/dom/base/nsContentList.h +++ b/dom/base/nsContentList.h @@ -371,9 +371,9 @@ protected: * traversed the whole document (or both). * * @param aNeededLength the length the list should have when we are - * done (unless it exhausts the document) + * done (unless it exhausts the document) */ - void PopulateSelf(uint32_t aNeededLength); + virtual void PopulateSelf(uint32_t aNeededLength); /** * @param aContainer a content node which must be a descendant of @@ -584,4 +584,40 @@ public: #endif }; +class nsLabelsNodeList final : public nsContentList +{ +public: + nsLabelsNodeList(nsINode* aRootNode, + nsContentListMatchFunc aFunc, + nsContentListDestroyFunc aDestroyFunc, + void* aData) + : nsContentList(aRootNode, aFunc, aDestroyFunc, aData) + { + } + + NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED + NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED + NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED + NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED + + virtual JSObject* WrapObject(JSContext *cx, JS::Handle aGivenProto) override; + + /** + * Reset root, mutation observer, and clear content list + * if the root has been changed. + * + * @param aRootNode The node under which to limit our search. + */ + void MaybeResetRoot(nsINode* aRootNode); + +private: + /** + * Start searching at the last one if we already have nodes, otherwise + * start searching at the root. + * + * @param aNeededLength The list of length should have when we are + * done (unless it exhausts the document). + */ + void PopulateSelf(uint32_t aNeededLength) override; +}; #endif // nsContentList_h___ diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 91427fabb..e4ae7ede8 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -526,6 +526,7 @@ GK_ATOM(keytext, "keytext") GK_ATOM(keyup, "keyup") GK_ATOM(kind, "kind") GK_ATOM(label, "label") +GK_ATOM(labels, "labels") GK_ATOM(lang, "lang") GK_ATOM(language, "language") GK_ATOM(last, "last") diff --git a/dom/base/test/test_bug1375050.html b/dom/base/test/test_bug1375050.html new file mode 100644 index 000000000..b91b859d0 --- /dev/null +++ b/dom/base/test/test_bug1375050.html @@ -0,0 +1,33 @@ + + + + + + Test for Bug 1375050 + + + + + +Mozilla Bug 1375050 +

+ +
+
+ + diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 78f74ae0c..d46eccdbc 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -8800,6 +8800,16 @@ HTMLInputElement::GetWebkitEntries(nsTArray>& aSequence) aSequence.AppendElements(mEntries); } +already_AddRefed +HTMLInputElement::GetLabels() +{ + if (!IsLabelable()) { + return nullptr; + } + + return nsGenericHTMLElement::Labels(); +} + } // namespace dom } // namespace mozilla diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index e5d670e08..9ca876aee 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -704,6 +704,8 @@ public: // XPCOM GetCustomVisibility() is OK + already_AddRefed GetLabels(); + // XPCOM Select() is OK Nullable GetSelectionStart(ErrorResult& aRv); diff --git a/dom/html/HTMLLabelElement.cpp b/dom/html/HTMLLabelElement.cpp index c1d22b0a6..d1c037336 100644 --- a/dom/html/HTMLLabelElement.cpp +++ b/dom/html/HTMLLabelElement.cpp @@ -14,6 +14,7 @@ #include "nsFocusManager.h" #include "nsIDOMMouseEvent.h" #include "nsQueryObject.h" +#include "mozilla/dom/ShadowRoot.h" // construction, destruction @@ -268,17 +269,23 @@ HTMLLabelElement::GetLabeledElement() const return GetFirstLabelableDescendant(); } - // We have a @for. The id has to be linked to an element in the same document + // We have a @for. The id has to be linked to an element in the same tree // and this element should be a labelable form control. - //XXXsmaug It is unclear how this should work in case the element is in - // Shadow DOM. - // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=26365. - nsIDocument* doc = GetUncomposedDoc(); - if (!doc) { - return nullptr; + nsINode* root = SubtreeRoot(); + ShadowRoot* shadow = ShadowRoot::FromNode(root); + Element* element = nullptr; + + if (shadow) { + element = shadow->GetElementById(elementId); + } else { + nsIDocument* doc = GetUncomposedDoc(); + if (doc) { + element = doc->GetElementById(elementId); + } else { + element = nsContentUtils::MatchElementId(root->AsContent(), elementId); + } } - Element* element = doc->GetElementById(elementId); if (element && element->IsLabelable()) { return static_cast(element); } diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index d75001a83..2f890325a 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -108,6 +108,7 @@ #include "mozilla/StyleSetHandle.h" #include "mozilla/StyleSetHandleInlines.h" #include "ReferrerPolicy.h" +#include "mozilla/dom/HTMLLabelElement.h" using namespace mozilla; using namespace mozilla::dom; @@ -493,6 +494,14 @@ nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, } } + // We need to consider a labels element is moved to another subtree + // with different root, it needs to update labels list and its root + // as well. + nsDOMSlots* slots = GetExistingDOMSlots(); + if (slots && slots->mLabelsList) { + slots->mLabelsList->MaybeResetRoot(SubtreeRoot()); + } + return rv; } @@ -513,6 +522,13 @@ nsGenericHTMLElement::UnbindFromTree(bool aDeep, bool aNullParent) } } + // We need to consider a labels element is removed from tree, + // it needs to update labels list and its root as well. + nsDOMSlots* slots = GetExistingDOMSlots(); + if (slots && slots->mLabelsList) { + slots->mLabelsList->MaybeResetRoot(SubtreeRoot()); + } + nsStyledElement::UnbindFromTree(aDeep, aNullParent); } @@ -1701,6 +1717,30 @@ nsGenericHTMLElement::IsLabelable() const return IsAnyOfHTMLElements(nsGkAtoms::progress, nsGkAtoms::meter); } +/* static */ bool +nsGenericHTMLElement::MatchLabelsElement(Element* aElement, int32_t aNamespaceID, + nsIAtom* aAtom, void* aData) +{ + HTMLLabelElement* element = HTMLLabelElement::FromContent(aElement); + return element && element->GetControl() == aData; +} + +already_AddRefed +nsGenericHTMLElement::Labels() +{ + MOZ_ASSERT(IsLabelable(), + "Labels() only allow labelable elements to use it."); + nsDOMSlots* slots = DOMSlots(); + + if (!slots->mLabelsList) { + slots->mLabelsList = new nsLabelsNodeList(SubtreeRoot(), MatchLabelsElement, + nullptr, this); + } + + RefPtr labels = slots->mLabelsList; + return labels.forget(); +} + bool nsGenericHTMLElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index 3cca41c3d..0635c27e1 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -834,6 +834,12 @@ public: } virtual bool IsLabelable() const override; + + static bool MatchLabelsElement(Element* aElement, int32_t aNamespaceID, + nsIAtom* aAtom, void* aData); + + already_AddRefed Labels(); + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override; static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */); diff --git a/dom/html/test/forms/test_button_attributes_reflection.html b/dom/html/test/forms/test_button_attributes_reflection.html index 26858e939..4e702b3ac 100644 --- a/dom/html/test/forms/test_button_attributes_reflection.html +++ b/dom/html/test/forms/test_button_attributes_reflection.html @@ -128,9 +128,12 @@ is(typeof(document.createElement("button").setCustomValidity), "function", "button.setCustomValidity should be a function"); // .labels -todo("labels" in document.createElement("button"), - "button.labels isn't implemented yet"); - +ok("labels" in document.createElement("button"), + "button.labels should be an IDL attribute of the button element"); +is(typeof(document.createElement("button").labels), "object", + "button.labels should be an object"); +ok(document.createElement("button").labels instanceof NodeList, + "button.labels sohuld be an instance of NodeList");
diff --git a/dom/webidl/HTMLButtonElement.webidl b/dom/webidl/HTMLButtonElement.webidl index c50e09ae0..579efa39c 100644 --- a/dom/webidl/HTMLButtonElement.webidl +++ b/dom/webidl/HTMLButtonElement.webidl @@ -44,6 +44,5 @@ interface HTMLButtonElement : HTMLElement { boolean reportValidity(); void setCustomValidity(DOMString error); -// Not yet implemented: -// readonly attribute NodeList labels; + readonly attribute NodeList labels; }; diff --git a/dom/webidl/HTMLInputElement.webidl b/dom/webidl/HTMLInputElement.webidl index d3d537f84..050d19510 100644 --- a/dom/webidl/HTMLInputElement.webidl +++ b/dom/webidl/HTMLInputElement.webidl @@ -111,7 +111,7 @@ interface HTMLInputElement : HTMLElement { boolean reportValidity(); void setCustomValidity(DOMString error); - // Bug 850365 readonly attribute NodeList labels; + readonly attribute NodeList? labels; void select(); diff --git a/dom/webidl/HTMLMeterElement.webidl b/dom/webidl/HTMLMeterElement.webidl index 1f80764e9..104e00353 100644 --- a/dom/webidl/HTMLMeterElement.webidl +++ b/dom/webidl/HTMLMeterElement.webidl @@ -26,8 +26,5 @@ interface HTMLMeterElement : HTMLElement { [SetterThrows] attribute double optimum; - /** - * The labels attribute will be done with bug 556743. - */ - //readonly attribute NodeList labels; + readonly attribute NodeList labels; }; diff --git a/dom/webidl/HTMLOutputElement.webidl b/dom/webidl/HTMLOutputElement.webidl index 05dcf1800..d0e4ecbe6 100644 --- a/dom/webidl/HTMLOutputElement.webidl +++ b/dom/webidl/HTMLOutputElement.webidl @@ -33,6 +33,5 @@ interface HTMLOutputElement : HTMLElement { boolean reportValidity(); void setCustomValidity(DOMString error); -// Not yet implemented (bug 556743). -// readonly attribute NodeList labels; + readonly attribute NodeList labels; }; diff --git a/dom/webidl/HTMLProgressElement.webidl b/dom/webidl/HTMLProgressElement.webidl index 3d1000d22..028728e22 100644 --- a/dom/webidl/HTMLProgressElement.webidl +++ b/dom/webidl/HTMLProgressElement.webidl @@ -17,9 +17,5 @@ interface HTMLProgressElement : HTMLElement { [SetterThrows] attribute double max; readonly attribute double position; - - /** - * The labels attribute will be done with bug 567740. - */ - //readonly attribute NodeList labels; + readonly attribute NodeList labels; }; diff --git a/dom/webidl/HTMLSelectElement.webidl b/dom/webidl/HTMLSelectElement.webidl index 74fc7b2cf..b18ca3634 100644 --- a/dom/webidl/HTMLSelectElement.webidl +++ b/dom/webidl/HTMLSelectElement.webidl @@ -53,7 +53,7 @@ interface HTMLSelectElement : HTMLElement { boolean reportValidity(); void setCustomValidity(DOMString error); -// NYI: readonly attribute NodeList labels; + readonly attribute NodeList labels; // https://www.w3.org/Bugs/Public/show_bug.cgi?id=20720 void remove(); diff --git a/dom/webidl/HTMLTextAreaElement.webidl b/dom/webidl/HTMLTextAreaElement.webidl index b1005ed42..4df687a0b 100644 --- a/dom/webidl/HTMLTextAreaElement.webidl +++ b/dom/webidl/HTMLTextAreaElement.webidl @@ -57,7 +57,7 @@ interface HTMLTextAreaElement : HTMLElement { boolean reportValidity(); void setCustomValidity(DOMString error); - // readonly attribute NodeList labels; + readonly attribute NodeList labels; void select(); [Throws] diff --git a/testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini b/testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini deleted file mode 100644 index e1a2e38b5..000000000 --- a/testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini +++ /dev/null @@ -1,17 +0,0 @@ -[label-attributes.html] - type: testharness - [A non-control follows by a control with same ID.] - expected: FAIL - - [A form control has multiple labels.] - expected: FAIL - - [A form control has no label 1.] - expected: FAIL - - [A form control has no label 2.] - expected: FAIL - - [A form control has an implicit label.] - expected: FAIL - diff --git a/testing/web-platform/meta/html/semantics/forms/the-label-element/labelable-elements.html.ini b/testing/web-platform/meta/html/semantics/forms/the-label-element/labelable-elements.html.ini index bfa61edb7..363324f2e 100644 --- a/testing/web-platform/meta/html/semantics/forms/the-label-element/labelable-elements.html.ini +++ b/testing/web-platform/meta/html/semantics/forms/the-label-element/labelable-elements.html.ini @@ -1,29 +1,7 @@ [labelable-elements.html] type: testharness - [Check if the output element can access 'labels'] - expected: FAIL - - [Check if the progress element can access 'labels'] - expected: FAIL - - [Check if the select element can access 'labels'] - expected: FAIL - - [Check if the textarea element can access 'labels'] - expected: FAIL - - [Check if the button element can access 'labels'] - expected: FAIL - - [Check if the hidden input element can access 'labels'] - expected: FAIL - - [Check if the input element in radio state can access 'labels'] + [Check if the keygen element is not a labelable element] expected: FAIL [Check if the keygen element can access 'labels'] expected: FAIL - - [Check if the meter element can access 'labels'] - expected: FAIL - diff --git a/testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/button_labels.html.ini b/testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/button_labels.html.ini deleted file mode 100644 index e4a30320e..000000000 --- a/testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/button_labels.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[button_labels.html] - type: testharness - [Forms] - expected: FAIL - diff --git a/testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/input_labels.html.ini b/testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/input_labels.html.ini deleted file mode 100644 index da0fb96d7..000000000 --- a/testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/input_labels.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[input_labels.html] - type: testharness - [Forms] - expected: FAIL - diff --git a/testing/web-platform/tests/html/semantics/forms/the-label-element/iframe-label-attributes.html b/testing/web-platform/tests/html/semantics/forms/the-label-element/iframe-label-attributes.html new file mode 100644 index 000000000..56b52c951 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-label-element/iframe-label-attributes.html @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html b/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html index 826533e0c..2910f2c01 100644 --- a/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html +++ b/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html @@ -32,10 +32,53 @@ + + +
+ + +
+ + + + + + +
+
+ +
+
+ - +