WebKit Bugzilla
Attachment 369762 Details for
Bug 197840
: [css-grid] specified value for (eg.) grid-template-columns expands repeat()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197840-20190513213649.patch (text/plain), 38.39 KB, created by
Oriol Brufau
on 2019-05-13 12:36:51 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Oriol Brufau
Created:
2019-05-13 12:36:51 PDT
Size:
38.39 KB
patch
obsolete
>Subversion Revision: 245045 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 2493abb804653eb7200d84450c849b4f3f415182..eca93540b37060fbdc894b44d22797c787c05db0 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,42 @@ >+2019-05-10 Oriol Brufau <obrufau@igalia.com> >+ >+ [css-grid] Preserve repeat() notation when serializing declared values >+ https://bugs.webkit.org/show_bug.cgi?id=197840 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Tests: fast/css-grid-layout/grid-element-auto-repeat-get-set.html >+ fast/css-grid-layout/grid-repeat-calc.html >+ fast/css-grid-layout/named-grid-line-get-set.html >+ imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002.html >+ >+ Before this change, a repeat() notation with an integral number of >+ repetitions was expanded at parse time. This was observable when reading >+ declared values using JS APIs. >+ >+ This patch makes the parser preserve that notation, like it was already >+ happening when the number of repetitions was automatic and not integral. >+ >+ The resolved value in getComputedStyle() will still be expanded, though, >+ as required by the spec. >+ >+ * Sources.txt: >+ * css/CSSGridIntegerRepeatValue.cpp: Added. >+ (WebCore::CSSGridIntegerRepeatValue::customCSSText const): >+ (WebCore::CSSGridIntegerRepeatValue::equals const): >+ * css/CSSGridIntegerRepeatValue.h: Added. >+ * css/CSSValue.cpp: >+ (WebCore::CSSValue::equals const): >+ (WebCore::CSSValue::cssText const): >+ (WebCore::CSSValue::destroy): >+ * css/CSSValue.h: >+ (WebCore::CSSValue::isGridIntegerRepeatValue const): >+ * css/StyleBuilderConverter.h: >+ (WebCore::StyleBuilderConverter::createGridTrackList): >+ (WebCore::StyleBuilderConverter::convertGridTrackSizeList): >+ * css/parser/CSSPropertyParser.cpp: >+ (WebCore::consumeGridTrackRepeatFunction): >+ > 2019-05-07 Ryan Haddad <ryanhaddad@apple.com> > > Unreviewed, rolling out r245038. >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index bcecba9089766f90f950c21783af62e118ffb6cc..94e8ad6621fe35d74cebbb41c1bd641e2a9cb04a 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -670,6 +670,7 @@ css/CSSFontVariationValue.cpp > css/CSSFunctionValue.cpp > css/CSSGradientValue.cpp > css/CSSGridAutoRepeatValue.cpp >+css/CSSGridIntegerRepeatValue.cpp > css/CSSGridLineNamesValue.cpp > css/CSSGridTemplateAreasValue.cpp > css/CSSGroupingRule.cpp >diff --git a/Source/WebCore/css/CSSGridIntegerRepeatValue.cpp b/Source/WebCore/css/CSSGridIntegerRepeatValue.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..fe583ca171906bdf688f19420cf61b93c2fe7cc7 >--- /dev/null >+++ b/Source/WebCore/css/CSSGridIntegerRepeatValue.cpp >@@ -0,0 +1,54 @@ >+/* >+ * Copyright (C) 2019 Igalia S.L. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions are >+ * met: >+ * >+ * * Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * * Redistributions in binary form must reproduce the above >+ * copyright notice, this list of conditions and the following disclaimer >+ * in the documentation and/or other materials provided with the >+ * distribution. >+ * * Neither the name of Google Inc. nor the names of its >+ * contributors may be used to endorse or promote products derived from >+ * this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT >+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, >+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT >+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "CSSGridIntegerRepeatValue.h" >+ >+#include <wtf/text/StringBuilder.h> >+ >+namespace WebCore { >+ >+String CSSGridIntegerRepeatValue::customCSSText() const >+{ >+ StringBuilder result; >+ result.append("repeat("); >+ result.append(String::number(repetitions())); >+ result.append(", "); >+ result.append(CSSValueList::customCSSText()); >+ result.append(')'); >+ return result.toString(); >+} >+ >+bool CSSGridIntegerRepeatValue::equals(const CSSGridIntegerRepeatValue& other) const >+{ >+ return m_repetitions == other.m_repetitions && CSSValueList::equals(other); >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/css/CSSGridIntegerRepeatValue.h b/Source/WebCore/css/CSSGridIntegerRepeatValue.h >new file mode 100644 >index 0000000000000000000000000000000000000000..4111138bee10fb4b031d5d06a985d951be4b643a >--- /dev/null >+++ b/Source/WebCore/css/CSSGridIntegerRepeatValue.h >@@ -0,0 +1,71 @@ >+/* >+ * Copyright (C) 2019 Igalia S.L. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions are >+ * met: >+ * >+ * * Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * * Redistributions in binary form must reproduce the above >+ * copyright notice, this list of conditions and the following disclaimer >+ * in the documentation and/or other materials provided with the >+ * distribution. >+ * * Neither the name of Google Inc. nor the names of its >+ * contributors may be used to endorse or promote products derived from >+ * this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT >+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, >+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT >+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CSSValueKeywords.h" >+#include "CSSValueList.h" >+ >+namespace WebCore { >+ >+// CSSGridIntegerRepeatValue stores the track sizes and line numbers when the >+// integer-repeat syntax is used. >+// >+// Right now the integer-repeat syntax is as follows: >+// <track-repeat> = repeat( [ <positive-integer> ], >+// [ <line-names>? <track-size> ]+ <line-names>? ) >+// <fixed-repeat> = repeat( [ <positive-integer> ], >+// [ <line-names>? <fixed-size> ]+ <line-names>? ) >+class CSSGridIntegerRepeatValue final : public CSSValueList { >+public: >+ static Ref<CSSGridIntegerRepeatValue> create(size_t repetitions) >+ { >+ return adoptRef(*new CSSGridIntegerRepeatValue(repetitions)); >+ } >+ >+ String customCSSText() const; >+ bool equals(const CSSGridIntegerRepeatValue&) const; >+ >+ size_t repetitions() const { return m_repetitions; } >+ >+private: >+ CSSGridIntegerRepeatValue(size_t repetitions) >+ : CSSValueList(GridIntegerRepeatClass, SpaceSeparator) >+ , m_repetitions(repetitions) >+ { >+ ASSERT(repetitions > 0); >+ } >+ >+ const size_t m_repetitions; >+}; >+ >+} // namespace WebCore >+ >+SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSGridIntegerRepeatValue, isGridIntegerRepeatValue()); >diff --git a/Source/WebCore/css/CSSValue.cpp b/Source/WebCore/css/CSSValue.cpp >index cc3f59f30faeb55f7496ba8d98049d37b09c0470..50d2a97b71519f6bb0fd1c2194cc51f4f60db136 100644 >--- a/Source/WebCore/css/CSSValue.cpp >+++ b/Source/WebCore/css/CSSValue.cpp >@@ -65,6 +65,7 @@ > #include "CSSVariableReferenceValue.h" > > #include "CSSGridAutoRepeatValue.h" >+#include "CSSGridIntegerRepeatValue.h" > #include "CSSGridLineNamesValue.h" > #include "CSSGridTemplateAreasValue.h" > >@@ -188,6 +189,8 @@ bool CSSValue::equals(const CSSValue& other) const > return compareCSSValues<CSSRevertValue>(*this, other); > case GridAutoRepeatClass: > return compareCSSValues<CSSGridAutoRepeatValue>(*this, other); >+ case GridIntegerRepeatClass: >+ return compareCSSValues<CSSGridIntegerRepeatValue>(*this, other); > case GridLineNamesClass: > return compareCSSValues<CSSGridLineNamesValue>(*this, other); > case GridTemplateAreasClass: >@@ -288,6 +291,8 @@ String CSSValue::cssText() const > return downcast<CSSRevertValue>(*this).customCSSText(); > case GridAutoRepeatClass: > return downcast<CSSGridAutoRepeatValue>(*this).customCSSText(); >+ case GridIntegerRepeatClass: >+ return downcast<CSSGridIntegerRepeatValue>(*this).customCSSText(); > case GridLineNamesClass: > return downcast<CSSGridLineNamesValue>(*this).customCSSText(); > case GridTemplateAreasClass: >@@ -399,6 +404,9 @@ void CSSValue::destroy() > case GridAutoRepeatClass: > delete downcast<CSSGridAutoRepeatValue>(this); > return; >+ case GridIntegerRepeatClass: >+ delete downcast<CSSGridIntegerRepeatValue>(this); >+ return; > case GridLineNamesClass: > delete downcast<CSSGridLineNamesValue>(this); > return; >diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h >index 7edd3e231a7c1b20a0b01a468f51d594afb98536..7d4b118fb7be1b20f34c50ddeab84ff6d210efbe 100644 >--- a/Source/WebCore/css/CSSValue.h >+++ b/Source/WebCore/css/CSSValue.h >@@ -111,6 +111,7 @@ public: > #endif > bool isContentDistributionValue() const { return m_classType == CSSContentDistributionClass; } > bool isGridAutoRepeatValue() const { return m_classType == GridAutoRepeatClass; } >+ bool isGridIntegerRepeatValue() const { return m_classType == GridIntegerRepeatClass; } > bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; } > bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; } > bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } >@@ -200,6 +201,7 @@ protected: > ImageSetClass, > GridLineNamesClass, > GridAutoRepeatClass, >+ GridIntegerRepeatClass, > // Do not append non-list class types here. > }; > >diff --git a/Source/WebCore/css/StyleBuilderConverter.h b/Source/WebCore/css/StyleBuilderConverter.h >index abf5caa3a8ab0215be860c52789da39302458023..8d8b6f1676a10701f4a5f1ea9cbea48e3fb144f2 100644 >--- a/Source/WebCore/css/StyleBuilderConverter.h >+++ b/Source/WebCore/css/StyleBuilderConverter.h >@@ -34,6 +34,7 @@ > #include "CSSFontVariationValue.h" > #include "CSSFunctionValue.h" > #include "CSSGridAutoRepeatValue.h" >+#include "CSSGridIntegerRepeatValue.h" > #include "CSSGridLineNamesValue.h" > #include "CSSImageGeneratorValue.h" > #include "CSSImageSetValue.h" >@@ -989,12 +990,16 @@ inline bool StyleBuilderConverter::createGridTrackList(const CSSValue& value, Tr > return false; > > unsigned currentNamedGridLine = 0; >- for (auto& currentValue : downcast<CSSValueList>(value)) { >- if (is<CSSGridLineNamesValue>(currentValue)) { >- createGridLineNamesList(currentValue.get(), currentNamedGridLine, tracksData.m_namedGridLines, tracksData.m_orderedNamedGridLines); >- continue; >+ auto handleLineNameOrTrackSize = [&](const CSSValue& currentValue) { >+ if (is<CSSGridLineNamesValue>(currentValue)) >+ createGridLineNamesList(currentValue, currentNamedGridLine, tracksData.m_namedGridLines, tracksData.m_orderedNamedGridLines); >+ else { >+ ++currentNamedGridLine; >+ tracksData.m_trackSizes.append(createGridTrackSize(currentValue, styleResolver)); > } >+ }; > >+ for (auto& currentValue : downcast<CSSValueList>(value)) { > if (is<CSSGridAutoRepeatValue>(currentValue)) { > ASSERT(tracksData.m_autoRepeatTrackSizes.isEmpty()); > unsigned autoRepeatIndex = 0; >@@ -1013,8 +1018,16 @@ inline bool StyleBuilderConverter::createGridTrackList(const CSSValue& value, Tr > continue; > } > >- ++currentNamedGridLine; >- tracksData.m_trackSizes.append(createGridTrackSize(currentValue, styleResolver)); >+ if (is<CSSGridIntegerRepeatValue>(currentValue)) { >+ size_t repetitions = downcast<CSSGridIntegerRepeatValue>(currentValue.get()).repetitions(); >+ for (size_t i = 0; i < repetitions; ++i) { >+ for (auto& integerRepeatValue : downcast<CSSValueList>(currentValue.get())) >+ handleLineNameOrTrackSize(integerRepeatValue); >+ } >+ continue; >+ } >+ >+ handleLineNameOrTrackSize(currentValue); > } > > // The parser should have rejected any <track-list> without any <track-size> as >@@ -1099,6 +1112,7 @@ inline Vector<GridTrackSize> StyleBuilderConverter::convertGridTrackSizeList(Sty > for (auto& currValue : valueList) { > ASSERT(!currValue->isGridLineNamesValue()); > ASSERT(!currValue->isGridAutoRepeatValue()); >+ ASSERT(!currValue->isGridIntegerRepeatValue()); > trackSizes.uncheckedAppend(convertGridTrackSize(styleResolver, currValue)); > } > return trackSizes; >diff --git a/Source/WebCore/css/parser/CSSPropertyParser.cpp b/Source/WebCore/css/parser/CSSPropertyParser.cpp >index 3eeaa080fae12947965a7ea3d3b01597486bdcf2..befef3404ad35ef3445658c37ff12b51b6ab1604 100644 >--- a/Source/WebCore/css/parser/CSSPropertyParser.cpp >+++ b/Source/WebCore/css/parser/CSSPropertyParser.cpp >@@ -47,6 +47,7 @@ > #include "CSSFontStyleValue.h" > #include "CSSFunctionValue.h" > #include "CSSGridAutoRepeatValue.h" >+#include "CSSGridIntegerRepeatValue.h" > #include "CSSGridLineNamesValue.h" > #include "CSSGridTemplateAreasValue.h" > #include "CSSLineBoxContainValue.h" >@@ -3425,10 +3426,10 @@ static bool consumeGridTrackRepeatFunction(CSSParserTokenRange& range, CSSParser > else { > // We clamp the repetitions to a multiple of the repeat() track list's size, while staying below the max grid size. > repetitions = std::min(repetitions, GridPosition::max() / numberOfTracks); >- for (size_t i = 0; i < repetitions; ++i) { >- for (size_t j = 0; j < repeatedValues->length(); ++j) >- list.append(*repeatedValues->itemWithoutBoundsCheck(j)); >- } >+ RefPtr<CSSValueList> integerRepeatedValues = CSSGridIntegerRepeatValue::create(repetitions); >+ for (size_t i = 0; i < repeatedValues->length(); ++i) >+ integerRepeatedValues->append(*repeatedValues->itemWithoutBoundsCheck(i)); >+ list.append(*integerRepeatedValues); > } > return true; > } >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index f5b8c15dff1a8e8230841a94fc795be193424f82..a461287d8c0973d07a12354908540018ae1e5a98 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2019-05-13 Oriol Brufau <obrufau@igalia.com> >+ >+ [css-grid] Preserve repeat() notation when serializing declared values >+ https://bugs.webkit.org/show_bug.cgi?id=197840 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update test expectations. >+ >+ * fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt: >+ * fast/css-grid-layout/grid-element-auto-repeat-get-set.html: >+ * fast/css-grid-layout/grid-repeat-calc-expected.txt: >+ * fast/css-grid-layout/grid-repeat-calc.html: >+ * fast/css-grid-layout/named-grid-line-get-set-expected.txt: >+ * fast/css-grid-layout/named-grid-line-get-set.html: >+ > 2019-05-07 Jiewen Tan <jiewen_tan@apple.com> > > [WebAuthN] A new request should always suppress the pending request if any >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 0a05cee769733eda7e6c1e7b1324c0e23d54988d..2de21a810e23ae08b551d67d292dc43931c66262 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,16 @@ >+2019-05-10 Oriol Brufau <obrufau@igalia.com> >+ >+ [css-grid] Preserve repeat() notation when serializing declared values >+ https://bugs.webkit.org/show_bug.cgi?id=197840 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Import WPT test. >+ >+ * web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002-expected.txt: Added. >+ * web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002.html: Added. >+ * web-platform-tests/css/css-grid/grid-definition/w3c-import.log: >+ > 2019-05-07 Antoine Quint <graouts@apple.com> > > [Pointer Events] isPrimary property of pointercancel events should match previous events for that pointer >diff --git a/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt b/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt >index e2608b636dcfc27477a6eeb92e4cebbdab0e84fb..64da1e1a81a9453c11539d6474e28c57cfe8cb3e 100644 >--- a/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt >+++ b/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt >@@ -13,9 +13,9 @@ PASS element.style.gridTemplateColumns is "repeat(auto-fill, [foo bar] minmax(30 > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[foo] 175px [bar foo] 175px [bar foo] 175px [bar]" > PASS element.style.gridTemplateRows is "repeat(auto-fill, [foo] minmax(175px, max-content) [bar])" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "100px 100px 100px 250px 250px" >-PASS element.style.gridTemplateColumns is "repeat(auto-fill, minmax(50px, 100px)) 250px 250px" >+PASS element.style.gridTemplateColumns is "repeat(auto-fill, minmax(50px, 100px)) repeat(2, 250px)" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "450px 50px [bar] 50px [bar foo] 10px [foo] 10px" >-PASS element.style.gridTemplateRows is "450px repeat(auto-fill, minmax(max-content, 5em) [bar]) [foo] 1em [foo] 1em" >+PASS element.style.gridTemplateRows is "repeat(1, 450px) repeat(auto-fill, minmax(max-content, 5em) [bar]) repeat(2, [foo] 1em)" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[start] 80px [foo bar] 200px [foo bar] 200px [foo bar] 200px [end]" > PASS element.style.gridTemplateColumns is "[start] 10% repeat(auto-fill, [foo bar] 200px) [end]" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "75px [prev] 200px [foo bar next] 150px [last end]" >@@ -33,15 +33,15 @@ PASS element.style.gridTemplateColumns is "repeat(auto-fit, [foo bar] minmax(270 > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[foo] 0px [bar foo] 0px [bar foo] 0px [bar]" > PASS element.style.gridTemplateRows is "repeat(auto-fit, [foo] minmax(20em, max-content) [bar])" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "0px 0px 20px 20px" >-PASS element.style.gridTemplateColumns is "repeat(auto-fit, minmax(300px, min-content)) 20px 20px" >+PASS element.style.gridTemplateColumns is "repeat(auto-fit, minmax(300px, min-content)) repeat(2, 20px)" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "60px 0px [bar foo] 10px [foo] 10px" >-PASS element.style.gridTemplateRows is "10% repeat(auto-fit, minmax(30em, max-content) [bar]) [foo] 1em [foo] 1em" >+PASS element.style.gridTemplateRows is "repeat(1, 10%) repeat(auto-fit, minmax(30em, max-content) [bar]) repeat(2, [foo] 1em)" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[a z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y b] 30px [c d] 20px [e]" > PASS element.style.gridTemplateColumns is "[a] repeat(auto-fit, [z] 100px [y]) [b] 30px [c d] 20px [e]" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y a b] 30px [c d] 20px [e]" > PASS element.style.gridTemplateRows is "repeat(auto-fit, [z] 100px [y]) [a b] 30px [c d] 20px [e]" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[a z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y b] 30px [c] 20px [e]" >-PASS element.style.gridTemplateColumns is "[a] repeat(auto-fit, [z] 100px [y]) [b] 30px [c] 20px [e]" >+PASS element.style.gridTemplateColumns is "[a] repeat(auto-fit, [z] 100px [y]) repeat(1, [b] 30px [c]) 20px [e]" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[a b] 30px [c d] 20px [e z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y]" > PASS element.style.gridTemplateRows is "[a b] 30px [c d] 20px [e] repeat(auto-fit, [z] 100px [y])" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[start] 0px 0px [end start] 0px 0px [end]" >diff --git a/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html b/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html >index eb37897eb49e4a3ea354e580f47db5bb4e7abed2..4d937dd58f387ae844935e159eda14307bfb7dea 100644 >--- a/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html >+++ b/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html >@@ -13,14 +13,14 @@ body { font-size: 10px; } > debug("Test auto-repeat syntax."); > testGridTemplatesSetJSValues("repeat(auto-fill, [foo bar] 200px)", "repeat(auto-fill, 20em [foo bar])", "[foo bar] 200px [foo bar] 200px [foo bar] 200px [foo bar] 200px", "200px [foo bar] 200px [foo bar] 200px [foo bar]"); > testGridTemplatesSetJSValues("repeat(auto-fill, [foo bar] minmax(300px, 1fr))", "repeat(auto-fill, [foo] minmax(175px, max-content) [bar])", "[foo bar] 400px [foo bar] 400px", "[foo] 175px [bar foo] 175px [bar foo] 175px [bar]"); >- testGridTemplatesSetJSValues("repeat(auto-fill, minmax(50px, 100px)) repeat(2, 250px)", "repeat(1, 450px) repeat(auto-fill, minmax(max-content, 5em) [bar]) repeat(2, [foo] 1em)", "100px 100px 100px 250px 250px", "450px 50px [bar] 50px [bar foo] 10px [foo] 10px", "repeat(auto-fill, minmax(50px, 100px)) 250px 250px", "450px repeat(auto-fill, minmax(max-content, 5em) [bar]) [foo] 1em [foo] 1em"); >+ testGridTemplatesSetJSValues("repeat(auto-fill, minmax(50px, 100px)) repeat(2, 250px)", "repeat(1, 450px) repeat(auto-fill, minmax(max-content, 5em) [bar]) repeat(2, [foo] 1em)", "100px 100px 100px 250px 250px", "450px 50px [bar] 50px [bar foo] 10px [foo] 10px", "repeat(auto-fill, minmax(50px, 100px)) repeat(2, 250px)", "repeat(1, 450px) repeat(auto-fill, minmax(max-content, 5em) [bar]) repeat(2, [foo] 1em)"); > testGridTemplatesSetJSValues("[start] 10% repeat(auto-fill, [foo bar] 200px) [end]", "75px [prev] repeat(auto-fill, 20em [foo bar]) [next] 15em [last end]", "[start] 80px [foo bar] 200px [foo bar] 200px [foo bar] 200px [end]", "75px [prev] 200px [foo bar next] 150px [last end]"); > testGridTemplatesSetJSValues("repeat(auto-fit, [foo bar] 150px)", "repeat(auto-fit, 24em [foo bar])", "[foo bar] 0px [foo bar] 0px [foo bar] 0px [foo bar] 0px [foo bar] 0px", "0px [foo bar] 0px [foo bar]"); > testGridTemplatesSetJSValues("repeat(auto-fill, [start] 200px 100px [end])", "100px [foo] repeat(auto-fill, [a] 2em [b] 10% [c]) [bar] 3em", "[start] 200px 100px [end start] 200px 100px [end]", "100px [foo a] 20px [b] 60px [c a] 20px [b] 60px [c a] 20px [b] 60px [c a] 20px [b] 60px [c a] 20px [b] 60px [c bar] 30px"); > testGridTemplatesSetJSValues("repeat(auto-fit, [foo bar] minmax(270px, 1fr))", "repeat(auto-fit, [foo] minmax(20em, max-content) [bar])", "[foo bar] 0px [foo bar] 0px", "[foo] 0px [bar foo] 0px [bar foo] 0px [bar]"); >- testGridTemplatesSetJSValues("repeat(auto-fit, minmax(300px, min-content)) repeat(2, 20px)", "repeat(1, 10%) repeat(auto-fit, minmax(30em, max-content) [bar]) repeat(2, [foo] 1em)", "0px 0px 20px 20px", "60px 0px [bar foo] 10px [foo] 10px", "repeat(auto-fit, minmax(300px, min-content)) 20px 20px", "10% repeat(auto-fit, minmax(30em, max-content) [bar]) [foo] 1em [foo] 1em"); >+ testGridTemplatesSetJSValues("repeat(auto-fit, minmax(300px, min-content)) repeat(2, 20px)", "repeat(1, 10%) repeat(auto-fit, minmax(30em, max-content) [bar]) repeat(2, [foo] 1em)", "0px 0px 20px 20px", "60px 0px [bar foo] 10px [foo] 10px", "repeat(auto-fit, minmax(300px, min-content)) repeat(2, 20px)", "repeat(1, 10%) repeat(auto-fit, minmax(30em, max-content) [bar]) repeat(2, [foo] 1em)"); > testGridTemplatesSetJSValues("[a] repeat(auto-fit, [z] 100px [y]) [b] 30px [c d] 20px [e]", "repeat(auto-fit, [z] 100px [y]) [a b] 30px [c d] 20px [e]", "[a z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y b] 30px [c d] 20px [e]", "[z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y a b] 30px [c d] 20px [e]"); >- testGridTemplatesSetJSValues("[a] repeat(auto-fit, [z] 100px [y]) repeat(1, [b] 30px [c]) 20px [e]", "[a b] 30px [c d] 20px [e] repeat(auto-fit, [z] 100px [y])", "[a z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y b] 30px [c] 20px [e]", "[a b] 30px [c d] 20px [e z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y]", "[a] repeat(auto-fit, [z] 100px [y]) [b] 30px [c] 20px [e]"); >+ testGridTemplatesSetJSValues("[a] repeat(auto-fit, [z] 100px [y]) repeat(1, [b] 30px [c]) 20px [e]", "[a b] 30px [c d] 20px [e] repeat(auto-fit, [z] 100px [y])", "[a z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y b] 30px [c] 20px [e]", "[a b] 30px [c d] 20px [e z] 0px [y z] 0px [y z] 0px [y z] 0px [y z] 0px [y]", "[a] repeat(auto-fit, [z] 100px [y]) repeat(1, [b] 30px [c]) 20px [e]"); > testGridTemplatesSetJSValues("repeat(auto-fit, [start] 200px 100px [end])", "100px [foo] repeat(auto-fit, [a] 2em [b] 10% [c]) [bar] 3em", "[start] 0px 0px [end start] 0px 0px [end]", "100px [foo a] 0px [b] 0px [c a] 0px [b] 0px [c a] 0px [b] 0px [c a] 0px [b] 0px [c a] 0px [b] 0px [c bar] 30px"); > > debug(""); >diff --git a/LayoutTests/fast/css-grid-layout/grid-repeat-calc-expected.txt b/LayoutTests/fast/css-grid-layout/grid-repeat-calc-expected.txt >index 6ff29067570dbbd115c3125084586ad8164ac8a9..476d107e3bd761cf28e5cfa81364b4f4564ef80b 100644 >--- a/LayoutTests/fast/css-grid-layout/grid-repeat-calc-expected.txt >+++ b/LayoutTests/fast/css-grid-layout/grid-repeat-calc-expected.txt >@@ -5,7 +5,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE > > PASS testDiv.style['grid-template-rows'] is "" > testDiv.style['grid-template-rows'] = 'repeat(calc(1 + 1), 18px)' >-PASS testDiv.style['grid-template-rows'] is "18px 18px" >+PASS testDiv.style['grid-template-rows'] is "repeat(2, 18px)" > PASS window.getComputedStyle(testDiv).getPropertyValue('grid-template-rows') is "18px 18px" > PASS successfullyParsed is true > >diff --git a/LayoutTests/fast/css-grid-layout/grid-repeat-calc.html b/LayoutTests/fast/css-grid-layout/grid-repeat-calc.html >index 3f9dccf595a0e24ba584ff78d809ca06297fe237..725c9278a2fa1eb9521c8e5c36fb6fe87e85c1b1 100644 >--- a/LayoutTests/fast/css-grid-layout/grid-repeat-calc.html >+++ b/LayoutTests/fast/css-grid-layout/grid-repeat-calc.html >@@ -10,7 +10,7 @@ var testDiv = document.getElementById("testDiv"); > // grid-template-columns: repeat(1, 15%); > shouldBeEmptyString("testDiv.style['grid-template-rows']"); > evalAndLog("testDiv.style['grid-template-rows'] = 'repeat(calc(1 + 1), 18px)'"); >-shouldBeEqualToString("testDiv.style['grid-template-rows']", "18px 18px"); >+shouldBeEqualToString("testDiv.style['grid-template-rows']", "repeat(2, 18px)"); > shouldBeEqualToString("window.getComputedStyle(testDiv).getPropertyValue('grid-template-rows')", "18px 18px"); > > </script> >diff --git a/LayoutTests/fast/css-grid-layout/named-grid-line-get-set-expected.txt b/LayoutTests/fast/css-grid-layout/named-grid-line-get-set-expected.txt >index e95c4b2e1f5f276c0ca8baf6e3b453adfeea6990..c3b4d99e9cc675e7f8c03331547ba84ad934e510 100644 >--- a/LayoutTests/fast/css-grid-layout/named-grid-line-get-set-expected.txt >+++ b/LayoutTests/fast/css-grid-layout/named-grid-line-get-set-expected.txt >@@ -77,9 +77,9 @@ PASS element.style.gridTemplateColumns is "[foo bar] auto [foo] auto [bar]" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[foo bar] 0px [foo] 0px [bar]" > PASS element.style.gridTemplateRows is "[foo bar] auto [foo] auto [bar]" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[first] 0px [foo bar] 20px [foo bar] 20px" >-PASS element.style.gridTemplateColumns is "[first] auto [foo bar] 20px [foo bar] 20px" >+PASS element.style.gridTemplateColumns is "[first] auto repeat(2, [foo bar] 20px)" > PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "220px [foo] 300px [baz]" >-PASS element.style.gridTemplateRows is "220px [foo] 50% [baz]" >+PASS element.style.gridTemplateRows is "220px [foo] repeat(1, 50% [baz])" > > Test getting invalid grid-template-columns and grid-template-rows set through CSS > PASS window.getComputedStyle(gridWithoutBrackets, '').getPropertyValue('grid-template-columns') is "none" >diff --git a/LayoutTests/fast/css-grid-layout/named-grid-line-get-set.html b/LayoutTests/fast/css-grid-layout/named-grid-line-get-set.html >index f3c3b9ac72c6156fbf398f33aaaf2bb8dbe4d04d..a391f48568fdc348e640a9ccdca8def0b043ac28 100644 >--- a/LayoutTests/fast/css-grid-layout/named-grid-line-get-set.html >+++ b/LayoutTests/fast/css-grid-layout/named-grid-line-get-set.html >@@ -124,7 +124,7 @@ > testGridTemplatesSetJSValues("[first nav] minmax(min-content, max-content) [last]", "[first nav] minmax(max-content, min-content) [last]", "[first nav] 0px [last]", "[first nav] 0px [last]", "[first nav] minmax(min-content, max-content) [last]", "[first nav] minmax(max-content, min-content) [last]"); > testGridTemplatesSetJSValues("[first nav] minmax(min-content, max-content) [nav] auto [last]", "[first nav2] minmax(max-content, min-content) [nav2] minmax(10px, 15px) [last]", "[first nav] 0px [nav] 0px [last]", "[first nav2] 0px [nav2] 15px [last]", "[first nav] minmax(min-content, max-content) [nav] auto [last]", "[first nav2] minmax(max-content, min-content) [nav2] minmax(10px, 15px) [last]"); > testGridTemplatesSetJSValues("[foo bar] auto [foo] auto [bar]", "[foo bar] auto [foo] auto [bar]", "[foo bar] 0px [foo] 0px [bar]", "[foo bar] 0px [foo] 0px [bar]", "[foo bar] auto [foo] auto [bar]", "[foo bar] auto [foo] auto [bar]"); >- testGridTemplatesSetJSValues("[first] auto repeat(2, [foo bar] 20px)", "220px [foo] repeat(1, 50% [baz])", "[first] 0px [foo bar] 20px [foo bar] 20px", "220px [foo] 300px [baz]", "[first] auto [foo bar] 20px [foo bar] 20px", "220px [foo] 50% [baz]"); >+ testGridTemplatesSetJSValues("[first] auto repeat(2, [foo bar] 20px)", "220px [foo] repeat(1, 50% [baz]", "[first] 0px [foo bar] 20px [foo bar] 20px", "220px [foo] 300px [baz]", "[first] auto repeat(2, [foo bar] 20px)", "220px [foo] repeat(1, 50% [baz])"); > > debug(""); > debug("Test getting invalid grid-template-columns and grid-template-rows set through CSS"); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..95970557fddc15ea2cee66e434321ab65cef4c12 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002-expected.txt >@@ -0,0 +1,22 @@ >+ >+PASS grid-template-columns: repeat(1, auto); and grid-template-rows: repeat(1, auto); >+PASS grid-template-columns: repeat(2, auto); and grid-template-rows: repeat(2, auto); >+PASS grid-template-columns: repeat(2, minmax(50px, calc(50% + 50px))); and grid-template-rows: repeat(2, minmax(50px, calc(50% + 50px))); >+PASS grid-template-columns: repeat(5, 10%); and grid-template-rows: repeat(5, 10%); >+PASS grid-template-columns: max-content repeat(2, 25%) 1fr; and grid-template-rows: max-content repeat(2, 25%) 1fr; >+PASS grid-template-columns: repeat(2, min-content 50px); and grid-template-rows: repeat(2, min-content 50px); >+PASS grid-template-columns: repeat(2, [a] minmax(50px, 100px) [b] 25em [c]); and grid-template-rows: repeat(2, [a] minmax(50px, 100px) [b] 25em [c]); >+PASS grid-template-columns: [a] repeat(2, auto [b] 100px) [c]; and grid-template-rows: [a] repeat(2, auto [b] 100px) [c]; >+PASS grid-template-columns: [a] auto repeat(2, [b] 100px) [c]; and grid-template-rows: [a] auto repeat(2, [b] 100px) [c]; >+PASS grid-template-columns: [a] repeat(2, auto [b]) 100px [c]; and grid-template-rows: [a] repeat(2, auto [b]) 100px [c]; >+PASS grid-template-columns: [a] repeat(2, [b] 100px); and grid-template-rows: [a] repeat(2, [b] 100px); >+PASS grid-template-columns: [a] repeat(2, [b] auto [c]) [d]; and grid-template-rows: [a] repeat(2, [b] auto [c]) [d]; >+PASS grid-template-columns: [a] min-content repeat(2, [b] 1fr [c] calc(10% + 20px)) [d] minmax(30em, 50em) [e]; and grid-template-rows: [a] min-content repeat(2, [b] 1fr [c] calc(10% + 20px)) [d] minmax(30em, 50em) [e]; >+PASS grid-template-columns: repeat(-1, auto); and grid-template-rows: repeat(-1, auto); >+PASS grid-template-columns: repeat(auto, 2); and grid-template-rows: repeat(auto, 2); >+PASS grid-template-columns: repeat 2, auto; and grid-template-rows: repeat 2, auto; >+PASS grid-template-columns: repeat(2 auto); and grid-template-rows: repeat(2 auto); >+PASS grid-template-columns: 100px (repeat 2, auto); and grid-template-rows: 100px (repeat 2, auto); >+PASS grid-template-columns: repeat(2, 50px repeat(2, 100px)); and grid-template-rows: repeat(2, 50px repeat(2, 100px)); >+PASS grid-template-columns: 100px repeat(2, [a]); and grid-template-rows: 100px repeat(2, [a]); >+GRID ITEM >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1bdc24d9dd0040f37ab8d8b4bc71510d51e3210b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002.html >@@ -0,0 +1,65 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>CSS Grid Layout Test: Support 'repeat()' notation for 'grid-template-columns' and 'grid-template-rows' properties</title> >+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> >+<link rel="help" href="http://www.w3.org/TR/css-grid-1/#repeat-notation" title="5.1.2 Repeating Rows and Columns: the 'repeat()' notation"> >+<meta name="assert" content="This test checks that 'grid-template-columns' and 'grid-template-rows' properties support 'repeat()' notation, and that their declared value serializes correctly."> >+<style> >+#grid { >+ display: grid; >+ width: 800px; >+ height: 600px; >+ font: 10px/1 Ahem; >+ justify-content: start; >+ align-content: start; >+} >+</style> >+ >+<div id="log"></div> >+ >+<div id="grid"> >+ <div>GRID ITEM</div> >+</div> >+ >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+var {style} = document.getElementById("grid"); >+ >+function testGridTemplateColumnsRows(assignedValue, expectedValue = assignedValue) { >+ test(function() { >+ style.gridTemplateColumns = assignedValue; >+ style.gridTemplateRows = assignedValue; >+ assert_equals(style.gridTemplateColumns, expectedValue, "gridTemplateColumns"); >+ assert_equals(style.gridTemplateRows, expectedValue, "gridTemplateRows"); >+ }, `grid-template-columns: ${assignedValue}; and grid-template-rows: ${assignedValue};`); >+} >+ >+// Valid values. >+testGridTemplateColumnsRows("repeat(1, auto)"); >+testGridTemplateColumnsRows("repeat(2, auto)"); >+testGridTemplateColumnsRows("repeat(2, minmax(50px, calc(50% + 50px)))"); >+testGridTemplateColumnsRows("repeat(5, 10%)"); >+testGridTemplateColumnsRows("max-content repeat(2, 25%) 1fr"); >+testGridTemplateColumnsRows("repeat(2, min-content 50px)"); >+testGridTemplateColumnsRows("repeat(2, [a] minmax(50px, 100px) [b] 25em [c])"); >+testGridTemplateColumnsRows("[a] repeat(2, auto [b] 100px) [c]"); >+testGridTemplateColumnsRows("[a] auto repeat(2, [b] 100px) [c]"); >+testGridTemplateColumnsRows("[a] repeat(2, auto [b]) 100px [c]"); >+testGridTemplateColumnsRows("[a] repeat(2, [b] 100px)"); >+testGridTemplateColumnsRows("[a] repeat(2, [b] auto [c]) [d]"); >+testGridTemplateColumnsRows("[a] min-content repeat(2, [b] 1fr [c] calc(10% + 20px)) [d] minmax(30em, 50em) [e]"); >+ >+// Reset values. >+style.gridTemplateColumns = ""; >+style.gridTemplateRows = ""; >+ >+// Wrong values. >+testGridTemplateColumnsRows("repeat(-1, auto)", ""); >+testGridTemplateColumnsRows("repeat(auto, 2)", ""); >+testGridTemplateColumnsRows("repeat 2, auto", ""); >+testGridTemplateColumnsRows("repeat(2 auto)", ""); >+testGridTemplateColumnsRows("100px (repeat 2, auto)", ""); >+testGridTemplateColumnsRows("repeat(2, 50px repeat(2, 100px))", ""); >+testGridTemplateColumnsRows("100px repeat(2, [a])", ""); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/w3c-import.log >index f7045c3743bfcad141ac4a2d7520e167437287d2..c1c6c88d244940ac94834d1d3ff8b41d402e3fbb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/w3c-import.log >@@ -40,6 +40,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-grid-template-columns-rows-001.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-named-grid-lines-001.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-001.html >+/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-support-repeat-002.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-template-columns-fit-content-001-expected.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-template-columns-fit-content-001.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-template-columns-rows-resolved-values-001.html
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197840
:
369742
|
369747
|
369762
|
369785
|
369804
|
369887