Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(995)

Side by Side Diff: third_party/WebKit/Source/core/dom/IntersectionObserver.cpp

Issue 1548523002: Use Document, rather than document element, for implicit root. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@intersection-observer
Patch Set: Nits, comments, rebaseline Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/dom/IntersectionObserver.h" 5 #include "core/dom/IntersectionObserver.h"
6 6
7 #include "bindings/core/v8/ExceptionState.h" 7 #include "bindings/core/v8/ExceptionState.h"
8 #include "core/css/parser/CSSParserTokenRange.h" 8 #include "core/css/parser/CSSParserTokenRange.h"
9 #include "core/css/parser/CSSTokenizer.h" 9 #include "core/css/parser/CSSTokenizer.h"
10 #include "core/dom/ElementIntersectionObserverData.h"
11 #include "core/dom/ExceptionCode.h" 10 #include "core/dom/ExceptionCode.h"
12 #include "core/dom/ExecutionContext.h" 11 #include "core/dom/ExecutionContext.h"
13 #include "core/dom/IntersectionObserverCallback.h" 12 #include "core/dom/IntersectionObserverCallback.h"
14 #include "core/dom/IntersectionObserverController.h" 13 #include "core/dom/IntersectionObserverController.h"
15 #include "core/dom/IntersectionObserverEntry.h" 14 #include "core/dom/IntersectionObserverEntry.h"
16 #include "core/dom/IntersectionObserverInit.h" 15 #include "core/dom/IntersectionObserverInit.h"
16 #include "core/dom/NodeIntersectionObserverData.h"
17 #include "core/html/HTMLFrameOwnerElement.h" 17 #include "core/html/HTMLFrameOwnerElement.h"
18 #include "core/layout/LayoutView.h" 18 #include "core/layout/LayoutView.h"
19 #include "platform/Timer.h" 19 #include "platform/Timer.h"
20 #include "wtf/MainThread.h" 20 #include "wtf/MainThread.h"
21 #include <algorithm> 21 #include <algorithm>
22 22
23 namespace blink { 23 namespace blink {
24 24
25 static void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMarg in, ExceptionState& exceptionState) 25 static void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMarg in, ExceptionState& exceptionState)
26 { 26 {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 exceptionState.throwTypeError("Threshold values must be between 0 an d 1"); 74 exceptionState.throwTypeError("Threshold values must be between 0 an d 1");
75 break; 75 break;
76 } 76 }
77 } 77 }
78 78
79 std::sort(thresholds.begin(), thresholds.end()); 79 std::sort(thresholds.begin(), thresholds.end());
80 } 80 }
81 81
82 IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni t& observerInit, IntersectionObserverCallback& callback, ExceptionState& excepti onState) 82 IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni t& observerInit, IntersectionObserverCallback& callback, ExceptionState& excepti onState)
83 { 83 {
84 RefPtrWillBeRawPtr<Element> root = observerInit.root(); 84 RefPtrWillBeRawPtr<Node> root = observerInit.root();
85 if (!root) { 85 if (!root) {
86 // TODO(szager): Use Document instead of document element for implicit r oot. (crbug.com/570538) 86 // TODO(szager): Use Document instead of document element for implicit r oot. (crbug.com/570538)
87 ExecutionContext* context = callback.executionContext(); 87 ExecutionContext* context = callback.executionContext();
88 ASSERT(context->isDocument()); 88 ASSERT(context->isDocument());
89 Frame* mainFrame = toDocument(context)->frame()->tree().top(); 89 Frame* mainFrame = toDocument(context)->frame()->tree().top();
90 if (mainFrame && mainFrame->isLocalFrame()) 90 if (mainFrame && mainFrame->isLocalFrame())
91 root = toLocalFrame(mainFrame)->document()->documentElement(); 91 root = toLocalFrame(mainFrame)->document();
92 } 92 }
93 if (!root) { 93 if (!root) {
94 exceptionState.throwDOMException(HierarchyRequestError, "Unable to get r oot element in main frame to track."); 94 exceptionState.throwDOMException(HierarchyRequestError, "Unable to get r oot node in main frame to track.");
95 return nullptr; 95 return nullptr;
96 } 96 }
97 97
98 Vector<Length> rootMargin; 98 Vector<Length> rootMargin;
99 if (observerInit.hasRootMargin()) 99 if (observerInit.hasRootMargin())
100 parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState); 100 parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState);
101 if (exceptionState.hadException()) 101 if (exceptionState.hadException())
102 return nullptr; 102 return nullptr;
103 103
104 Vector<float> thresholds; 104 Vector<float> thresholds;
105 if (observerInit.hasThreshold()) 105 if (observerInit.hasThreshold())
106 parseThresholds(observerInit.threshold(), thresholds, exceptionState); 106 parseThresholds(observerInit.threshold(), thresholds, exceptionState);
107 else 107 else
108 thresholds.append(0); 108 thresholds.append(0);
109 if (exceptionState.hadException()) 109 if (exceptionState.hadException())
110 return nullptr; 110 return nullptr;
111 111
112 return new IntersectionObserver(callback, *root, rootMargin, thresholds); 112 return new IntersectionObserver(callback, *root, rootMargin, thresholds);
113 } 113 }
114 114
115 IntersectionObserver::IntersectionObserver(IntersectionObserverCallback& callbac k, Element& root, const Vector<Length>& rootMargin, const Vector<float>& thresho lds) 115 IntersectionObserver::IntersectionObserver(IntersectionObserverCallback& callbac k, Node& root, const Vector<Length>& rootMargin, const Vector<float>& thresholds )
116 : m_callback(&callback) 116 : m_callback(&callback)
117 , m_root(root.ensureIntersectionObserverData().createWeakPtr(&root))
118 , m_thresholds(thresholds) 117 , m_thresholds(thresholds)
119 , m_topMargin(Fixed) 118 , m_topMargin(Fixed)
120 , m_rightMargin(Fixed) 119 , m_rightMargin(Fixed)
121 , m_bottomMargin(Fixed) 120 , m_bottomMargin(Fixed)
122 , m_leftMargin(Fixed) 121 , m_leftMargin(Fixed)
123 { 122 {
123 if (root.isDocumentNode())
124 m_root = toDocument(root).ensureIntersectionObserverData().createWeakPtr (&root);
125 else
126 m_root = toElement(root).ensureIntersectionObserverData().createWeakPtr( &root);
124 switch (rootMargin.size()) { 127 switch (rootMargin.size()) {
125 case 0: 128 case 0:
126 break; 129 break;
127 case 1: 130 case 1:
128 m_topMargin = m_rightMargin = m_bottomMargin = m_leftMargin = rootMargin [0]; 131 m_topMargin = m_rightMargin = m_bottomMargin = m_leftMargin = rootMargin [0];
129 break; 132 break;
130 case 2: 133 case 2:
131 m_topMargin = m_bottomMargin = rootMargin[0]; 134 m_topMargin = m_bottomMargin = rootMargin[0];
132 m_rightMargin = m_leftMargin = rootMargin[1]; 135 m_rightMargin = m_leftMargin = rootMargin[1];
133 break; 136 break;
134 case 3: 137 case 3:
135 m_topMargin = rootMargin[0]; 138 m_topMargin = rootMargin[0];
136 m_rightMargin = m_leftMargin = rootMargin[1]; 139 m_rightMargin = m_leftMargin = rootMargin[1];
137 m_bottomMargin = rootMargin[2]; 140 m_bottomMargin = rootMargin[2];
138 break; 141 break;
139 case 4: 142 case 4:
140 m_topMargin = rootMargin[0]; 143 m_topMargin = rootMargin[0];
141 m_rightMargin = rootMargin[1]; 144 m_rightMargin = rootMargin[1];
142 m_bottomMargin = rootMargin[2]; 145 m_bottomMargin = rootMargin[2];
143 m_leftMargin = rootMargin[3]; 146 m_leftMargin = rootMargin[3];
144 break; 147 break;
145 default: 148 default:
146 ASSERT_NOT_REACHED(); 149 ASSERT_NOT_REACHED();
147 break; 150 break;
148 } 151 }
149 root.document().ensureIntersectionObserverController().addTrackedObserver(*t his); 152 root.document().ensureIntersectionObserverController().addTrackedObserver(*t his);
150 } 153 }
151 154
152 LayoutObject* IntersectionObserver::rootLayoutObject() 155 LayoutObject* IntersectionObserver::rootLayoutObject() const
153 { 156 {
154 Element* rootElement = root(); 157 Node* rootNode = root();
155 if (rootElement == rootElement->document().documentElement()) 158 if (rootNode->isDocumentNode())
156 return rootElement->document().layoutView(); 159 return toDocument(rootNode)->layoutView();
157 return rootElement->layoutObject(); 160 return toElement(rootNode)->layoutObject();
158 } 161 }
159 162
160 bool IntersectionObserver::isDescendantOfRoot(const Element* target) const 163 bool IntersectionObserver::isDescendantOfRoot(const Element* target) const
161 { 164 {
162 // Is m_root an ancestor, through the DOM and frame trees, of target? 165 // Is m_root an ancestor, through the DOM and frame trees, of target?
163 Element* rootElement = m_root.get(); 166 Node* rootNode = root();
164 if (!rootElement || !target || target == rootElement) 167 if (!rootNode || !target || target == rootNode)
165 return false; 168 return false;
166 if (!target->inDocument() || !rootElement->inDocument()) 169 if (!target->inDocument() || !rootNode->inDocument())
167 return false; 170 return false;
168 171
169 Document* rootDocument = &rootElement->document(); 172 Document* rootDocument = &rootNode->document();
170 Document* targetDocument = &target->document(); 173 Document* targetDocument = &target->document();
171 while (targetDocument != rootDocument) { 174 while (targetDocument != rootDocument) {
172 target = targetDocument->ownerElement(); 175 target = targetDocument->ownerElement();
173 if (!target) 176 if (!target)
174 return false; 177 return false;
175 targetDocument = &target->document(); 178 targetDocument = &target->document();
176 } 179 }
177 return target->isDescendantOf(rootElement); 180 if (rootNode->isDocumentNode()) {
181 ASSERT(targetDocument == rootNode);
182 return true;
183 }
184 return target->isDescendantOf(rootNode);
178 } 185 }
179 186
180 void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta te) 187 void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta te)
181 { 188 {
182 checkRootAndDetachIfNeeded(); 189 checkRootAndDetachIfNeeded();
183 if (!m_root) { 190 if (!m_root) {
184 exceptionState.throwDOMException(HierarchyRequestError, "Invalid observe r: root element or containing document has been deleted."); 191 exceptionState.throwDOMException(HierarchyRequestError, "Invalid observe r: root element or containing document has been deleted.");
185 return; 192 return;
186 } 193 }
187 if (!target) { 194 if (!target) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 343
337 DEFINE_TRACE(IntersectionObserver) 344 DEFINE_TRACE(IntersectionObserver)
338 { 345 {
339 visitor->trace(m_callback); 346 visitor->trace(m_callback);
340 visitor->trace(m_root); 347 visitor->trace(m_root);
341 visitor->trace(m_observations); 348 visitor->trace(m_observations);
342 visitor->trace(m_entries); 349 visitor->trace(m_entries);
343 } 350 }
344 351
345 } // namespace blink 352 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698