Changeset 259577 in webkit


Ignore:
Timestamp:
Apr 6, 2020 10:41:43 AM (4 years ago)
Author:
graouts@webkit.org
Message:

[Web Animations] Move Document.getAnimations() to DocumentOrShadowRoot
https://bugs.webkit.org/show_bug.cgi?id=202192
<rdar://problem/55697775>

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Update the test relevant to DocumentOrShadowRoot.getAnimations() from upstream and record three new PASS results in it. We also get two new PASS from a harness test.

  • web-platform-tests/web-animations/idlharness.window-expected.txt:
  • web-platform-tests/web-animations/interfaces/DocumentOrShadowRoot/getAnimations-expected.txt:
  • web-platform-tests/web-animations/interfaces/DocumentOrShadowRoot/getAnimations.html:
  • web-platform-tests/web-animations/testcommon.js:

(async insertFrameAndAwaitLoad):

Source/WebCore:

We remove the getAnimations() declaration from the Document interface and instead move it on the DocumentOrShadowRoot interface.

We add the new method Document::matchingAnimations() which takes a lambda that is provided an animation's effect's target to determine whether
that animation should be found in the list of animations.

In the case of Document::getAnimations(), we filter out animations targeting elements hosted in shadow roots, while in ShadowRoot:getAnimations(),
we filter out animations targeting elements that are not hosted in the shadow root the method was called on.

  • dom/Document.cpp:

(WebCore::Document::getAnimations):
(WebCore::Document::matchingAnimations):

  • dom/Document.h:
  • dom/Document.idl:
  • dom/DocumentOrShadowRoot.idl:
  • dom/Element.cpp:

(WebCore::Element::getAnimations):

  • dom/ShadowRoot.cpp:

