summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-03-12 11:18:06 +0100
committerwolfbeast <mcwerewolf@gmail.com>2018-03-12 11:18:06 +0100
commitba74a4174d2cd6ccbabbc5aa6f4ffdf74b48f45c (patch)
tree42296be483ab2f1f3042f5aca8ce91c2aa669ec3
parenteda34d02aa8159def0d811846e9417c37cea15cd (diff)
parent519775b8d9d823b8cee786bc668e050110a8aa67 (diff)
downloaduxp-ba74a4174d2cd6ccbabbc5aa6f4ffdf74b48f45c.tar.gz
Merge branch 'ported-moebius'
-rw-r--r--config/milestone.txt2
-rw-r--r--devtools/client/webconsole/test/browser_webconsole_strict_mode_errors.js2
-rw-r--r--dom/base/Element.cpp5
-rw-r--r--dom/base/Element.h18
-rw-r--r--dom/base/FragmentOrElement.cpp7
-rw-r--r--dom/base/FragmentOrElement.h6
-rw-r--r--dom/base/nsContentList.cpp143
-rw-r--r--dom/base/nsContentList.h40
-rw-r--r--dom/base/nsContentListDeclarations.h8
-rw-r--r--dom/base/nsContentUtils.cpp4
-rw-r--r--dom/base/nsContentUtils.h3
-rw-r--r--dom/base/nsGkAtomList.h3
-rw-r--r--dom/base/nsIContent.h19
-rw-r--r--dom/base/test/test_bug1375050.html33
-rw-r--r--dom/events/EventNameList.h4
-rw-r--r--dom/html/HTMLAllCollection.cpp7
-rw-r--r--dom/html/HTMLDataListElement.cpp6
-rw-r--r--dom/html/HTMLDataListElement.h4
-rw-r--r--dom/html/HTMLFieldSetElement.cpp4
-rw-r--r--dom/html/HTMLFieldSetElement.h4
-rw-r--r--dom/html/HTMLInputElement.cpp10
-rw-r--r--dom/html/HTMLInputElement.h2
-rw-r--r--dom/html/HTMLLabelElement.cpp23
-rw-r--r--dom/html/HTMLSelectElement.cpp4
-rw-r--r--dom/html/HTMLSelectElement.h2
-rw-r--r--dom/html/HTMLTableRowElement.cpp4
-rw-r--r--dom/html/nsGenericHTMLElement.cpp40
-rw-r--r--dom/html/nsGenericHTMLElement.h6
-rw-r--r--dom/html/nsHTMLDocument.cpp36
-rw-r--r--dom/html/nsHTMLDocument.h11
-rw-r--r--dom/html/test/forms/test_button_attributes_reflection.html9
-rw-r--r--dom/svg/SVGGradientElement.cpp9
-rw-r--r--dom/svg/SVGGradientElement.h7
-rw-r--r--dom/webidl/Document.webidl3
-rw-r--r--dom/webidl/HTMLButtonElement.webidl3
-rw-r--r--dom/webidl/HTMLInputElement.webidl2
-rw-r--r--dom/webidl/HTMLMeterElement.webidl5
-rw-r--r--dom/webidl/HTMLOutputElement.webidl3
-rw-r--r--dom/webidl/HTMLProgressElement.webidl6
-rw-r--r--dom/webidl/HTMLSelectElement.webidl2
-rw-r--r--dom/webidl/HTMLTextAreaElement.webidl2
-rw-r--r--dom/webidl/SVGRadialGradientElement.webidl4
-rw-r--r--dom/workers/WorkerScope.cpp7
-rw-r--r--dom/workers/Workers.h8
-rw-r--r--dom/xul/XULDocument.cpp14
-rw-r--r--dom/xul/XULDocument.h2
-rw-r--r--image/DrawResult.h1
-rw-r--r--js/src/js.msg2
-rw-r--r--js/src/jsobj.cpp12
-rw-r--r--js/src/jsobj.h3
-rw-r--r--layout/base/nsLayoutDebugger.cpp6
-rw-r--r--layout/base/nsLayoutUtils.cpp151
-rw-r--r--layout/base/nsLayoutUtils.h5
-rw-r--r--layout/forms/nsFieldSetFrame.cpp71
-rw-r--r--layout/forms/nsFieldSetFrame.h10
-rw-r--r--layout/forms/nsHTMLButtonControlFrame.cpp41
-rw-r--r--layout/forms/nsHTMLButtonControlFrame.h7
-rw-r--r--layout/forms/nsLegendFrame.h5
-rw-r--r--layout/forms/nsTextControlFrame.cpp11
-rw-r--r--layout/forms/nsTextControlFrame.h35
-rw-r--r--layout/generic/ReflowInput.cpp12
-rw-r--r--layout/generic/ReflowInput.h4
-rw-r--r--layout/generic/nsFrame.cpp2
-rw-r--r--layout/generic/nsGridContainerFrame.cpp109
-rw-r--r--layout/generic/nsIFrame.h8
-rw-r--r--layout/reftests/bugs/315920-17.html15
-rw-r--r--layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html2
-rw-r--r--layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html2
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html78
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-001.html74
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html79
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-002.html75
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html84
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-003.html75
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html88
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-004.html82
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html83
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-005.html77
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html54
-rw-r--r--layout/reftests/css-grid/grid-item-overflow-stretch-006.html56
-rw-r--r--layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html2
-rw-r--r--layout/reftests/css-grid/reftest.list6
-rw-r--r--layout/reftests/forms/display-block-baselines-1-ref.html91
-rw-r--r--layout/reftests/forms/display-block-baselines-1.html92
-rw-r--r--layout/reftests/forms/display-block-baselines-2-ref.html100
-rw-r--r--layout/reftests/forms/display-block-baselines-2.html100
-rw-r--r--layout/reftests/forms/display-block-baselines-3-ref.html72
-rw-r--r--layout/reftests/forms/display-block-baselines-3.html73
-rw-r--r--layout/reftests/forms/display-block-baselines-4-ref.html73
-rw-r--r--layout/reftests/forms/display-block-baselines-4.html74
-rw-r--r--layout/reftests/forms/display-block-baselines-5-ref.html72
-rw-r--r--layout/reftests/forms/display-block-baselines-5.html72
-rw-r--r--layout/reftests/forms/reftest.list5
-rw-r--r--layout/reftests/svg/radialGradient-fr-01.svg27
-rw-r--r--layout/reftests/svg/radialGradient-fr-02-ref.svg28
-rw-r--r--layout/reftests/svg/radialGradient-fr-02.svg27
-rw-r--r--layout/reftests/svg/reftest.list2
-rw-r--r--layout/style/nsCSSParser.cpp7
-rw-r--r--layout/style/test/property_database.js14
-rw-r--r--layout/svg/nsSVGGradientFrame.cpp5
-rw-r--r--testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini17
-rw-r--r--testing/web-platform/meta/html/semantics/forms/the-label-element/labelable-elements.html.ini24
-rw-r--r--testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/button_labels.html.ini5
-rw-r--r--testing/web-platform/meta/old-tests/submission/Infraware/Forms/contents/Forms/input_labels.html.ini5
-rw-r--r--testing/web-platform/meta/svg/interfaces.html.ini6
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-label-element/iframe-label-attributes.html8
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html212
-rw-r--r--testing/web-platform/tests/page-visibility/idlharness.html6
-rw-r--r--widget/EventMessageList.h3
109 files changed, 2894 insertions, 299 deletions
diff --git a/config/milestone.txt b/config/milestone.txt
index 05d41f9342..27f2d007f6 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
diff --git a/devtools/client/webconsole/test/browser_webconsole_strict_mode_errors.js b/devtools/client/webconsole/test/browser_webconsole_strict_mode_errors.js
index c8f2200f9f..cdaf2764e7 100644
--- a/devtools/client/webconsole/test/browser_webconsole_strict_mode_errors.js
+++ b/devtools/client/webconsole/test/browser_webconsole_strict_mode_errors.js
@@ -55,7 +55,7 @@ add_task(function* () {
webconsole: hud,
messages: [
{
- text: "TypeError: setting a property that has only a getter",
+ text: 'TypeError: setting getter-only property "p"',
category: CATEGORY_JS,
severity: SEVERITY_ERROR,
},
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
index 886acc670a..9ced64c0d6 100644
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -165,10 +165,9 @@ nsIContent::DoGetID() const
}
const nsAttrValue*
-nsIContent::DoGetClasses() const
+Element::DoGetClasses() const
{
MOZ_ASSERT(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call");
- MOZ_ASSERT(IsElement(), "Only elements can have classes");
if (IsSVGElement()) {
const nsAttrValue* animClass =
@@ -178,7 +177,7 @@ nsIContent::DoGetClasses() const
}
}
- return AsElement()->GetParsedAttr(nsGkAtoms::_class);
+ return GetParsedAttr(nsGkAtoms::_class);
}
NS_IMETHODIMP
diff --git a/dom/base/Element.h b/dom/base/Element.h
index 5d878df606..cf1d197e2c 100644
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -544,6 +544,18 @@ public:
virtual uint32_t GetAttrCount() const override;
virtual bool IsNodeOfType(uint32_t aFlags) const override;
+ /**
+ * Get the class list of this element (this corresponds to the value of the
+ * class attribute). This may be null if there are no classes, but that's not
+ * guaranteed (e.g. we could have class="").
+ */
+ const nsAttrValue* GetClasses() const {
+ if (HasFlag(NODE_MAY_HAVE_CLASS)) {
+ return DoGetClasses();
+ }
+ return nullptr;
+ }
+
#ifdef DEBUG
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override
{
@@ -1372,6 +1384,12 @@ protected:
private:
/**
+ * Hook for implementing GetClasses. This is guaranteed to only be
+ * called if the NODE_MAY_HAVE_CLASS flag is set.
+ */
+ const nsAttrValue* DoGetClasses() const;
+
+ /**
* Get this element's client area rect in app units.
* @return the frame's client area
*/
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index 293177ce7c..79f6cff51e 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;
}
@@ -1827,7 +1831,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
}
nsAutoString classes;
- const nsAttrValue* classAttrValue = tmp->GetClasses();
+ const nsAttrValue* classAttrValue = tmp->IsElement() ?
+ tmp->AsElement()->GetClasses() : nullptr;
if (classAttrValue) {
classes.AppendLiteral(" class='");
nsAutoString classString;
diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h
index 3cb5575fe0..1cd8033bb5 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<nsDOMTokenList> mClassList;
+ /*
+ * An object implementing the .labels property for this element.
+ */
+ RefPtr<nsLabelsNodeList> mLabelsList;
+
/**
* ShadowRoot bound to the element.
*/
diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp
index 09e9490098..43e65777dc 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<JSObject*> aGivenProto)
-{
- return NodeListBinding::Wrap(cx, this, aGivenProto);
-}
-
-
-JSObject*
-nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle<JSObject*> 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<JSObject*> aGivenProto)
+{
+ return NodeListBinding::Wrap(cx, this, aGivenProto);
+}
+
+//-----------------------------------------------------
+// nsCacheableFuncStringHTMLCollection
+
+JSObject*
+nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
+{
+ return HTMLCollectionBinding::Wrap(cx, this, aGivenProto);
+}
+
+//-----------------------------------------------------
+// nsLabelsNodeList
+
+JSObject*
+nsLabelsNodeList::WrapObject(JSContext *cx, JS::Handle<JSObject*> 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 3878074b21..83d27da950 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<JSObject*> 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/nsContentListDeclarations.h b/dom/base/nsContentListDeclarations.h
index db3a09036b..a5e0e3691b 100644
--- a/dom/base/nsContentListDeclarations.h
+++ b/dom/base/nsContentListDeclarations.h
@@ -18,6 +18,12 @@ class nsINode;
class nsString;
class nsAString;
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
+
// Magic namespace id that means "match all namespaces". This is
// negative so it won't collide with actual namespace constants.
#define kNameSpaceID_Wildcard INT32_MIN
@@ -26,7 +32,7 @@ class nsAString;
// arbitrary matching algorithm. aContent is the content that may
// match the list, while aNamespaceID, aAtom, and aData are whatever
// was passed to the list's constructor.
-typedef bool (*nsContentListMatchFunc)(nsIContent* aContent,
+typedef bool (*nsContentListMatchFunc)(mozilla::dom::Element* aElement,
int32_t aNamespaceID,
nsIAtom* aAtom,
void* aData);
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 1cc352685b..02c6bf1deb 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -6287,11 +6287,11 @@ struct ClassMatchingInfo {
// static
bool
-nsContentUtils::MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
+nsContentUtils::MatchClassNames(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
// We can't match if there are no class names
- const nsAttrValue* classAttr = aContent->GetClasses();
+ const nsAttrValue* classAttr = aElement->GetClasses();
if (!classAttr) {
return false;
}
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index f688eeecf5..0a293d73ea 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2753,7 +2753,8 @@ private:
static void DropFragmentParsers();
- static bool MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
+ static bool MatchClassNames(mozilla::dom::Element* aElement,
+ int32_t aNamespaceID,
nsIAtom* aAtom, void* aData);
static void DestroyClassNameArray(void* aData);
static void* AllocClassMatchingInfo(nsINode* aRootNode,
diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
index 0b76b2bea0..e4ae7ede81 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")
@@ -950,6 +951,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")
@@ -1449,6 +1451,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/base/nsIContent.h b/dom/base/nsIContent.h
index f05c47a615..4050908659 100644
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -862,18 +862,6 @@ public:
}
/**
- * Get the class list of this content node (this corresponds to the
- * value of the class attribute). This may be null if there are no
- * classes, but that's not guaranteed.
- */
- const nsAttrValue* GetClasses() const {
- if (HasFlag(NODE_MAY_HAVE_CLASS)) {
- return DoGetClasses();
- }
- return nullptr;
- }
-
- /**
* Walk aRuleWalker over the content style rules (presentational
* hint rules) for this content node.
*/
@@ -990,13 +978,6 @@ protected:
*/
nsIAtom* DoGetID() const;
-private:
- /**
- * Hook for implementing GetClasses. This is guaranteed to only be
- * called if the NODE_MAY_HAVE_CLASS flag is set.
- */
- const nsAttrValue* DoGetClasses() const;
-
public:
#ifdef DEBUG
/**
diff --git a/dom/base/test/test_bug1375050.html b/dom/base/test/test_bug1375050.html
new file mode 100644
index 0000000000..b91b859d09
--- /dev/null
+++ b/dom/base/test/test_bug1375050.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1375050
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1375050</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ try { o1 = document.createElement('input'); } catch(e) { console.log(e); };
+ try { o2 = document.createElement('col'); } catch(e) { console.log(e); };
+ try { o4 = document.createRange(); } catch(e) { console.log(e); };
+ try { document.documentElement.appendChild(o1); } catch(e) { console.log(e); };
+ try { for (let p in o1) { let x = o1[p] }; } catch(e) { console.log(e); };
+ try { o4.selectNode(o1); } catch(e) { console.log(e); };
+ try { o6 = document.createComment(" x"); } catch(e) { console.log(e); }
+ try { o4.surroundContents(o6); } catch(e) { console.log(e); }
+ try { o7 = document.implementation.createDocument('', '', null).adoptNode(o1); } catch(e) { console.log(e);};
+ try { o2.appendChild(o1); } catch(e) { console.log(e); };
+ ok(true, "Didn't crash.");
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1375050">Mozilla Bug 1375050</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h
index b1be6dd762..ba2427623e 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/html/HTMLAllCollection.cpp b/dom/html/HTMLAllCollection.cpp
index afa160e0ce..6305cce31c 100644
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -8,6 +8,7 @@
#include "mozilla/dom/HTMLAllCollectionBinding.h"
#include "mozilla/dom/Nullable.h"
+#include "mozilla/dom/Element.h"
#include "nsHTMLDocument.h"
namespace mozilla {
@@ -86,14 +87,14 @@ IsAllNamedElement(nsIContent* aContent)
}
static bool
-DocAllResultMatch(nsIContent* aContent, int32_t aNamespaceID, nsIAtom* aAtom,
+DocAllResultMatch(Element* aElement, int32_t aNamespaceID, nsIAtom* aAtom,
void* aData)
{
- if (aContent->GetID() == aAtom) {
+ if (aElement->GetID() == aAtom) {
return true;
}
- nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aContent);
+ nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aElement);
if (!elm) {
return false;
}
diff --git a/dom/html/HTMLDataListElement.cpp b/dom/html/HTMLDataListElement.cpp
index d9ad4da091..5aa772645d 100644
--- a/dom/html/HTMLDataListElement.cpp
+++ b/dom/html/HTMLDataListElement.cpp
@@ -35,11 +35,11 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLDataListElement)
bool
-HTMLDataListElement::MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
+HTMLDataListElement::MatchOptions(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- return aContent->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
- !aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+ return aElement->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
+ !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
}
} // namespace dom
diff --git a/dom/html/HTMLDataListElement.h b/dom/html/HTMLDataListElement.h
index e0aff818be..ba2a2e0b41 100644
--- a/dom/html/HTMLDataListElement.h
+++ b/dom/html/HTMLDataListElement.h
@@ -37,8 +37,8 @@ public:
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
// This function is used to generate the nsContentList (option elements).
- static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
+ static bool MatchOptions(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
nsGenericHTMLElement)
diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp
index 865d3c9cf4..d72fd1061a 100644
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -120,10 +120,10 @@ HTMLFieldSetElement::GetType(nsAString& aType)
/* static */
bool
-HTMLFieldSetElement::MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
+HTMLFieldSetElement::MatchListedElements(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aContent);
+ nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aElement);
return formControl;
}
diff --git a/dom/html/HTMLFieldSetElement.h b/dom/html/HTMLFieldSetElement.h
index d169434ae8..96fff4582b 100644
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -124,8 +124,8 @@ private:
void NotifyElementsForFirstLegendChange(bool aNotify);
// This function is used to generate the nsContentList (listed form elements).
- static bool MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
+ static bool MatchListedElements(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
// listed form controls elements.
RefPtr<nsContentList> mElements;
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 78f74ae0c2..d46eccdbc0 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -8800,6 +8800,16 @@ HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence)
aSequence.AppendElements(mEntries);
}
+already_AddRefed<nsINodeList>
+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 e5d670e085..9ca876aee8 100644
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -704,6 +704,8 @@ public:
// XPCOM GetCustomVisibility() is OK
+ already_AddRefed<nsINodeList> GetLabels();
+
// XPCOM Select() is OK
Nullable<int32_t> GetSelectionStart(ErrorResult& aRv);
diff --git a/dom/html/HTMLLabelElement.cpp b/dom/html/HTMLLabelElement.cpp
index c1d22b0a60..d1c037336e 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<nsGenericHTMLElement*>(element);
}
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 24ddabb654..53f42317a0 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -735,12 +735,12 @@ HTMLSelectElement::SetLength(uint32_t aLength, ErrorResult& aRv)
/* static */
bool
-HTMLSelectElement::MatchSelectedOptions(nsIContent* aContent,
+HTMLSelectElement::MatchSelectedOptions(Element* aElement,
int32_t /* unused */,
nsIAtom* /* unused */,
void* /* unused*/)
{
- HTMLOptionElement* option = HTMLOptionElement::FromContent(aContent);
+ HTMLOptionElement* option = HTMLOptionElement::FromContent(aElement);
return option && option->Selected();
}
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index d7e4350b44..8a25385de6 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -247,7 +247,7 @@ public:
mOptions->IndexedSetter(aIndex, aOption, aRv);
}
- static bool MatchSelectedOptions(nsIContent* aContent, int32_t, nsIAtom*,
+ static bool MatchSelectedOptions(Element* aElement, int32_t, nsIAtom*,
void*);
nsIHTMLCollection* SelectedOptions();
diff --git a/dom/html/HTMLTableRowElement.cpp b/dom/html/HTMLTableRowElement.cpp
index 2dec9c8838..ac2463400d 100644
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -120,10 +120,10 @@ HTMLTableRowElement::SectionRowIndex() const
}
static bool
-IsCell(nsIContent *aContent, int32_t aNamespaceID,
+IsCell(Element *aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void *aData)
{
- return aContent->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
+ return aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
}
nsIHTMLCollection*
diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp
index d75001a83a..2f890325ad 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<nsINodeList>
+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<nsLabelsNodeList> 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 3cca41c3d7..0635c27e1c 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<nsINodeList> Labels();
+
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
index 7d66aab04f..fea78dc37e 100644
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1100,31 +1100,31 @@ nsHTMLDocument::Applets()
}
bool
-nsHTMLDocument::MatchLinks(nsIContent *aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchLinks(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- nsIDocument* doc = aContent->GetUncomposedDoc();
+ nsIDocument* doc = aElement->GetUncomposedDoc();
if (doc) {
- NS_ASSERTION(aContent->IsInUncomposedDoc(),
+ NS_ASSERTION(aElement->IsInUncomposedDoc(),
"This method should never be called on content nodes that "
"are not in a document!");
#ifdef DEBUG
{
nsCOMPtr<nsIHTMLDocument> htmldoc =
- do_QueryInterface(aContent->GetUncomposedDoc());
+ do_QueryInterface(aElement->GetUncomposedDoc());
NS_ASSERTION(htmldoc,
"Huh, how did this happen? This should only be used with "
"HTML documents!");
}
#endif
- mozilla::dom::NodeInfo *ni = aContent->NodeInfo();
+ mozilla::dom::NodeInfo *ni = aElement->NodeInfo();
nsIAtom *localName = ni->NameAtom();
if (ni->NamespaceID() == kNameSpaceID_XHTML &&
(localName == nsGkAtoms::a || localName == nsGkAtoms::area)) {
- return aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
+ return aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
}
}
@@ -1148,24 +1148,24 @@ nsHTMLDocument::Links()
}
bool
-nsHTMLDocument::MatchAnchors(nsIContent *aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchAnchors(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- NS_ASSERTION(aContent->IsInUncomposedDoc(),
+ NS_ASSERTION(aElement->IsInUncomposedDoc(),
"This method should never be called on content nodes that "
"are not in a document!");
#ifdef DEBUG
{
nsCOMPtr<nsIHTMLDocument> htmldoc =
- do_QueryInterface(aContent->GetUncomposedDoc());
+ do_QueryInterface(aElement->GetUncomposedDoc());
NS_ASSERTION(htmldoc,
"Huh, how did this happen? This should only be used with "
"HTML documents!");
}
#endif
- if (aContent->NodeInfo()->Equals(nsGkAtoms::a, kNameSpaceID_XHTML)) {
- return aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name);
+ if (aElement->IsHTMLElement(nsGkAtoms::a)) {
+ return aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::name);
}
return false;
@@ -1952,14 +1952,14 @@ nsHTMLDocument::Writeln(JSContext* cx, const Sequence<nsString>& aText,
}
bool
-nsHTMLDocument::MatchNameAttribute(nsIContent* aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- NS_PRECONDITION(aContent, "Must have content node to work with!");
+ NS_PRECONDITION(aElement, "Must have element to work with!");
nsString* elementName = static_cast<nsString*>(aData);
return
- aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
- aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+ aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
+ aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
*elementName, eCaseMatters);
}
@@ -2279,10 +2279,10 @@ nsHTMLDocument::GetForms()
return mForms;
}
-static bool MatchFormControls(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData)
+static bool MatchFormControls(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData)
{
- return aContent->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
+ return aElement->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
}
nsContentList*
diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h
index 2dbbf2b57f..426ebddc59 100644
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -261,12 +261,13 @@ protected:
nsIContent *MatchId(nsIContent *aContent, const nsAString& aId);
- static bool MatchLinks(nsIContent *aContent, int32_t aNamespaceID,
+ static bool MatchLinks(mozilla::dom::Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
+ static bool MatchAnchors(mozilla::dom::Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData);
- static bool MatchAnchors(nsIContent *aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
- static bool MatchNameAttribute(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
+ static bool MatchNameAttribute(mozilla::dom::Element* aElement,
+ int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
static void DocumentWriteTerminationFunc(nsISupports *aRef);
diff --git a/dom/html/test/forms/test_button_attributes_reflection.html b/dom/html/test/forms/test_button_attributes_reflection.html
index 26858e939b..4e702b3ac6 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");
</script>
</pre>
</body>
diff --git a/dom/svg/SVGGradientElement.cpp b/dom/svg/SVGGradientElement.cpp
index 1bcac67e6e..93767c9340 100644
--- a/dom/svg/SVGGradientElement.cpp
+++ b/dom/svg/SVGGradientElement.cpp
@@ -198,13 +198,14 @@ SVGRadialGradientElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> 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<SVGAnimatedLength>
+SVGRadialGradientElement::Fr()
+{
+ return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this);
+}
+
//----------------------------------------------------------------------
// nsSVGElement methods
diff --git a/dom/svg/SVGGradientElement.h b/dom/svg/SVGGradientElement.h
index 7b2c6b2200..ce9f3b4b1c 100644
--- a/dom/svg/SVGGradientElement.h
+++ b/dom/svg/SVGGradientElement.h
@@ -139,13 +139,14 @@ public:
already_AddRefed<SVGAnimatedLength> R();
already_AddRefed<SVGAnimatedLength> Fx();
already_AddRefed<SVGAnimatedLength> Fy();
+ already_AddRefed<SVGAnimatedLength> 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/Document.webidl b/dom/webidl/Document.webidl
index c895fad392..f05656e840 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/dom/webidl/HTMLButtonElement.webidl b/dom/webidl/HTMLButtonElement.webidl
index c50e09ae07..579efa39ce 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 d3d537f84c..050d195107 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 1f80764e94..104e003539 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 05dcf1800f..d0e4ecbe62 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 3d1000d22f..028728e22c 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 74fc7b2cfb..b18ca3634d 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 b1005ed422..4df687a0b1 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/dom/webidl/SVGRadialGradientElement.webidl b/dom/webidl/SVGRadialGradientElement.webidl
index d4a3724f6a..8d7ce90168 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/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp
index d9a987b62f..54252e53b8 100644
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -968,11 +968,4 @@ IsDebuggerSandbox(JSObject* object)
SimpleGlobalObject::GlobalType::WorkerDebuggerSandbox;
}
-bool
-GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
-{
- JS_ReportErrorNumberASCII(aCx, js::GetErrorMessage, nullptr, JSMSG_GETTER_ONLY);
- return false;
-}
-
END_WORKERS_NAMESPACE
diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h
index ad083d3b8e..cd15a4d7cb 100644
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -362,14 +362,6 @@ IsDebuggerGlobal(JSObject* global);
bool
IsDebuggerSandbox(JSObject* object);
-// Throws the JSMSG_GETTER_ONLY exception. This shouldn't be used going
-// forward -- getter-only properties should just use JS_PSG for the setter
-// (implying no setter at all), which will not throw when set in non-strict
-// code but will in strict code. Old code should use this only for temporary
-// compatibility reasons.
-extern bool
-GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
-
END_WORKERS_NAMESPACE
#endif // mozilla_dom_workers_workers_h__
diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp
index ae3cdb7eb9..1dcb55aee4 100644
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -1919,26 +1919,26 @@ XULDocument::StartLayout(void)
/* static */
bool
-XULDocument::MatchAttribute(nsIContent* aContent,
+XULDocument::MatchAttribute(Element* aElement,
int32_t aNamespaceID,
nsIAtom* aAttrName,
void* aData)
{
- NS_PRECONDITION(aContent, "Must have content node to work with!");
+ NS_PRECONDITION(aElement, "Must have content node to work with!");
nsString* attrValue = static_cast<nsString*>(aData);
if (aNamespaceID != kNameSpaceID_Unknown &&
aNamespaceID != kNameSpaceID_Wildcard) {
return attrValue->EqualsLiteral("*") ?
- aContent->HasAttr(aNamespaceID, aAttrName) :
- aContent->AttrValueIs(aNamespaceID, aAttrName, *attrValue,
+ aElement->HasAttr(aNamespaceID, aAttrName) :
+ aElement->AttrValueIs(aNamespaceID, aAttrName, *attrValue,
eCaseMatters);
}
// Qualified name match. This takes more work.
- uint32_t count = aContent->GetAttrCount();
+ uint32_t count = aElement->GetAttrCount();
for (uint32_t i = 0; i < count; ++i) {
- const nsAttrName* name = aContent->GetAttrNameAt(i);
+ const nsAttrName* name = aElement->GetAttrNameAt(i);
bool nameMatch;
if (name->IsAtom()) {
nameMatch = name->Atom() == aAttrName;
@@ -1950,7 +1950,7 @@ XULDocument::MatchAttribute(nsIContent* aContent,
if (nameMatch) {
return attrValue->EqualsLiteral("*") ||
- aContent->AttrValueIs(name->NamespaceID(), name->LocalName(),
+ aElement->AttrValueIs(name->NamespaceID(), name->LocalName(),
*attrValue, eCaseMatters);
}
}
diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h
index a2f82bb896..06abb797f0 100644
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -180,7 +180,7 @@ public:
NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) override;
static bool
- MatchAttribute(nsIContent* aContent,
+ MatchAttribute(Element* aContent,
int32_t aNameSpaceID,
nsIAtom* aAttrName,
void* aData);
diff --git a/image/DrawResult.h b/image/DrawResult.h
index 8240ede26b..912f59dc34 100644
--- a/image/DrawResult.h
+++ b/image/DrawResult.h
@@ -6,6 +6,7 @@
#ifndef mozilla_image_DrawResult_h
#define mozilla_image_DrawResult_h
+#include <cstdint> // for uint8_t
#include "mozilla/Attributes.h"
#include "mozilla/Likely.h"
diff --git a/js/src/js.msg b/js/src/js.msg
index 246e363c37..cb5fc383bd 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -65,7 +65,7 @@ MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage")
MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length")
MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}")
MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}")
-MSG_DEF(JSMSG_GETTER_ONLY, 0, JSEXN_TYPEERR, "setting a property that has only a getter")
+MSG_DEF(JSMSG_GETTER_ONLY, 1, JSEXN_TYPEERR, "setting getter-only property {0}")
MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}")
MSG_DEF(JSMSG_UNDEFINED_PROP, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}")
MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects")
diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp
index a39a4b0a04..33feb0a546 100644
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3298,18 +3298,6 @@ GetObjectSlotNameFunctor::operator()(JS::CallbackTracer* trc, char* buf, size_t
}
}
-bool
-js::ReportGetterOnlyAssignment(JSContext* cx, bool strict)
-{
- return JS_ReportErrorFlagsAndNumberASCII(cx,
- strict
- ? JSREPORT_ERROR
- : JSREPORT_WARNING | JSREPORT_STRICT,
- GetErrorMessage, nullptr,
- JSMSG_GETTER_ONLY);
-}
-
-
/*** Debugging routines **************************************************************************/
#ifdef DEBUG
diff --git a/js/src/jsobj.h b/js/src/jsobj.h
index fbf4e47bec..af79131af7 100644
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1320,9 +1320,6 @@ template<XDRMode mode>
bool
XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj);
-extern bool
-ReportGetterOnlyAssignment(JSContext* cx, bool strict);
-
/*
* Report a TypeError: "so-and-so is not an object".
* Using NotNullObject is usually less code.
diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp
index 22c313c72b..6ce629bc90 100644
--- a/layout/base/nsLayoutDebugger.cpp
+++ b/layout/base/nsLayoutDebugger.cpp
@@ -126,8 +126,10 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
contentData.AppendLiteral(" id:");
contentData.Append(tmp);
}
- if (content->GetClasses()) {
- content->GetClasses()->ToString(tmp);
+ const nsAttrValue* classes = content->IsElement() ?
+ content->AsElement()->GetClasses() : nullptr;
+ if (classes) {
+ classes->ToString(tmp);
contentData.AppendLiteral(" class:");
contentData.Append(tmp);
}
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 789c91f505..c8c91b251c 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<LogicalSize>& 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<LogicalSize>& 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<LogicalSize>& 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 d9580a3dfb..97fc410b0a 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<mozilla::LogicalSize>& aPercentageBasis = mozilla::Nothing(),
uint32_t aFlags = 0,
nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE);
/**
diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp
index befd41ee26..fc9f0571b7 100644
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -5,26 +5,22 @@
#include "nsFieldSetFrame.h"
+#include <algorithm>
#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 <algorithm>
-#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<nsFieldSetFrame*>(mFrame)->
+ image::DrawResult result = static_cast<nsFieldSetFrame*>(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 54eaf678f3..5eb67c3209 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
@@ -33,7 +33,6 @@ public:
const mozilla::LogicalSize& aBorder,
const mozilla::LogicalSize& aPadding,
ComputeSizeFlags aFlags) override;
- virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
/**
* The area to paint box-shadows around. It's the border rect except
@@ -46,6 +45,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 ef9459ef23..2e4fa9f67a 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)) {
+ // <input type=color> 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)) {
+ // <input type=color> 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 96ad0f3665..432afa12c0 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 5f5e1e03ee..a9e11cbbeb 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 f85bc2a800..a7f7d40a8f 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<nsFontMetrics> 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 a76cba5145..9d4d0b77c9 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<ContentInfo>& aElements) override;
virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& 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/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index 42f4a24b53..a8756cea2d 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 e425086469..09c980b728 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 69791d5c52..418fa16b7a 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 71d5bba212..8f117b5ab0 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 ?
@@ -2090,6 +2093,18 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput
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.
*/
LogicalRect ContainingBlockFor(const GridArea& aArea) const;
@@ -3731,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<LogicalSize>& 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);
@@ -3812,6 +3829,10 @@ struct CachedIntrinsicSizes
Maybe<nscoord> mMinSize;
Maybe<nscoord> mMinContentContribution;
Maybe<nscoord> mMaxContentContribution;
+
+ // The item's percentage basis for intrinsic sizing purposes.
+ Maybe<LogicalSize> 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
@@ -3832,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);
@@ -3850,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);
@@ -3904,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));
@@ -3977,9 +4010,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 +4415,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 +4448,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 +4486,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.
@@ -4707,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;
@@ -5038,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
{
@@ -5231,6 +5295,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 50eb958e03..2acafa8821 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/bugs/315920-17.html b/layout/reftests/bugs/315920-17.html
index 1681754a52..6d9180144b 100644
--- a/layout/reftests/bugs/315920-17.html
+++ b/layout/reftests/bugs/315920-17.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html class="reftest-wait">
<head>
<style>
input ~ label {color: red}
@@ -8,9 +8,7 @@
input:checked:default + label {color: green}
</style>
</head>
- <body onload='document.getElementById("two").setAttribute("checked", "true");
- document.getElementById("one").setAttribute("checked", "checked");
- document.getElementById("two").removeAttribute("checked");'>
+ <body>
<form>
<input type="checkbox" name="group1" id="one" value="1"/>
<label for="one">Should be no red</label><br>
@@ -19,5 +17,14 @@
<input type="checkbox" name="group1" id="three" value="3"/>
<label for="three">Should be no red</label>
</form>
+<script>
+function doTest() {
+ document.getElementById("two").setAttribute("checked", "true");
+ document.getElementById("one").setAttribute("checked", "checked");
+ document.getElementById("two").removeAttribute("checked");
+ setTimeout(function () { document.documentElement.removeAttribute("class"); }, 0);
+}
+window.addEventListener("MozReftestInvalidate", doTest);
+</script>
</body>
</html>
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 fc74cd2147..caef8b0314 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 c5d8a68ff1..36a2d4920a 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-item-overflow-stretch-001-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html
new file mode 100644
index 0000000000..463bbb4e6e
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Reference: stretching overflow!=visible items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px 30px 3px / 7px 80px 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ min-width:0;
+ min-height:0;
+ box-sizing: border-box;
+}
+
+.oa, .os, .oh { width:80px; height:30px; }
+.m.oa, .m.os, .m.oh { width:70px; height:24px; }
+.oa { overflow: auto; }
+.os { overflow: scroll; }
+.oh { overflow: hidden; }
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" " style="width:112px"><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m " style="width:112px"><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" " style="height:112px"><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m " style="height:112px"><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..4f6259abeb
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-001.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: stretching overflow!=visible items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <link rel="match" href="grid-item-overflow-stretch-001-ref.html">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px auto 3px / 7px auto 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+}
+
+.oa { overflow: auto; }
+.os { overflow: scroll; }
+.oh { overflow: hidden; }
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..a9690a54e5
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Reference: stretching overflow!=visible vertical-rl items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px 30px 3px / 7px 80px 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ writing-mode: vertical-rl;
+ min-width:0;
+ min-height:0;
+ box-sizing: border-box;
+}
+
+.oa, .os, .oh { width:80px; height:30px; }
+.m.oa, .m.os, .m.oh { width:70px; height:24px; }
+.oa { overflow: auto; }
+.os { overflow: scroll; }
+.oh { overflow: hidden; }
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" " style="width:112px"><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m " style="width:112px"><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" " style="height:112px"><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m " style="height:112px"><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..520eed911a
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-002.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: stretching overflow!=visible vertical-rl items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <link rel="match" href="grid-item-overflow-stretch-002-ref.html">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px auto 3px / 7px auto 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ writing-mode: vertical-rl;
+}
+
+.oa { overflow: auto; }
+.os { overflow: scroll; }
+.oh { overflow: hidden; }
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..c082e6be41
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Reference: margin:auto stretch items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px 30px 3px / 7px 112px 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+.c2 { grid-template-columns: 7px 122px 3px; }
+.h > .grid { grid: 7px 112px 3px / 7px 80px 3px; }
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ margin: 0 auto;
+ justify-self:start;
+ align-self:start;
+ height:28px;
+}
+.c2 > * { height:22px; }
+.h .grid > * {
+ margin: 10px 0 0 10px;
+ justify-self:center;
+ align-self:center;
+ width:5px;
+ height:110px;
+}
+
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid c2"><span class="m oa"><x></x></span></div>
+<div class="grid c2"><span class="m os"><x></x></span></div>
+<div class="grid c2"><span class="m oh"><x></x></span></div>
+<div class="grid c2"><span class="m "><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..8bcd79d9be
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-003.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: margin:auto stretch items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <link rel="match" href="grid-item-overflow-stretch-003-ref.html">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px auto 3px / 7px auto 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ margin: 0 auto;
+}
+.h .grid > * {
+ margin: auto;
+}
+
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="oa"><x></x></span></div>
+<div class="grid"><span class="os"><x></x></span></div>
+<div class="grid"><span class="oh"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m oa"><x></x></span></div>
+<div class="grid"><span class="m os"><x></x></span></div>
+<div class="grid"><span class="m oh"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..71ed28d7cc
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Reference: stretching items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 90px;
+ height: 50px;
+ grid: 7px 30px 3px / 7px 102px 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+.c2 { grid: 7px 30x 3px / 7px 112px 3px; grid-gap: 5px;}
+.c3 { grid: 7px 30x 3px / 7px 70px 3px; grid-gap: 5px;}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ min-width: 0;
+ max-width: 100px;
+}
+.h .grid > * {
+ min-height: 0;
+ max-height: 100px;
+ justify-self:center safe;
+ align-self:center safe;
+}
+.h > .grid { grid: 7px 102px 3px / 7px 70px 3px; grid-gap: 5px;}
+.h > .grid.c2 { grid: 7px 30px 3px / 7px 70px 3px; grid-gap: 5px;}
+.h > .grid.c3 { grid: 7px 108px 3px / 7px 70px 3px; grid-gap: 5px;}
+
+.oa { overflow: auto; }
+.p { width: 100%; }
+.h .grid > .p { height: 100%; }
+.x { width:5px; }
+.h .grid > .x { max-height:5px; }
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="p oa"><x></x></span></div>
+<div class="grid"><span class="p "><x></x></span></div>
+<div class="grid c2"><span class="p x" style="height:5px; margin-left:31.5px; margin-top:11.5px"><x></x></span></div>
+<div class="grid c2"><span class=" " style="width:68px"><x></x></span></div>
+
+<br>
+
+<div class="grid c3"><span class="p m oa"><x></x></span></div>
+<div class="grid c3"><span class="p m"><x></x></span></div>
+<div class="grid c2"><span class="m p x"><x></x></span></div>
+<div class="grid c2"><span class="m " style="width:58px"><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="p oa"><x></x></span></div>
+<div class="grid"><span class="p "><x></x></span></div>
+<div class="grid c2"><span class="p x" style=""><x></x></span></div>
+<div class="grid c2"><span class=" " style="height:28px; width:68px;"><x></x></span></div>
+
+<br>
+
+<div class="grid c3"><span class="m p oa"><x></x></span></div>
+<div class="grid c3"><span class="m p"><x></x></span></div>
+<div class="grid c2"><span class="m p x" style="justify-self:start;align-self:start"><x></x></span></div>
+<div class="grid c2"><span class="m " style="height:22px; width:58px"><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..b983b5184b
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-004.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: stretching items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <link rel="match" href="grid-item-overflow-stretch-004-ref.html">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 90px;
+ height: 50px;
+ grid: 7px auto 3px / 7px auto 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ min-width: 0;
+ max-width: 100px;
+}
+.h .grid > * {
+ min-height: 0;
+ max-height: 100px;
+}
+
+.oa { overflow: auto; }
+.p { width: 100%; }
+.h .grid > .p { height: 100%; }
+.x { max-width:5px; margin:auto; }
+.h .grid > .x { max-height:5px; }
+.m { margin: 1px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class="p oa"><x></x></span></div>
+<div class="grid"><span class="p "><x></x></span></div>
+<div class="grid"><span class="p x"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="p m oa"><x></x></span></div>
+<div class="grid"><span class="p m"><x></x></span></div>
+<div class="grid"><span class="m p x"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="p oa"><x></x></span></div>
+<div class="grid"><span class="p "><x></x></span></div>
+<div class="grid"><span class="p x"><x></x></span></div>
+<div class="grid"><span class=" "><x></x></span></div>
+
+<br>
+
+<div class="grid"><span class="m p oa"><x></x></span></div>
+<div class="grid"><span class="m p"><x></x></span></div>
+<div class="grid"><span class="m p x"><x></x></span></div>
+<div class="grid"><span class="m "><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..e7d353c8b8
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Reference: stretching overflow!=visible items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px auto 3px / 7px auto 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ min-width:0;
+ min-height:0;
+ box-sizing: border-box;
+}
+
+.oa, .os, .oh { width:80px; height:30px; }
+.m.oa, .m.os, .m.oh { width:70px; height:8px; }
+.oa { overflow: auto; }
+.os { overflow: scroll; }
+.oh { overflow: hidden; }
+.ov { justify-self: start; }
+.m.ov { align-self: start; }
+.m { margin: 17px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><input class="oa"></div>
+<div class="grid"><input class="os"></div>
+<div class="grid"><input class="oh"></div>
+<div class="grid"><input class="ov"></div>
+
+<br>
+
+<div class="grid"><input class="m oa"></div>
+<div class="grid"><input class="m os"></div>
+<div class="grid"><input class="m oh"></div>
+<div class="grid"><input class="m ov"></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><input class="oa"></div>
+<div class="grid"><input class="os"></div>
+<div class="grid"><input class="oh"></div>
+<div class="grid"><input class="ov"></div>
+
+<br>
+
+<div class="grid"><input class="m oa"></div>
+<div class="grid"><input class="m os"></div>
+<div class="grid"><input class="m oh"></div>
+<div class="grid"><input class="m ov"></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..33fe468d74
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-005.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: stretching overflow!=visible items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <link rel="match" href="grid-item-overflow-stretch-005-ref.html">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px auto 3px / 7px auto 3px;
+ grid-gap: 5px;
+ border:1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border:1px solid;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+.oa { overflow: auto; }
+.os { overflow: scroll; }
+.oh { overflow: hidden; }
+.m { margin: 17px 3px 5px 7px; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><input class="oa"></div>
+<div class="grid"><input class="os"></div>
+<div class="grid"><input class="oh"></div>
+<div class="grid"><input class=" "></div>
+
+<br>
+
+<div class="grid"><input class="m oa"></div>
+<div class="grid"><input class="m os"></div>
+<div class="grid"><input class="m oh"></div>
+<div class="grid"><input class="m "></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><input class="oa"></div>
+<div class="grid"><input class="os"></div>
+<div class="grid"><input class="oh"></div>
+<div class="grid"><input class=" "></div>
+
+<br>
+
+<div class="grid"><input class="m oa"></div>
+<div class="grid"><input class="m os"></div>
+<div class="grid"><input class="m oh"></div>
+<div class="grid"><input class="m "></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..71d4d4f542
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Reference: stretching overflow visible items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-flex;
+ width: 90px;
+ height: 40px;
+ padding: 7px 3px 3px 7px;
+ border: 1px solid;
+}
+
+.grid > * {
+ border: 1px solid;
+ margin: 5px;
+}
+
+.m { margin: 6px 8px 10px 12px; }
+.ma { margin: auto; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class=""><x></x></span></div>
+<div class="grid"><span class="m"><x></x></span></div>
+<div class="grid"><span class="ma" style="margin-left:5px"><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class="" style="flex:1"><x></x></span></div>
+<div class="grid"><span class="m" style="flex:1"><x></x></span></div>
+<div class="grid"><span class="ma" style="margin-top:5px"><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 0000000000..015c50fccd
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-overflow-stretch-006.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>CSS Grid Test: stretching overflow visible items</title>
+ <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857">
+ <link rel="match" href="grid-item-overflow-stretch-006-ref.html">
+ <style type="text/css">
+body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; }
+
+.grid {
+ display: inline-grid;
+ width: 100px;
+ height: 50px;
+ grid: 7px minmax(20px, auto) 3px / 7px minmax(20px, auto) 3px;
+ grid-gap: 5px;
+ border: 1px solid;
+}
+
+.grid > * {
+ grid-area: 2/2;
+ border: 1px solid;
+}
+
+.m { margin: 1px 3px 5px 7px; }
+.ma { margin: auto; }
+
+x { display:block; width:110px; height:5px; background:grey; }
+.h .grid x { width:5px; height:110px; }
+
+br { clear:both; }
+ </style>
+</head>
+<body>
+
+<div class="grid"><span class=""><x></x></span></div>
+<div class="grid"><span class="m"><x></x></span></div>
+<div class="grid"><span class="ma"><x></x></span></div>
+
+<br>
+
+<div class="h">
+
+<div class="grid"><span class=""><x></x></span></div>
+<div class="grid"><span class="m"><x></x></span></div>
+<div class="grid"><span class="ma"><x></x></span></div>
+
+<br>
+
+</div>
+
+</body>
+</html>
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 5fa60b3b56..04d047b836 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"
diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list
index d85eefbd01..093e2faee2 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
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 0000000000..d01c086b5d
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-1-ref.html
@@ -0,0 +1,91 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Testcase #1 for bug 1330962</title>
+ <style type="text/css">
+@font-face {
+ src: url(../fonts/Ahem.ttf);
+ font-family: Ahem;
+}
+html,body {
+ color:black; background-color:white; font:16px/1 Ahem; padding:0; margin:0;
+}
+* { font:16px/1 Ahem; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-grid">
+ A<img class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-grid">
+ A
+ <input type="image" class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><input type="text" value="text"></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><input type="text" value="text"></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><input type="text"></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><input class="no-theme" type="text" value="text"></div>
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..96ebdad713
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-1.html
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Testcase #1 for bug 1330962</title>
+ <style type="text/css">
+@font-face {
+ src: url(../fonts/Ahem.ttf);
+ font-family: Ahem;
+}
+html,body {
+ color:black; background-color:white; font:16px/1 Ahem; padding:0; margin:0;
+}
+* { font:16px/1 Ahem; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <img class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input type="image" class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input class="block" type="text" value="text">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input class="block scroll" type="text" value="text">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input class="block" type="text">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input class="block no-theme" type="text" value="text">
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..441a927b49
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-2-ref.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Testcase #2 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+ color: black;
+ text-align: start;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A<div>
+ <div style="display:inline-block"><input type="button" value="button"></div></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><button>button</button></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><input class="no-theme" type="button" value="button"></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <button class="no-theme">button-first<div style="font-size:10px">button-last</div></button>
+ </div>
+ B
+ <div class="no-theme" style="display:inline-block">button-first<div style="font-size:10px">button-last</div></div>
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <button class="no-theme" style="display:inline-grid">button-first<x style="font-size:10px">button-last</x></button>
+ </div>
+ B
+ <div class="no-theme" style="display:inline-grid">button-first<x style="font-size:10px">button-last</x></div>
+</div>
+
+<div>
+ <div style="display:inline-grid">
+ A
+ <input type="checkbox" class="block" checked>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-grid">
+ A
+ <input type="radio" class="block" checked>
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..78253fe4c2
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-2.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Testcase #2 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+ color: black;
+ text-align: start;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input class="block" type="button" value="button">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <button class="block">button</button>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input class="block no-theme" type="button" value="button">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <button class="block no-theme">button-first<div style="font-size:10px">button-last</div></button>
+ </div>
+ B
+ <button class="no-theme">button-first<div style="font-size:10px">button-last</div></button>
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <button class="grid no-theme">button-first<x style="font-size:10px">button-last</x></button>
+ </div>
+ B
+ <button class="no-theme" style="display:inline-grid">button-first<x style="font-size:10px">button-last</x></button>
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input type="checkbox" class="block" checked>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input type="radio" class="block" checked>
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..ce277b50c9
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-3-ref.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Testcase #3 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-grid">
+ A
+ <textarea class="block">textarea</textarea>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-grid">
+ A
+ <textarea class="block no-theme">textarea</textarea>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-grid">
+ A
+ <textarea class="block no-theme no-scroll">textarea</textarea>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><fieldset style="display:inline">fieldset-first<br>fieldset-last</fieldset></div>
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..9f3c2b1101
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-3.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Testcase #3 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <textarea class="block">textarea</textarea>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <textarea class="block no-theme">textarea</textarea>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <textarea class="block no-theme no-scroll">textarea</textarea>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <fieldset class="block">fieldset-first<br>fieldset-last</fieldset>
+ </div>
+ B
+</div>
+
+
+</body>
+</html>
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 0000000000..5015d50c42
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-4-ref.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Testcase #4 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <div style="display:inline-block"><fieldset style="display:inline"><legend>legend</legend>
+fieldset-first<br>fieldset-last</fieldset></div>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <fieldset style="display:inline-grid">grid-fieldset-first<x>grid-fieldset-last</x></fieldset>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <fieldset style="display:inline" class="no-theme">fieldset-first<br>fieldset-last</fieldset>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <fieldset style="display:inline" class="no-theme scroll">fieldset-first<br>fieldset-last</fieldset>
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..1bfd344b0e
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-4.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Testcase #4 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <fieldset class="block"><legend>legend</legend>
+fieldset-first<br>fieldset-last</fieldset>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <fieldset class="grid"><x style="order:2">grid-fieldset-last</x>grid-fieldset-first</fieldset>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <fieldset class="block no-theme">fieldset-first<br>fieldset-last</fieldset>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <fieldset class="block no-theme scroll">fieldset-first<br>fieldset-last</fieldset>
+ </div>
+ B
+</div>
+
+
+</body>
+</html>
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 0000000000..0dce47f593
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-5-ref.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Testcase #5 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <input type="color">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <input type="color" class="no-theme">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <select><option>select</select>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A<br>
+ <select class="no-theme"><option>select</select>
+ </div>
+ B
+</div>
+
+</body>
+</html>
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 0000000000..0359c8a6fb
--- /dev/null
+++ b/layout/reftests/forms/display-block-baselines-5.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Testcase #5 for bug 1330962</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+* { font:16px/1 monospace; }
+
+.block { display: block; }
+.grid { display: grid; }
+
+.no-theme {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ padding: 20px 0;
+ border: none;
+ background: white;
+}
+
+.scroll {
+ overflow-y: scroll;
+}
+
+.no-scroll {
+ overflow: visible;
+}
+
+ </style>
+</head>
+<body>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input type="color" class="block">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <input type="color" class="block no-theme">
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <select class="block"><option>select</select>
+ </div>
+ B
+</div>
+
+<div>
+ <div style="display:inline-block">
+ A
+ <select class="block no-theme"><option>select</select>
+ </div>
+ B
+</div>
+
+</body>
+</html>
diff --git a/layout/reftests/forms/reftest.list b/layout/reftests/forms/reftest.list
index d45db276f5..c7532077b8 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
diff --git a/layout/reftests/svg/radialGradient-fr-01.svg b/layout/reftests/svg/radialGradient-fr-01.svg
new file mode 100644
index 0000000000..2f28d3aba2
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-fr-01.svg
@@ -0,0 +1,27 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <title>Test gradient fr attribute</title>
+ <defs>
+ <radialGradient id="grad1" fr="100%">
+ <stop offset="0%" stop-color="red" />
+ <stop offset="100%" stop-color="lime" />
+ </radialGradient>
+ <radialGradient id="grad2" xlink:href="#grad1"/>
+ <style>
+ circle {
+ stroke-width: 3px;
+ stroke: lime;
+ }
+ </style>
+ </defs>
+ <rect width="100%" height="100%" fill="lime"/>
+
+ <circle cx="100" cy="100" r="50" fill="url(#grad1)" />
+
+ <circle cx="300" cy="100" r="50" fill="url(#grad2)" />
+</svg>
+
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 0000000000..c256f72a24
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-fr-02-ref.svg
@@ -0,0 +1,28 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <title>Test gradient fr attribute</title>
+ <defs>
+ <radialGradient id="grad1">
+ <stop offset="0%" stop-color="red" />
+ <stop offset="20%" stop-color="red" />
+ <stop offset="100%" stop-color="lime" />
+ </radialGradient>
+ <style>
+ .cover {
+ stroke-width: 3px;
+ stroke: lime;
+ fill: none;
+ image-rendering: optimizeSpeed;
+ }
+ </style>
+ </defs>
+ <rect width="100%" height="100%" fill="lime"/>
+
+ <circle cx="100" cy="100" r="50" fill="url(#grad1)" />
+ <circle class="cover" cx="100" cy="100" r="50" fill="none"/>
+</svg>
+
diff --git a/layout/reftests/svg/radialGradient-fr-02.svg b/layout/reftests/svg/radialGradient-fr-02.svg
new file mode 100644
index 0000000000..1933203be0
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-fr-02.svg
@@ -0,0 +1,27 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <title>Test gradient fr attribute</title>
+ <defs>
+ <radialGradient id="grad1" fr="10%">
+ <stop offset="0%" stop-color="red" />
+ <stop offset="100%" stop-color="lime" />
+ </radialGradient>
+ <style>
+ .cover {
+ stroke-width: 3px;
+ stroke: lime;
+ fill: none;
+ image-rendering: optimizeSpeed;
+ }
+ </style>
+ </defs>
+ <rect width="100%" height="100%" fill="lime"/>
+
+ <circle cx="100" cy="100" r="50" fill="url(#grad1)" />
+ <circle class="cover" cx="100" cy="100" r="50" />
+</svg>
+
diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list
index e596feae8f..520adc9e65 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/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index 1108ce5b58..b361cf0c25 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() &&
@@ -10400,7 +10404,8 @@ CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue,
UngetToken();
// <angle> ,
- 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 9c69e7d101..62d413d983 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 <angle> */
+ "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 <angle> */
- "-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 <angle> */
+ "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)",
@@ -6270,6 +6271,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 +6316,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 +6339,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",
diff --git a/layout/svg/nsSVGGradientFrame.cpp b/layout/svg/nsSVGGradientFrame.cpp
index 217ab8c4a4..2d7684f5a0 100644
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -623,7 +623,7 @@ nsSVGRadialGradientFrame::GradientVectorLengthIsZero()
already_AddRefed<gfxPattern>
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<gfxPattern> pattern = new gfxPattern(fx, fy, 0, cx, cy, r);
+ RefPtr<gfxPattern> pattern = new gfxPattern(fx, fy, fr, cx, cy, r);
return pattern.forget();
}
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 e1a2e38b5d..0000000000
--- 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 bfa61edb7a..363324f2e7 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 e4a30320e7..0000000000
--- 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 da0fb96d7b..0000000000
--- 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/meta/svg/interfaces.html.ini b/testing/web-platform/meta/svg/interfaces.html.ini
index f3f7f6b5c5..1162695c8c 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
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 0000000000..56b52c9515
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-label-element/iframe-label-attributes.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <label>
+ <div id="div1"></div>
+ </label>
+ <label for="test13"></label>
+ </body>
+</html> \ 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 826533e0c1..2910f2c01f 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 @@
<label id="lbl5" for="test7"></label>
<input id="test7">
+
+ <label id="lbl7">
+ <label id="lbl8">
+ <div id="div1">
+ <input id="test8">
+ </div>
+ </label>
+ </label>
+ <div id="div2"></div>
+
+ <label id="lbl9">
+ <label id="lbl10" for="test10">
+ <div id="div3">
+ <input id="test9">
+ </div>
+ </label>
+ </label>
+ <div id="div4"><input id="test10"></div>
+
+ <label id="lbl11">
+ <object id="obj">
+ <input id="test11">
+ <input id="test12">
+ </object>
+ </label>
+ <label id="lbl12" for="test12"><div id="div5"></div></label>
+
+ <label id="lbl13">
+ <p id="p1">
+ <input id="test13">
+ </p>
+ </label>
+
+ <div id="div6">
+ <div id="div7">
+ <label id="lbl14">
+ <label id="lbl15" for="test15">
+ <input id="test14">
+ </label>
+ </label>
+ </div>
+ </div>
+ <input id="test15">
</form>
<label id="lbl6" for="test7"></label>
-
+<div id="content" style="display: none">
<script>
//control attribute
@@ -57,6 +100,7 @@
}, "A label element not in a document can not label any element in the document.");
test(function () {
+ var labels = document.getElementById("test3").labels;
assert_equals(document.getElementById("lbl1").control, document.getElementById("test3"),
"The first labelable descendant of a label element should be its labeled control.");
@@ -64,6 +108,10 @@
document.getElementById("lbl1").insertBefore(input, document.getElementById("test2"));
assert_equals(document.getElementById("lbl1").control, input,
"The first labelable descendant of a label element in tree order should be its labeled control.");
+ assert_equals(input.labels.length, 1,
+ "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
+ assert_equals(labels.length, 0,
+ "The number of labels should be 0 if it's not the first labelable descendant of a label element.");
input.remove();
}, "The labeled control for a label element that has no 'for' attribute is the first labelable element which is a descendant of that label element.");
@@ -101,6 +149,168 @@
}, "A form control has multiple labels.");
test(function () {
+ var labels = document.getElementById("test8").labels;
+ assert_true(labels instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels.length, 2,
+ "The form control has two ancestors with no explicit associated label, and is the first labelable descendant.");
+ assert_array_equals(labels, [document.getElementById("lbl7"), document.getElementById("lbl8")],
+ "The labels for a form control should be returned in tree order.");
+
+ document.getElementById('div2').insertBefore(document.getElementById('div1'), document.getElementById('div2').firstChild);
+ assert_equals(labels.length, 0,
+ "The number of labels should be 0 after the labelable element is moved to outside of nested associated labels.");
+ }, "A labelable element is moved to outside of nested associated labels.");
+
+ test(function () {
+ var labels1 = document.getElementById("test9").labels;
+ var labels2 = document.getElementById("test10").labels;
+ assert_true(labels1 instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_true(labels2 instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels1.length, 1,
+ "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
+ assert_equals(labels2.length, 1,
+ "The number of labels associated with a form control should be the number of label elements for which it is a labeled control.");
+ assert_array_equals(labels1, [document.getElementById("lbl9")],
+ "The labels for a form control should be returned in tree order.");
+ assert_array_equals(labels2, [document.getElementById("lbl10")],
+ "The labels for a form control should be returned in tree order.");
+ document.getElementById('div3').insertBefore(document.getElementById('div4'), document.getElementById('div3').firstChild);
+ assert_equals(labels1.length, 0,
+ "The number of labels should be 0 if it's not the first labelable descendant of a label element.");
+ assert_equals(labels2.length, 2,
+ "The form control has an ancestor with an explicit associated label, and is the first labelable descendant.");
+ }, "A labelable element is moved to inside of nested associated labels.");
+
+ test(function () {
+ var labels1 = document.getElementById("test11").labels;
+ var labels2 = document.getElementById("test12").labels;
+ assert_true(labels1 instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_true(labels2 instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels1.length, 1,
+ "The form control has an ancestor with no explicit associated label, and it is the first labelable descendant.");
+ assert_equals(labels2.length, 1,
+ "The number of labels should be 1 since there is a label with a 'for' attribute associated with this labelable element.");
+ assert_array_equals(labels1, [document.getElementById("lbl11")],
+ "The labels for a form control should be returned in tree order.");
+ assert_array_equals(labels2, [document.getElementById("lbl12")],
+ "The labels for a form control should be returned in tree order.");
+ document.getElementById('div5').appendChild(document.getElementById('obj'));
+ assert_equals(labels1.length, 0,
+ "The number of labels should be 0 after the labelable element is moved to outside of associated label.");
+ assert_equals(labels2.length, 1,
+ "The number of labels should be 1 after the labelable element is moved to outside of associated label.");
+ }, "A labelable element which is a descendant of non-labelable element is moved to outside of associated label.");
+
+ async_test(function () {
+ var labels = document.getElementById("test13").labels;
+ assert_true(labels instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels.length, 1,
+ "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
+ assert_array_equals(labels, [document.getElementById("lbl13")],
+ "The labels for a form control should be returned in tree order.");
+ let iframe = document.createElement('iframe');
+
+ iframe.onload = this.step_func_done(() => {
+ iframe.contentWindow.document.getElementById("div1").appendChild(document.getElementById("p1"));
+ assert_equals(labels.length, 2,
+ "The number of labels should be 2 after the labelable element is moved to iframe.");
+ });
+
+ iframe.setAttribute('src', 'http://web-platform.test:8000/html/semantics/forms/the-label-element/iframe-label-attributes.html');
+ document.body.appendChild(iframe);
+ }, "A labelable element is moved to iframe.");
+
+ test(function () {
+ var labels1 = document.getElementById("test14").labels;
+ var labels2 = document.getElementById("test15").labels;
+ assert_true(labels1 instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels1.length, 1,
+ "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
+ assert_equals(labels2.length, 1,
+ "The number of labels associated with a form control should be the number of label elements for which it is a labeled control.");
+ assert_array_equals(labels1, [document.getElementById("lbl14")],
+ "The labels for a form control should be returned in tree order.");
+
+ document.getElementById('div6').removeChild(document.getElementById('div7'));
+ assert_equals(labels1.length, 0,
+ "The number of labels should be 0 after the labelable element is removed.");
+ assert_equals(labels2.length, 0,
+ "The number of labels should be 0 since there is no label with a 'for' attribute associated with this labelable element.");
+ }, "A div element which contains labelable element is removed.");
+
+ test(function () {
+ // <label><input id="test16"><label for="test16"></label></label>
+ var label1 = document.createElement('label');
+ label1.innerHTML = "<input id='test16'>";
+ var label2 = document.createElement('label');
+ label2.htmlFor = "test16";
+ label1.appendChild(label2);
+
+ var input = label1.firstChild;
+ var labels = input.labels;
+
+ assert_equals(labels.length, 2,
+ "The number of labels associated with a form control should be the number of label elements for which it is a labeled control.");
+ assert_true(labels instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(label1.control, input, "The first labelable descendant of a label element should be its labeled control.");
+ assert_equals(label2.control, input, "The labeled cotrol should be associated with the control whose ID is equal to the value of the 'for' attribute.");
+ }, "A labelable element not in a document can label element in the same tree.");
+
+ test(function () {
+ var isShadowDOMV0;
+ if ("createShadowRoot" in document.getElementById('content')) {
+ isShadowDOMV0 = true;
+ }
+ var root1;
+ if (isShadowDOMV0) {
+ root1 = document.getElementById('content').createShadowRoot();
+ } else {
+ root1 = document.getElementById('content').attachShadow({mode: 'open'});
+ }
+ assert_true(root1 instanceof DocumentFragment,
+ "ShadowRoot should be an instance of DocumentFragment.");
+ // <label><input id="shadow1"/></label><div id="div1"></div>
+ var label1 = document.createElement('label');
+ var input1 = document.createElement('input');
+ input1.setAttribute("id", "shadow1");
+ label1.appendChild(input1);
+ root1.appendChild(label1);
+
+ var div1 = document.createElement('div');
+ label1.appendChild(div1);
+ // <label for="shadow2"></label><input id="shadow2"/>
+ var root2;
+ if (isShadowDOMV0) {
+ root2 = div1.createShadowRoot();
+ } else {
+ root2 = div1.attachShadow({mode: 'open'});
+ }
+
+ assert_true(root2 instanceof DocumentFragment,
+ "ShadowRoot should be an instance of DocumentFragment.");
+ var label2 = document.createElement('label');
+ label2.setAttribute("for", "shadow2");
+
+ var input2 = document.createElement('input');
+ input2.setAttribute("id", "shadow2");
+ root2.appendChild(label2);
+ root2.appendChild(input2);
+
+ assert_equals(root1.getElementById("shadow1").labels.length, 1,
+ "The form control has an ancestor with no explicit associated label, and it is the first labelable descendant.");
+ assert_equals(root2.getElementById("shadow2").labels.length, 1,
+ "The number of labels should be 1 since there is a label with a 'for' attribute associated with this labelable element.");
+ }, "A labelable element inside the shadow DOM.");
+
+ test(function () {
var labels = document.getElementById("test3").labels;
assert_true(labels instanceof NodeList, "A form control's 'labels' property should be an instance of a NodeList.");
assert_equals(labels.length, 1, "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
diff --git a/testing/web-platform/tests/page-visibility/idlharness.html b/testing/web-platform/tests/page-visibility/idlharness.html
index c8086a1bc6..2575460801 100644
--- a/testing/web-platform/tests/page-visibility/idlharness.html
+++ b/testing/web-platform/tests/page-visibility/idlharness.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<title>Page Visibility IDL tests</title>
<link rel="author" title="W3C" href="http://www.w3.org/" />
-<link rel="help" href="http://www.w3.org/TR/page-visibility/#sec-document-interface"/>
+<link rel="help" href="https://w3c.github.io/page-visibility/"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
@@ -16,6 +16,10 @@
<pre id='untested_idl' style='display:none'>
interface Document {
};
+
+[TreatNonObjectAsNull]
+callback EventHandlerNonNull = any (Event event);
+typedef EventHandlerNonNull? EventHandler;
</pre>
<pre id='idl'>
diff --git a/widget/EventMessageList.h b/widget/EventMessageList.h
index 55fc7375ec..7fe642637e 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)