Title: [234761] trunk
Revision
234761
Author
[email protected]
Date
2018-08-10 10:08:44 -0700 (Fri, 10 Aug 2018)

Log Message

[IntersectionObserver] Implement rootMargin parsing
https://bugs.webkit.org/show_bug.cgi?id=188469

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update expectations for newly passing test cases.

* web-platform-tests/intersection-observer/observer-attributes-expected.txt:
* web-platform-tests/intersection-observer/observer-exceptions-expected.txt:

Source/WebCore:

Parse IntersectionObserver's rootMargin argument and throw an exception if it's invalid.
Change the stored rootMargin from a String to a LengthBox so that future patches can
use this value in intersection logic.

Tested by: imported/w3c/web-platform-tests/intersection-observer/observer-attributes.html
           imported/w3c/web-platform-tests/intersection-observer/observer-exceptions.html
           intersection-observer/intersection-observer-interface.html

* page/IntersectionObserver.cpp:
(WebCore::parseRootMargin):
(WebCore::IntersectionObserver::create):
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::rootMargin const):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::create): Deleted.
(WebCore::IntersectionObserver::rootMargin const): Deleted.
* page/IntersectionObserver.idl:

LayoutTests:

* intersection-observer/intersection-observer-interface-expected.txt:
* intersection-observer/intersection-observer-interface.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (234760 => 234761)


--- trunk/LayoutTests/ChangeLog	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/LayoutTests/ChangeLog	2018-08-10 17:08:44 UTC (rev 234761)
@@ -1,3 +1,13 @@
+2018-08-10  Ali Juma  <[email protected]>
+
+        [IntersectionObserver] Implement rootMargin parsing
+        https://bugs.webkit.org/show_bug.cgi?id=188469
+
+        Reviewed by Darin Adler.
+
+        * intersection-observer/intersection-observer-interface-expected.txt:
+        * intersection-observer/intersection-observer-interface.html:
+
 2018-08-10  Joseph Pecoraro  <[email protected]>
 
         Eliminate remaining instances of "ElCapitan" from LayoutTests / Tools

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (234760 => 234761)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-08-10 17:08:44 UTC (rev 234761)
@@ -1,3 +1,15 @@
+2018-08-10  Ali Juma  <[email protected]>
+
+        [IntersectionObserver] Implement rootMargin parsing
+        https://bugs.webkit.org/show_bug.cgi?id=188469
+
+        Reviewed by Darin Adler.
+
+        Update expectations for newly passing test cases.
+
+        * web-platform-tests/intersection-observer/observer-attributes-expected.txt:
+        * web-platform-tests/intersection-observer/observer-exceptions-expected.txt:
+
 2018-08-09  Ali Juma  <[email protected]>
 
         Import WPTs for IntersectionObserver

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes-expected.txt (234760 => 234761)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes-expected.txt	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes-expected.txt	2018-08-10 17:08:44 UTC (rev 234761)
@@ -2,8 +2,8 @@
 PASS Observer attribute getters. 
 PASS observer.root 
 PASS observer.thresholds 
-FAIL observer.rootMargin assert_equals: expected "0px 0px 0px 0px" but got "0px"
+PASS observer.rootMargin 
 PASS set observer.root 
 PASS set observer.thresholds 
-FAIL set observer.rootMargin assert_equals: expected "10% 20px 10% 20px" but got "10% 20px"
+PASS set observer.rootMargin 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt (234760 => 234761)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt	2018-08-10 17:08:44 UTC (rev 234761)
@@ -3,23 +3,11 @@
     new IntersectionObserver(e => {}, {threshold: [1.1]})
   }" did not throw
 PASS IntersectionObserver constructor with { threshold: ["foo"] } 
