Changeset 257976 in webkit
- Timestamp:
- Mar 6, 2020 3:53:49 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r257729 r257976 1 2020-03-06 Frederic Wang <fwang@igalia.com> 2 3 [intersection-observer] Accept a Document as an explicit root 4 https://bugs.webkit.org/show_bug.cgi?id=208047 5 6 Reviewed by Simon Fraser. 7 8 * web-platform-tests/intersection-observer/document-scrolling-element-root-expected.txt: 9 Update expectation now that the test passes. 10 1 11 2020-03-02 Rob Buis <rbuis@igalia.com> 2 12 -
trunk/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/document-scrolling-element-root-expected.txt
r257137 r257976 1 1 2 FAIL Observer with explicit root which is the document. Type error 2 PASS Observer with explicit root which is the document. 3 PASS First rAF. 3 4 -
trunk/Source/WebCore/ChangeLog
r257975 r257976 1 2020-03-06 Frederic Wang <fwang@igalia.com> 2 3 [intersection-observer] Accept a Document as an explicit root 4 https://bugs.webkit.org/show_bug.cgi?id=208047 5 6 Reviewed by Simon Fraser. 7 8 This patch introduces a recent enhancement to the Intersection Observer specification: the 9 root initialization parameter can be explicitly be set to a Document. The typical use case 10 is when document is an iframe. See https://github.com/w3c/IntersectionObserver/issues/372 11 12 This patch also updates the way Element's intersection observer data is handled so that it is 13 more consistent with the explicit Document root case introduced here. 14 15 Test: imported/w3c/web-platform-tests/intersection-observer/document-scrolling-element-root.html 16 17 * dom/Document.cpp: 18 (WebCore::Document::~Document): Notify observers about our desctruction. 19 (WebCore::Document::updateIntersectionObservations): Use new method name. This does not 20 require null-check because ensureIntersectionObserverData() has been called in 21 IntersectionObserver::observe(). 22 (WebCore::Document::ensureIntersectionObserverData): Return reference to intersection 23 observer data for this document, creating one if it does not exist. 24 * dom/Document.h: Add new intersection observer data, used for documents that are explicit 25 intersection observer roots. 26 (WebCore::Document::intersectionObserverDataIfExists): Return pointer to intersection 27 observer data or null if it does not exist. 28 * dom/Element.cpp: 29 (WebCore::Element::didMoveToNewDocument): Use new method name. 30 (WebCore::Element::disconnectFromIntersectionObservers): Ditto and null-check weak refs. 31 (WebCore::Element::intersectionObserverDataIfExists): Rename method to match Document's one 32 and be more explicit that it will be null if it does not exist. 33 (WebCore::Element::intersectionObserverData): Renamed. 34 * dom/Element.h: Renamed. 35 * html/LazyLoadImageObserver.cpp: 36 (WebCore::LazyLoadImageObserver::intersectionObserver): Initialize with a WTF::Optional 37 after API change. 38 * page/IntersectionObserver.cpp: 39 (WebCore::IntersectionObserver::create): Pass a Node* root, which can be null (implicit 40 root), Document* or Element* (explicit roots). This is determined from init.root. 41 (WebCore::IntersectionObserver::IntersectionObserver): Handle the case of explicit Document 42 root. 43 (WebCore::IntersectionObserver::~IntersectionObserver): Ditto and update method name for 44 the explicit Element case. Note that in both explicit root cases the corresponding 45 ensureIntersectionObserverData() method had been called in the constructor so they can 46 be safely deferenced. 47 (WebCore::IntersectionObserver::removeTargetRegistration): Use new method name. 48 * page/IntersectionObserver.h: Update comment and code now that explicit root is a Node* and 49 IntersectionObserver::Init::root is either an Element or a Document or null. 50 (WebCore::IntersectionObserver::root const): Ditto. 51 (): Deleted. 52 * page/IntersectionObserver.idl: Update IDL to match the spec IntersectionObserver::root 53 is a nullable Node and IntersectionObserverInit::root a nullable Element or Document. 54 1 55 2020-03-06 Yusuke Suzuki <ysuzuki@apple.com> 2 56 -
trunk/Source/WebCore/dom/Document.cpp
r257862 r257976 636 636 m_logger->removeObserver(*this); 637 637 638 #if ENABLE(INTERSECTION_OBSERVER) 639 if (m_intersectionObserverData) { 640 for (const auto& observer : m_intersectionObserverData->observers) { 641 if (observer) 642 observer->rootDestroyed(); 643 } 644 m_intersectionObserverData->observers.clear(); 645 // Document cannot be a target. 646 ASSERT(m_intersectionObserverData->registrations.isEmpty()); 647 } 648 #endif 649 638 650 ASSERT(allDocumentsMap().contains(m_identifier)); 639 651 allDocumentsMap().remove(m_identifier); … … 7575 7587 continue; 7576 7588 for (Element* target : observer->observationTargets()) { 7577 auto& targetRegistrations = target->intersectionObserverData ()->registrations;7589 auto& targetRegistrations = target->intersectionObserverDataIfExists()->registrations; 7578 7590 auto index = targetRegistrations.findMatching([observer](auto& registration) { 7579 7591 return registration.observer.get() == observer; … … 7662 7674 } 7663 7675 7676 IntersectionObserverData& Document::ensureIntersectionObserverData() 7677 { 7678 if (!m_intersectionObserverData) 7679 m_intersectionObserverData = makeUnique<IntersectionObserverData>(); 7680 return *m_intersectionObserverData; 7681 } 7682 7664 7683 #endif 7665 7684 -
trunk/Source/WebCore/dom/Document.h
r257862 r257976 253 253 #if ENABLE(INTERSECTION_OBSERVER) 254 254 class IntersectionObserver; 255 struct IntersectionObserverData; 255 256 #endif 256 257 … … 1390 1391 void updateIntersectionObservations(); 1391 1392 void scheduleInitialIntersectionObservationUpdate(); 1393 IntersectionObserverData& ensureIntersectionObserverData(); 1394 IntersectionObserverData* intersectionObserverDataIfExists() { return m_intersectionObserverData.get(); } 1392 1395 #endif 1393 1396 … … 1824 1827 Timer m_intersectionObserversNotifyTimer; 1825 1828 Timer m_intersectionObserversInitialUpdateTimer; 1829 // This is only non-null when this document is an explicit root. 1830 std::unique_ptr<IntersectionObserverData> m_intersectionObserverData; 1826 1831 #endif 1827 1832 -
trunk/Source/WebCore/dom/Element.cpp
r257846 r257976 2066 2066 2067 2067 #if ENABLE(INTERSECTION_OBSERVER) 2068 if (auto* observerData = intersectionObserverData ()) {2068 if (auto* observerData = intersectionObserverDataIfExists()) { 2069 2069 for (const auto& observer : observerData->observers) { 2070 2070 if (observer->hasObservationTargets()) { … … 3725 3725 void Element::disconnectFromIntersectionObservers() 3726 3726 { 3727 auto* observerData = intersectionObserverData ();3727 auto* observerData = intersectionObserverDataIfExists(); 3728 3728 if (!observerData) 3729 3729 return; 3730 3730 3731 for (const auto& registration : observerData->registrations) 3732 registration.observer->targetDestroyed(*this); 3731 for (const auto& registration : observerData->registrations) { 3732 if (registration.observer) 3733 registration.observer->targetDestroyed(*this); 3734 } 3733 3735 observerData->registrations.clear(); 3734 3736 3735 for (const auto& observer : observerData->observers) 3736 observer->rootDestroyed(); 3737 for (const auto& observer : observerData->observers) { 3738 if (observer) 3739 observer->rootDestroyed(); 3740 } 3737 3741 observerData->observers.clear(); 3738 3742 } … … 3746 3750 } 3747 3751 3748 IntersectionObserverData* Element::intersectionObserverData ()3752 IntersectionObserverData* Element::intersectionObserverDataIfExists() 3749 3753 { 3750 3754 return hasRareData() ? elementRareData()->intersectionObserverData() : nullptr; -
trunk/Source/WebCore/dom/Element.h
r257839 r257976 592 592 #if ENABLE(INTERSECTION_OBSERVER) 593 593 IntersectionObserverData& ensureIntersectionObserverData(); 594 IntersectionObserverData* intersectionObserverData ();594 IntersectionObserverData* intersectionObserverDataIfExists(); 595 595 #endif 596 596 -
trunk/Source/WebCore/html/LazyLoadImageObserver.cpp
r256786 r257976 86 86 if (!m_lazyLoadIntersectionObserver) { 87 87 auto callback = LazyImageLoadIntersectionObserverCallback::create(document); 88 IntersectionObserver::Init options { nullptr, emptyString(), { } };88 IntersectionObserver::Init options { WTF::nullopt, emptyString(), { } }; 89 89 auto observer = IntersectionObserver::create(document, WTFMove(callback), WTFMove(options)); 90 90 if (observer.hasException()) -
trunk/Source/WebCore/page/IntersectionObserver.cpp
r251244 r257976 87 87 ExceptionOr<Ref<IntersectionObserver>> IntersectionObserver::create(Document& document, Ref<IntersectionObserverCallback>&& callback, IntersectionObserver::Init&& init) 88 88 { 89 Node* root = nullptr; 90 if (init.root) { 91 WTF::switchOn(*init.root, [&root] (RefPtr<Element> element) { 92 root = element.get(); 93 }, [&root] (RefPtr<Document> document) { 94 root = document.get(); 95 }); 96 } 97 89 98 auto rootMarginOrException = parseRootMargin(init.rootMargin); 90 99 if (rootMarginOrException.hasException()) … … 104 113 } 105 114 106 return adoptRef(*new IntersectionObserver(document, WTFMove(callback), init.root, rootMarginOrException.releaseReturnValue(), WTFMove(thresholds)));107 } 108 109 IntersectionObserver::IntersectionObserver(Document& document, Ref<IntersectionObserverCallback>&& callback, Element* root, LengthBox&& parsedRootMargin, Vector<double>&& thresholds)115 return adoptRef(*new IntersectionObserver(document, WTFMove(callback), root, rootMarginOrException.releaseReturnValue(), WTFMove(thresholds))); 116 } 117 118 IntersectionObserver::IntersectionObserver(Document& document, Ref<IntersectionObserverCallback>&& callback, Node* root, LengthBox&& parsedRootMargin, Vector<double>&& thresholds) 110 119 : ActiveDOMObject(callback->scriptExecutionContext()) 111 120 , m_root(root) … … 114 123 , m_callback(WTFMove(callback)) 115 124 { 116 if (m_root) { 117 auto& observerData = m_root->ensureIntersectionObserverData(); 125 if (is<Document>(m_root)) { 126 auto& observerData = downcast<Document>(*m_root).ensureIntersectionObserverData(); 127 observerData.observers.append(makeWeakPtr(this)); 128 } else if (m_root) { 129 ASSERT(is<Element>(m_root)); 130 auto& observerData = downcast<Element>(*m_root).ensureIntersectionObserverData(); 118 131 observerData.observers.append(makeWeakPtr(this)); 119 132 } else if (auto* frame = document.frame()) … … 126 139 IntersectionObserver::~IntersectionObserver() 127 140 { 128 if (m_root) 129 m_root->intersectionObserverData()->observers.removeFirst(this); 141 if (is<Document>(m_root)) { 142 downcast<Document>(*m_root).intersectionObserverDataIfExists()->observers.removeFirst(this); 143 } else if (m_root) { 144 ASSERT(is<Element>(m_root)); 145 downcast<Element>(*m_root).intersectionObserverDataIfExists()->observers.removeFirst(this); 146 } 130 147 disconnect(); 131 148 } … … 202 219 bool IntersectionObserver::removeTargetRegistration(Element& target) 203 220 { 204 auto* observerData = target.intersectionObserverData ();221 auto* observerData = target.intersectionObserverDataIfExists(); 205 222 if (!observerData) 206 223 return false; -
trunk/Source/WebCore/page/IntersectionObserver.h
r251244 r257976 42 42 class Document; 43 43 class Element; 44 class Node; 44 45 45 46 struct IntersectionObserverRegistration { … … 51 52 WTF_MAKE_STRUCT_FAST_ALLOCATED; 52 53 53 // IntersectionObservers for which the elementthat owns this IntersectionObserverData is the root.54 // IntersectionObservers for which the node that owns this IntersectionObserverData is the root. 54 55 // An IntersectionObserver is only owned by a JavaScript wrapper. ActiveDOMObject::hasPendingActivity 55 56 // is overridden to keep this wrapper alive while the observer has ongoing observations. 56 57 Vector<WeakPtr<IntersectionObserver>> observers; 57 58 58 // IntersectionObserverRegistrations for which the elementthat owns this IntersectionObserverData is the target.59 // IntersectionObserverRegistrations for which the node that owns this IntersectionObserverData is the target. 59 60 Vector<IntersectionObserverRegistration> registrations; 60 61 }; … … 63 64 public: 64 65 struct Init { 65 Element* root { nullptr };66 Optional<Variant<RefPtr<Element>, RefPtr<Document>>> root; 66 67 String rootMargin; 67 68 Variant<double, Vector<double>> threshold; … … 74 75 Document* trackingDocument() const { return m_root ? &m_root->document() : m_implicitRootDocument.get(); } 75 76 76 Element* root() const { return m_root; }77 Node* root() const { return m_root; } 77 78 String rootMargin() const; 78 79 const LengthBox& rootMarginBox() const { return m_rootMargin; } … … 105 106 106 107 private: 107 IntersectionObserver(Document&, Ref<IntersectionObserverCallback>&&, Element* root, LengthBox&& parsedRootMargin, Vector<double>&& thresholds);108 IntersectionObserver(Document&, Ref<IntersectionObserverCallback>&&, Node* root, LengthBox&& parsedRootMargin, Vector<double>&& thresholds); 108 109 109 110 bool removeTargetRegistration(Element&); … … 111 112 112 113 WeakPtr<Document> m_implicitRootDocument; 113 Element* m_root;114 Node* m_root; 114 115 LengthBox m_rootMargin; 115 116 Vector<double> m_thresholds; -
trunk/Source/WebCore/page/IntersectionObserver.idl
r237880 r257976 34 34 EnabledAtRuntime=IntersectionObserver 35 35 ] interface IntersectionObserver { 36 readonly attribute Element? root;36 readonly attribute Node? root; 37 37 readonly attribute DOMString rootMargin; 38 38 readonly attribute sequence<double> thresholds; … … 49 49 ] 50 50 dictionary IntersectionObserverInit { 51 Element? root = null;51 (Element or Document)? root = null; 52 52 DOMString rootMargin = "0px"; 53 53 (double or sequence<double>) threshold = 0.0;
Note: See TracChangeset
for help on using the changeset viewer.