(WebCore::ShadowRoot::getAnimations):

  • dom/ShadowRoot.h:
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r259562 r259577  
     12020-04-06  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Move Document.getAnimations() to DocumentOrShadowRoot
     4        https://bugs.webkit.org/show_bug.cgi?id=202192
     5        <rdar://problem/55697775>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Update the test relevant to DocumentOrShadowRoot.getAnimations() from upstream and record three new PASS results in it. We also get two new PASS from a harness test.
     10
     11        * web-platform-tests/web-animations/idlharness.window-expected.txt:
     12        * web-platform-tests/web-animations/interfaces/DocumentOrShadowRoot/getAnimations-expected.txt:
     13        * web-platform-tests/web-animations/interfaces/DocumentOrShadowRoot/getAnimations.html:
     14        * web-platform-tests/web-animations/testcommon.js:
     15        (async insertFrameAndAwaitLoad):
     16
    1172020-04-05  Manuel Rego Casasnovas  <rego@igalia.com>
    218
  • trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/idlharness.window-expected.txt

    r253635 r259577  
    141141PASS Document interface: document must inherit property "timeline" with the proper type
    142142PASS Document interface: document must inherit property "getAnimations()" with the proper type
    143 FAIL ShadowRoot interface: operation getAnimations() assert_own_property: interface prototype object missing non-static operation expected property "getAnimations" missing
    144 FAIL ShadowRoot interface: shadowRoot must inherit property "getAnimations()" with the proper type assert_inherits: property "getAnimations" not found in prototype chain
     143PASS ShadowRoot interface: operation getAnimations()
     144PASS ShadowRoot interface: shadowRoot must inherit property "getAnimations()" with the proper type
    145145PASS Element interface: operation animate(object, [object Object],[object Object])
    146146PASS Element interface: operation getAnimations(GetAnimationsOptions)
  • trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/DocumentOrShadowRoot/getAnimations-expected.txt

    r255821 r259577  
    66PASS Document.getAnimations() does not return an animation with a null target
    77FAIL Document.getAnimations() returns animations on elements inside same-origin iframes assert_equals: expected 1 but got 0
    8 FAIL ShadowRoot.getAnimations() return all animations in the shadow tree div.shadowRoot.getAnimations is not a function. (In 'div.shadowRoot.getAnimations()', 'div.shadowRoot.getAnimations' is undefined)
    9 FAIL Document.getAnimations() does NOT return animations in shadow trees assert_array_equals: getAnimations() called on Document does not return animations from shadow trees lengths differ, expected 0 got 1
     8FAIL iframe.contentDocument.getAnimations() returns animations on elements inside same-origin Document assert_equals: expected 1 but got 0
     9PASS ShadowRoot.getAnimations() return all animations in the shadow tree
     10PASS Document.getAnimations() does NOT return animations in shadow trees
     11PASS ShadowRoot.getAnimations() does NOT return animations in parent document
    1012PASS Document.getAnimations() triggers a style change event
    1113
  • trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/DocumentOrShadowRoot/getAnimations.html

    r255821 r259577  
    6969promise_test(async t => {
    7070  const iframe = document.createElement('iframe');
    71 
    72   const eventWatcher = new EventWatcher(t, iframe, ['load']);
    73   const event_promise = eventWatcher.wait_for('load');
    74 
    75   document.body.appendChild(iframe);
    76   t.add_cleanup(() => { document.body.removeChild(iframe); });
    77 
    78   await event_promise;
     71  await insertFrameAndAwaitLoad(t, iframe, document)
    7972
    8073  const div = createDiv(t, iframe.contentDocument)
     
    9184}, 'Document.getAnimations() returns animations on elements inside same-origin'
    9285   + ' iframes');
     86
     87promise_test(async t => {
     88  const iframe1 = document.createElement('iframe');
     89  const iframe2 = document.createElement('iframe');
     90
     91  await insertFrameAndAwaitLoad(t, iframe1, document);
     92  await insertFrameAndAwaitLoad(t, iframe2, document);
     93
     94  const div_frame1 = createDiv(t, iframe1.contentDocument)
     95  const div_main_frame = createDiv(t)
     96  const effect1 = new KeyframeEffect(div_frame1, null, 100 * MS_PER_SEC);
     97  const anim1 = new Animation(effect1, document.timeline);
     98  anim1.play();
     99  // Animation of div_frame1 is in iframe with main timeline.
     100  // The animation's timeline is from the iframe, but the effect's target
     101  // element is part of the iframe's document.
     102  assert_equals(document.getAnimations().length, 0);
     103  assert_equals(iframe1.contentDocument.getAnimations().length, 1);
     104  anim1.finish();
     105
     106   // animation of div_frame1 in iframe1 with iframe timeline
     107  const effect2 = new KeyframeEffect(div_frame1, null, 100 * MS_PER_SEC);
     108  const anim2 = new Animation(effect2, iframe1.contentDocument.timeline);
     109  anim2.play();
     110  assert_equals(document.getAnimations().length, 0);
     111  assert_equals(iframe1.contentDocument.getAnimations().length, 1);
     112  anim2.finish();
     113
     114  //animation of div_main_frame in main frame with iframe timeline
     115  const effect3 = new KeyframeEffect(div_main_frame, null, 100 * MS_PER_SEC);
     116  const anim3 = new Animation(effect3, iframe1.contentDocument.timeline);
     117  anim3.play();
     118  assert_equals(document.getAnimations().length, 1);
     119  assert_equals(iframe1.contentDocument.getAnimations().length, 0);
     120  anim3.finish();
     121
     122  //animation of div_frame1 in iframe1 with another iframe's timeline
     123  const effect4 = new KeyframeEffect(div_frame1, null, 100 * MS_PER_SEC);
     124  const anim4 = new Animation(effect4, iframe2.contentDocument.timeline);
     125  anim4.play();
     126  assert_equals(document.getAnimations().length, 0);
     127  assert_equals(iframe1.contentDocument.getAnimations().length, 1);
     128  assert_equals(iframe2.contentDocument.getAnimations().length, 0);
     129  anim4.finish();
     130}, 'iframe.contentDocument.getAnimations() returns animations on elements '
     131   + 'inside same-origin Document');
    93132
    94133test(t => {
     
    150189}, 'Document.getAnimations() does NOT return animations in shadow trees');
    151190
     191test(t => {
     192  const div = createDiv(t);
     193  const shadow = div.attachShadow({ mode: 'open' });
     194
     195  div.animate(gKeyFrames, 100 * MS_PER_SEC)
     196
     197  assert_array_equals(
     198    div.shadowRoot.getAnimations(),
     199    [],
     200    'getAnimations() called on ShadowRoot does not return animations from'
     201    + ' Document'
     202  );
     203}, 'ShadowRoot.getAnimations() does NOT return animations in parent document');
     204
    152205promise_test(async t => {
    153206  const div = createDiv(t);
  • trunk/LayoutTests/imported/w3c/web-platform-tests/web-animations/testcommon.js

    r255821 r259577  
    181181}
    182182
     183async function insertFrameAndAwaitLoad(test, iframe, doc) {
     184  const eventWatcher = new EventWatcher(test, iframe, ['load']);
     185  const event_promise = eventWatcher.wait_for('load');
     186
     187  doc.body.appendChild(iframe);
     188  test.add_cleanup(() => { doc.body.removeChild(iframe); });
     189
     190  await event_promise;
     191}
     192
    183193// Returns 'matrix()' or 'matrix3d()' function string generated from an array.
    184194function createMatrixFromArray(array) {
  • trunk/Source/WebCore/ChangeLog

    r259575 r259577  
     12020-04-06  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Move Document.getAnimations() to DocumentOrShadowRoot
     4        https://bugs.webkit.org/show_bug.cgi?id=202192
     5        <rdar://problem/55697775>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        We remove the getAnimations() declaration from the Document interface and instead move it on the DocumentOrShadowRoot interface.
     10
     11        We add the new method Document::matchingAnimations() which takes a lambda that is provided an animation's effect's target to determine whether
     12        that animation should be found in the list of animations.
     13
     14        In the case of Document::getAnimations(), we filter out animations targeting elements hosted in shadow roots, while in ShadowRoot:getAnimations(),
     15        we filter out animations targeting elements that are not hosted in the shadow root the method was called on.
     16
     17        * dom/Document.cpp:
     18        (WebCore::Document::getAnimations):
     19        (WebCore::Document::matchingAnimations):
     20        * dom/Document.h:
     21        * dom/Document.idl:
     22        * dom/DocumentOrShadowRoot.idl:
     23        * dom/Element.cpp:
     24        (WebCore::Element::getAnimations):
     25        * dom/ShadowRoot.cpp:
     26        (WebCore::ShadowRoot::getAnimations):
     27        * dom/ShadowRoot.h:
     28
    1292020-04-04  Darin Adler  <darin@apple.com>
    230
  • trunk/Source/WebCore/dom/Document.cpp

    r259575 r259577  
    81048104Vector<RefPtr<WebAnimation>> Document::getAnimations()
    81058105{
     8106    return matchingAnimations([] (Element& target) -> bool {
     8107        return !target.containingShadowRoot();
     8108    });
     8109}
     8110
     8111Vector<RefPtr<WebAnimation>> Document::matchingAnimations(const WTF::Function<bool(Element&)>& function)
     8112{
    81068113    // For the list of animations to be current, we need to account for any pending CSS changes,
    81078114    // such as updates to CSS Animations and CSS Transitions.
    81088115    updateStyleIfNeeded();
    81098116
    8110     if (m_timeline)
    8111         return m_timeline->getAnimations();
    8112     return { };
     8117    if (!m_timeline)
     8118        return { };
     8119
     8120    Vector<RefPtr<WebAnimation>> animations;
     8121    for (auto& animation : m_timeline->getAnimations()) {
     8122        auto* effect = animation->effect();
     8123        ASSERT(is<KeyframeEffect>(animation->effect()));
     8124        auto* target = downcast<KeyframeEffect>(*effect).target();
     8125        ASSERT(target);
     8126        if (function(*target))
     8127            animations.append(animation);
     8128    }
     8129    return animations;
    81138130}
    81148131
  • trunk/Source/WebCore/dom/Document.h

    r259447 r259577  
    14861486    DocumentTimeline* existingTimeline() const { return m_timeline.get(); }
    14871487    Vector<RefPtr<WebAnimation>> getAnimations();
    1488        
     1488    Vector<RefPtr<WebAnimation>> matchingAnimations(const WTF::Function<bool(Element&)>&);
     1489
    14891490#if ENABLE(ATTACHMENT_ELEMENT)
    14901491    void registerAttachmentIdentifier(const String&);
  • trunk/Source/WebCore/dom/Document.idl

    r254182 r259577  
    191191
    192192    [EnabledAtRuntime=WebAnimations] readonly attribute DocumentTimeline timeline;
    193     [EnabledAtRuntime=WebAnimations] sequence<WebAnimation> getAnimations();
    194193};
    195194
  • trunk/Source/WebCore/dom/DocumentOrShadowRoot.idl

    r251160 r259577  
    4444    // Extensions from Picture-in-Picture API (https://wicg.github.io/picture-in-picture/#documentorshadowroot-extension)
    4545    [Conditional=PICTURE_IN_PICTURE_API, EnabledBySetting=PictureInPictureAPI] readonly attribute Element? pictureInPictureElement;
     46
     47    // Extension from Web Animations API (https://drafts.csswg.org/web-animations-1/#extensions-to-the-documentorshadowroot-interface-mixin)
     48    [EnabledAtRuntime=WebAnimations] sequence<WebAnimation> getAnimations();
    4649};
  • trunk/Source/WebCore/dom/Element.cpp

    r259575 r259577  
    45354535    // pseudo element.
    45364536    if (options && options->subtree) {
    4537         Vector<RefPtr<WebAnimation>> animations;
    4538         for (auto& animation : document().getAnimations()) {
    4539             auto* effect = animation->effect();
    4540             ASSERT(is<KeyframeEffect>(animation->effect()));
    4541             auto* target = downcast<KeyframeEffect>(*effect).target();
    4542             ASSERT(target);
    4543             if (is<PseudoElement>(target)) {
    4544                 if (contains(downcast<PseudoElement>(*target).hostElement()))
    4545                     animations.append(animation);
    4546             } else if (contains(target))
    4547                 animations.append(animation);
    4548         }
    4549         return animations;
     4537        return document().matchingAnimations([&] (Element& target) -> bool {
     4538            if (is<PseudoElement>(target))
     4539                return contains(downcast<PseudoElement>(target).hostElement());
     4540            return contains(&target);
     4541        });
    45504542    }
    45514543
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r251160 r259577  
    368368#endif
    369369
    370 }
     370Vector<RefPtr<WebAnimation>> ShadowRoot::getAnimations()
     371{
     372    return document().matchingAnimations([&] (Element& target) -> bool {
     373        return target.containingShadowRoot() == this;
     374    });
     375}
     376
     377}
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r259353 r259577  
    4141class SlotAssignment;
    4242class StyleSheetList;
     43class WebAnimation;
    4344
    4445class ShadowRoot final : public DocumentFragment, public TreeScope {
     
    112113#endif
    113114
     115    Vector<RefPtr<WebAnimation>> getAnimations();
     116
    114117private:
    115118    ShadowRoot(Document&, ShadowRootMode, DelegatesFocus);
Note: See TracChangeset for help on using the changeset viewer.