-FAIL IntersectionObserver constructor witth { rootMargin: "1" } assert_throws: function "function () {
-    new IntersectionObserver(e => {}, {rootMargin: "1"})
-  }" did not throw
-FAIL IntersectionObserver constructor with { rootMargin: "2em" } assert_throws: function "function () {
-    new IntersectionObserver(e => {}, {rootMargin: "2em"})
-  }" did not throw
-FAIL IntersectionObserver constructor with { rootMargin: "auto" } assert_throws: function "function () {
-    new IntersectionObserver(e => {}, {rootMargin: "auto"})
-  }" did not throw
-FAIL IntersectionObserver constructor with { rootMargin: "calc(1px + 2px)" } assert_throws: function "function () {
-    new IntersectionObserver(e => {}, {rootMargin: "calc(1px + 2px)"})
-  }" did not throw
-FAIL IntersectionObserver constructor with { rootMargin: "1px !important" } assert_throws: function "function () {
-    new IntersectionObserver(e => {}, {rootMargin: "1px !important"})
-  }" did not throw
-FAIL IntersectionObserver constructor with { rootMargin: "1px 1px 1px 1px 1px" } assert_throws: function "function () {
-    new IntersectionObserver(e => {}, {rootMargin: "1px 1px 1px 1px 1px"})
-  }" did not throw
+PASS IntersectionObserver constructor witth { rootMargin: "1" } 
+PASS IntersectionObserver constructor with { rootMargin: "2em" } 
+PASS IntersectionObserver constructor with { rootMargin: "auto" } 
+PASS IntersectionObserver constructor with { rootMargin: "calc(1px + 2px)" } 
+PASS IntersectionObserver constructor with { rootMargin: "1px !important" } 
+PASS IntersectionObserver constructor with { rootMargin: "1px 1px 1px 1px 1px" } 
 PASS IntersectionObserver.observe("foo") 
 

Modified: trunk/LayoutTests/intersection-observer/intersection-observer-interface-expected.txt (234760 => 234761)


--- trunk/LayoutTests/intersection-observer/intersection-observer-interface-expected.txt	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/LayoutTests/intersection-observer/intersection-observer-interface-expected.txt	2018-08-10 17:08:44 UTC (rev 234761)
@@ -3,7 +3,10 @@
 PASS DefaultRootMargin 
 PASS DefaultRoot 
 PASS DefaultThresholds 
-PASS ExplicitRootMargin 
+PASS ExplicitOneArgumentRootMargin 
+PASS ExplicitTwoArgumentRootMargin 
+PASS ExplicitThreeArgumentRootMargin 
+PASS ExplicitFourArgumentRootMargin 
 PASS ExplicitRoot 
 PASS ExplicitThreshold 
 PASS ExplicitThresholds 

Modified: trunk/LayoutTests/intersection-observer/intersection-observer-interface.html (234760 => 234761)


--- trunk/LayoutTests/intersection-observer/intersection-observer-interface.html	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/LayoutTests/intersection-observer/intersection-observer-interface.html	2018-08-10 17:08:44 UTC (rev 234761)
@@ -15,7 +15,7 @@
     },'Constructor0');
     test(function() {
         var observer = new IntersectionObserver(function() {});
-        assert_equals(observer.rootMargin, '0px');
+        assert_equals(observer.rootMargin, '0px 0px 0px 0px');
     },'DefaultRootMargin');
     test(function() {
         var observer = new IntersectionObserver(function() {});
@@ -26,10 +26,22 @@
         assert_array_equals(observer.thresholds, [0]);
     },'DefaultThresholds');
     test(function() {
-        var observer = new IntersectionObserver(function() {}, { rootMargin: '33em 10px -120px 3pt' });
-        assert_equals(observer.rootMargin, '33em 10px -120px 3pt');
-    },'ExplicitRootMargin');
+        var observer = new IntersectionObserver(function() {}, { rootMargin: '33%' });
+        assert_equals(observer.rootMargin, '33% 33% 33% 33%');
+    },'ExplicitOneArgumentRootMargin');
     test(function() {
+        var observer = new IntersectionObserver(function() {}, { rootMargin: '33% 10px' });
+        assert_equals(observer.rootMargin, '33% 10px 33% 10px');
+    },'ExplicitTwoArgumentRootMargin');
+    test(function() {
+        var observer = new IntersectionObserver(function() {}, { rootMargin: '33% 10px -120px' });
+        assert_equals(observer.rootMargin, '33% 10px -120px 10px');
+    },'ExplicitThreeArgumentRootMargin');
+    test(function() {
+        var observer = new IntersectionObserver(function() {}, { rootMargin: '33% 10px -120px 3%' });
+        assert_equals(observer.rootMargin, '33% 10px -120px 3%');
+    },'ExplicitFourArgumentRootMargin');
+    test(function() {
         var observer = new IntersectionObserver(function() {}, { root: document.body });
         assert_equals(observer.root, document.body);
     },'ExplicitRoot');

Modified: trunk/Source/WebCore/ChangeLog (234760 => 234761)


--- trunk/Source/WebCore/ChangeLog	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/Source/WebCore/ChangeLog	2018-08-10 17:08:44 UTC (rev 234761)
@@ -1,3 +1,28 @@
+2018-08-10  Ali Juma  <[email protected]>
+
+        [IntersectionObserver] Implement rootMargin parsing
+        https://bugs.webkit.org/show_bug.cgi?id=188469
+
+        Reviewed by Darin Adler.
+
+        Parse IntersectionObserver's rootMargin argument and throw an exception if it's invalid.
+        Change the stored rootMargin from a String to a LengthBox so that future patches can
+        use this value in intersection logic.
+
+        Tested by: imported/w3c/web-platform-tests/intersection-observer/observer-attributes.html
+                   imported/w3c/web-platform-tests/intersection-observer/observer-exceptions.html
+                   intersection-observer/intersection-observer-interface.html
+
+        * page/IntersectionObserver.cpp:
+        (WebCore::parseRootMargin):
+        (WebCore::IntersectionObserver::create):
+        (WebCore::IntersectionObserver::IntersectionObserver):
+        (WebCore::IntersectionObserver::rootMargin const):
+        * page/IntersectionObserver.h:
+        (WebCore::IntersectionObserver::create): Deleted.
+        (WebCore::IntersectionObserver::rootMargin const): Deleted.
+        * page/IntersectionObserver.idl:
+
 2018-08-09  Ben Richards  <[email protected]>
 
         We should cache the compiled sandbox profile in a data vault

Modified: trunk/Source/WebCore/page/IntersectionObserver.cpp (234760 => 234761)


--- trunk/Source/WebCore/page/IntersectionObserver.cpp	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/Source/WebCore/page/IntersectionObserver.cpp	2018-08-10 17:08:44 UTC (rev 234761)
@@ -28,6 +28,9 @@
 #if ENABLE(INTERSECTION_OBSERVER)
 #include "IntersectionObserver.h"
 
+#include "CSSParserTokenRange.h"
+#include "CSSPropertyParserHelpers.h"
+#include "CSSTokenizer.h"
 #include "Element.h"
 #include "IntersectionObserverCallback.h"
 #include "IntersectionObserverEntry.h"
@@ -35,9 +38,61 @@
 
 namespace WebCore {
 
-IntersectionObserver::IntersectionObserver(Ref<IntersectionObserverCallback>&& callback, Init&& init)
+static ExceptionOr<LengthBox> parseRootMargin(String& rootMargin)
+{
+    CSSTokenizer tokenizer(rootMargin);
+    auto tokenRange = tokenizer.tokenRange();
+    Vector<Length, 4> margins;
+    while (!tokenRange.atEnd()) {
+        if (margins.size() == 4)
+            return Exception { SyntaxError, "Failed to construct 'IntersectionObserver': Extra text found at the end of rootMargin." };
+        RefPtr<CSSPrimitiveValue> parsedValue = CSSPropertyParserHelpers::consumeLengthOrPercent(tokenRange, HTMLStandardMode, ValueRangeAll);
+        if (!parsedValue || parsedValue->isCalculated())
+            return Exception { SyntaxError, "Failed to construct 'IntersectionObserver': rootMargin must be specified in pixels or percent." };
+        if (parsedValue->isPercentage())
+            margins.append(Length(parsedValue->doubleValue(), Percent));
+        else if (parsedValue->isPx())
+            margins.append(Length(parsedValue->intValue(), Fixed));
+        else
+            return Exception { SyntaxError, "Failed to construct 'IntersectionObserver': rootMargin must be specified in pixels or percent." };
+    }
+    switch (margins.size()) {
+    case 0:
+        for (unsigned i = 0; i < 4; ++i)
+            margins.append(Length());
+        break;
+    case 1:
+        for (unsigned i = 0; i < 3; ++i)
+            margins.append(margins[0]);
+        break;
+    case 2:
+        margins.append(margins[0]);
+        margins.append(margins[1]);
+        break;
+    case 3:
+        margins.append(margins[1]);
+        break;
+    case 4:
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    return LengthBox(WTFMove(margins[0]), WTFMove(margins[1]), WTFMove(margins[2]), WTFMove(margins[3]));
+}
+
+ExceptionOr<Ref<IntersectionObserver>> IntersectionObserver::create(Ref<IntersectionObserverCallback>&& callback, IntersectionObserver::Init&& init)
+{
+    auto rootMarginOrException = parseRootMargin(init.rootMargin);
+    if (rootMarginOrException.hasException())
+        return rootMarginOrException.releaseException();
+
+    return adoptRef(*new IntersectionObserver(WTFMove(callback), WTFMove(init), rootMarginOrException.releaseReturnValue()));
+}
+
+IntersectionObserver::IntersectionObserver(Ref<IntersectionObserverCallback>&& callback, Init&& init, LengthBox&& parsedRootMargin)
     : m_root(init.root)
-    , m_rootMargin(WTFMove(init.rootMargin))
+    , m_rootMargin(WTFMove(parsedRootMargin))
     , m_callback(WTFMove(callback))
 {
     if (WTF::holds_alternative<double>(init.threshold))
@@ -46,6 +101,23 @@
         m_thresholds = WTF::get<Vector<double>>(WTFMove(init.threshold));
 }
 
+String IntersectionObserver::rootMargin() const
+{
+    StringBuilder stringBuilder;
+    PhysicalBoxSide sides[4] = { PhysicalBoxSide::Top, PhysicalBoxSide::Right, PhysicalBoxSide::Bottom, PhysicalBoxSide::Left };
+    for (auto side : sides) {
+        auto& length = m_rootMargin.at(side);
+        stringBuilder.appendNumber(length.intValue());
+        if (length.type() == Percent)
+            stringBuilder.append('%');
+        else
+            stringBuilder.append("px", 2);
+        if (side != PhysicalBoxSide::Left)
+            stringBuilder.append(' ');
+    }
+    return stringBuilder.toString();
+}
+
 void IntersectionObserver::observe(Element&)
 {
 }

Modified: trunk/Source/WebCore/page/IntersectionObserver.h (234760 => 234761)


--- trunk/Source/WebCore/page/IntersectionObserver.h	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/Source/WebCore/page/IntersectionObserver.h	2018-08-10 17:08:44 UTC (rev 234761)
@@ -29,6 +29,7 @@
 
 #include "IntersectionObserverCallback.h"
 #include "IntersectionObserverEntry.h"
+#include "LengthBox.h"
 #include <wtf/RefCounted.h>
 #include <wtf/Variant.h>
 #include <wtf/text/WTFString.h>
@@ -45,13 +46,10 @@
         Variant<double, Vector<double>> threshold;
     };
 
-    static Ref<IntersectionObserver> create(Ref<IntersectionObserverCallback>&& callback, Init&& init)
-    {
-        return adoptRef(*new IntersectionObserver(WTFMove(callback), WTFMove(init)));
-    }
+    static ExceptionOr<Ref<IntersectionObserver>> create(Ref<IntersectionObserverCallback>&&, Init&&);
     
     Element* root() const { return m_root.get(); }
-    String rootMargin() const { return m_rootMargin; }
+    String rootMargin() const;
     const Vector<double>& thresholds() const { return m_thresholds; }
 
     void observe(Element&);
@@ -61,10 +59,10 @@
     Vector<RefPtr<IntersectionObserverEntry>> takeRecords();
 
 private:
-    IntersectionObserver(Ref<IntersectionObserverCallback>&&, Init&&);
+    IntersectionObserver(Ref<IntersectionObserverCallback>&&, Init&&, LengthBox&& parsedRootMargin);
     
     RefPtr<Element> m_root;
-    String m_rootMargin;
+    LengthBox m_rootMargin;
     Vector<double> m_thresholds;
     Ref<IntersectionObserverCallback> m_callback;
 };

Modified: trunk/Source/WebCore/page/IntersectionObserver.idl (234760 => 234761)


--- trunk/Source/WebCore/page/IntersectionObserver.idl	2018-08-10 16:46:21 UTC (rev 234760)
+++ trunk/Source/WebCore/page/IntersectionObserver.idl	2018-08-10 17:08:44 UTC (rev 234761)
@@ -27,6 +27,7 @@
 
 [
     Conditional=INTERSECTION_OBSERVER,
+    ConstructorMayThrowException,
     Constructor(IntersectionObserverCallback callback, optional IntersectionObserverInit options),
     ImplementationLacksVTable,
     EnabledAtRuntime=IntersectionObserver
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to