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

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

Issue 2051253002: Start autoplay muted videos with autoplay attribute when they are visible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: reduce Created 4 years, 6 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/Element.h" 10 #include "core/dom/Element.h"
(...skipping 10 matching lines...) Expand all
21 #include "core/html/HTMLFrameOwnerElement.h" 21 #include "core/html/HTMLFrameOwnerElement.h"
22 #include "core/inspector/ConsoleMessage.h" 22 #include "core/inspector/ConsoleMessage.h"
23 #include "core/layout/LayoutView.h" 23 #include "core/layout/LayoutView.h"
24 #include "core/timing/DOMWindowPerformance.h" 24 #include "core/timing/DOMWindowPerformance.h"
25 #include "core/timing/Performance.h" 25 #include "core/timing/Performance.h"
26 #include "platform/Timer.h" 26 #include "platform/Timer.h"
27 #include <algorithm> 27 #include <algorithm>
28 28
29 namespace blink { 29 namespace blink {
30 30
31 static void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMarg in, ExceptionState& exceptionState) 31 namespace {
32
33 // Internal implementation of IntersectionObserverCallback when using
34 // IntersectionObserver with an EventCallback.
35 class IntersectionObserverCallbackImpl final : public IntersectionObserverCallba ck {
36 WTF_MAKE_NONCOPYABLE(IntersectionObserverCallbackImpl);
37 public:
38 IntersectionObserverCallbackImpl(ExecutionContext* context, std::unique_ptr< IntersectionObserver::EventCallback> callback)
39 : m_context(context)
40 , m_callback(std::move(callback))
41 {}
42
43 void handleEvent(const HeapVector<Member<IntersectionObserverEntry>>& entrie s, IntersectionObserver&) override
44 {
45 (*m_callback.get())(entries);
46 }
47
48 ExecutionContext* getExecutionContext() const override
49 {
50 return m_context;
51 }
52
53 DEFINE_INLINE_TRACE()
54 {
55 IntersectionObserverCallback::trace(visitor);
56 visitor->trace(m_context);
57 }
58
59 private:
60 WeakMember<ExecutionContext> m_context;
61 std::unique_ptr<IntersectionObserver::EventCallback> m_callback;
62 };
63
64 void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMargin, Exc eptionState& exceptionState)
32 { 65 {
33 // TODO(szager): Make sure this exact syntax and behavior is spec-ed somewhe re. 66 // TODO(szager): Make sure this exact syntax and behavior is spec-ed somewhe re.
34 67
35 // The root margin argument accepts syntax similar to that for CSS margin: 68 // The root margin argument accepts syntax similar to that for CSS margin:
36 // 69 //
37 // "1px" = top/right/bottom/left 70 // "1px" = top/right/bottom/left
38 // "1px 2px" = top/bottom left/right 71 // "1px 2px" = top/bottom left/right
39 // "1px 2px 3px" = top left/right bottom 72 // "1px 2px 3px" = top left/right bottom
40 // "1px 2px 3px 4px" = top left right bottom 73 // "1px 2px 3px 4px" = top left right bottom
41 // 74 //
(...skipping 17 matching lines...) Expand all
59 default: 92 default:
60 exceptionState.throwDOMException(SyntaxError, "rootMargin must b e specified in pixels or percent."); 93 exceptionState.throwDOMException(SyntaxError, "rootMargin must b e specified in pixels or percent.");
61 } 94 }
62 break; 95 break;
63 default: 96 default:
64 exceptionState.throwDOMException(SyntaxError, "rootMargin must be sp ecified in pixels or percent."); 97 exceptionState.throwDOMException(SyntaxError, "rootMargin must be sp ecified in pixels or percent.");
65 } 98 }
66 } 99 }
67 } 100 }
68 101
69 static void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vecto r<float>& thresholds, ExceptionState& exceptionState) 102 void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vector<float >& thresholds, ExceptionState& exceptionState)
70 { 103 {
71 if (thresholdParameter.isDouble()) { 104 if (thresholdParameter.isDouble()) {
72 thresholds.append(static_cast<float>(thresholdParameter.getAsDouble())); 105 thresholds.append(static_cast<float>(thresholdParameter.getAsDouble()));
73 } else { 106 } else {
74 for (auto thresholdValue : thresholdParameter.getAsDoubleArray()) 107 for (auto thresholdValue : thresholdParameter.getAsDoubleArray())
75 thresholds.append(static_cast<float>(thresholdValue)); 108 thresholds.append(static_cast<float>(thresholdValue));
76 } 109 }
77 110
78 for (auto thresholdValue : thresholds) { 111 for (auto thresholdValue : thresholds) {
79 if (thresholdValue < 0.0 || thresholdValue > 1.0) { 112 if (thresholdValue < 0.0 || thresholdValue > 1.0) {
80 exceptionState.throwRangeError("Threshold values must be between 0 a nd 1"); 113 exceptionState.throwRangeError("Threshold values must be between 0 a nd 1");
81 break; 114 break;
82 } 115 }
83 } 116 }
84 117
85 std::sort(thresholds.begin(), thresholds.end()); 118 std::sort(thresholds.begin(), thresholds.end());
86 } 119 }
87 120
121 // Returns the root Node of a given Document to use as the IntersectionObserver
122 // root when no root is given.
123 // TODO(szager): it doesn't support RemoteFrames, see https://crbug.com/615156
124 Node* getRootNode(Document* document)
125 {
126 Frame* mainFrame = document->frame()->tree().top();
127 if (mainFrame && mainFrame->isLocalFrame())
128 return toLocalFrame(mainFrame)->document();
129 return nullptr;
130 }
131
132 } // anonymous namespace
133
88 IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni t& observerInit, IntersectionObserverCallback& callback, ExceptionState& excepti onState) 134 IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni t& observerInit, IntersectionObserverCallback& callback, ExceptionState& excepti onState)
89 { 135 {
90 Node* root = observerInit.root(); 136 Node* root = observerInit.root();
91 if (!root) { 137 if (!root) {
92 // TODO(szager): Use Document instead of document element for implicit r oot. (crbug.com/570538)
93 ExecutionContext* context = callback.getExecutionContext(); 138 ExecutionContext* context = callback.getExecutionContext();
94 DCHECK(context->isDocument()); 139 DCHECK(context->isDocument());
95 Frame* mainFrame = toDocument(context)->frame()->tree().top(); 140 root = getRootNode(toDocument(context));
96 if (mainFrame && mainFrame->isLocalFrame())
97 root = toLocalFrame(mainFrame)->document();
98 } 141 }
99 if (!root) { 142 if (!root) {
100 exceptionState.throwDOMException(HierarchyRequestError, "Unable to get r oot node in main frame to track."); 143 exceptionState.throwDOMException(HierarchyRequestError, "Unable to get r oot node in main frame to track.");
101 return nullptr; 144 return nullptr;
102 } 145 }
103 146
104 Vector<Length> rootMargin; 147 Vector<Length> rootMargin;
105 if (observerInit.hasRootMargin()) 148 if (observerInit.hasRootMargin())
106 parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState); 149 parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState);
107 if (exceptionState.hadException()) 150 if (exceptionState.hadException())
108 return nullptr; 151 return nullptr;
109 152
110 Vector<float> thresholds; 153 Vector<float> thresholds;
111 if (observerInit.hasThreshold()) 154 if (observerInit.hasThreshold())
112 parseThresholds(observerInit.threshold(), thresholds, exceptionState); 155 parseThresholds(observerInit.threshold(), thresholds, exceptionState);
113 else 156 else
114 thresholds.append(0); 157 thresholds.append(0);
115 if (exceptionState.hadException()) 158 if (exceptionState.hadException())
116 return nullptr; 159 return nullptr;
117 160
118 return new IntersectionObserver(callback, *root, rootMargin, thresholds); 161 return new IntersectionObserver(callback, *root, rootMargin, thresholds);
119 } 162 }
120 163
164 IntersectionObserver* IntersectionObserver::create(const Vector<Length>& rootMar gin, const Vector<float>& thresholds, Document* document, std::unique_ptr<EventC allback> callback)
165 {
166 Node* root = getRootNode(document);
167 if (!root)
168 return nullptr;
169
170 IntersectionObserverCallbackImpl* intersectionObserverCallback = new Interse ctionObserverCallbackImpl(document, std::move(callback));
171 return new IntersectionObserver(*intersectionObserverCallback, *root, rootMa rgin, thresholds);
172 }
173
121 IntersectionObserver::IntersectionObserver(IntersectionObserverCallback& callbac k, Node& root, const Vector<Length>& rootMargin, const Vector<float>& thresholds ) 174 IntersectionObserver::IntersectionObserver(IntersectionObserverCallback& callbac k, Node& root, const Vector<Length>& rootMargin, const Vector<float>& thresholds )
122 : m_callback(&callback) 175 : m_callback(&callback)
123 , m_root(&root) 176 , m_root(&root)
124 , m_thresholds(thresholds) 177 , m_thresholds(thresholds)
125 , m_topMargin(Fixed) 178 , m_topMargin(Fixed)
126 , m_rightMargin(Fixed) 179 , m_rightMargin(Fixed)
127 , m_bottomMargin(Fixed) 180 , m_bottomMargin(Fixed)
128 , m_leftMargin(Fixed) 181 , m_leftMargin(Fixed)
129 { 182 {
130 switch (rootMargin.size()) { 183 switch (rootMargin.size()) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 if (!m_root) { 230 if (!m_root) {
178 exceptionState.throwDOMException(InvalidStateError, "observe() called on an IntersectionObserver with an invalid root."); 231 exceptionState.throwDOMException(InvalidStateError, "observe() called on an IntersectionObserver with an invalid root.");
179 return; 232 return;
180 } 233 }
181 234
182 if (!target || m_root.get() == target) 235 if (!target || m_root.get() == target)
183 return; 236 return;
184 237
185 if (target->ensureIntersectionObserverData().getObservationFor(*this)) 238 if (target->ensureIntersectionObserverData().getObservationFor(*this))
186 return; 239 return;
187
188 bool shouldReportRootBounds = false; 240 bool shouldReportRootBounds = false;
189 bool isDOMDescendant = false; 241 bool isDOMDescendant = false;
190 LocalFrame* targetFrame = target->document().frame(); 242 LocalFrame* targetFrame = target->document().frame();
191 LocalFrame* rootFrame = m_root->document().frame(); 243 LocalFrame* rootFrame = m_root->document().frame();
192 244
193 if (target->document() == rootNode()->document()) { 245 if (target->document() == rootNode()->document()) {
194 shouldReportRootBounds = true; 246 shouldReportRootBounds = true;
195 isDOMDescendant = target->isDescendantOf(rootNode()); 247 isDOMDescendant = target->isDescendantOf(rootNode());
196 } else if (targetFrame && rootFrame) { 248 } else if (targetFrame && rootFrame) {
197 shouldReportRootBounds = targetFrame->securityContext()->getSecurityOrig in()->canAccess(rootFrame->securityContext()->getSecurityOrigin()); 249 shouldReportRootBounds = targetFrame->securityContext()->getSecurityOrig in()->canAccess(rootFrame->securityContext()->getSecurityOrigin());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 unsigned IntersectionObserver::firstThresholdGreaterThan(float ratio) const 385 unsigned IntersectionObserver::firstThresholdGreaterThan(float ratio) const
334 { 386 {
335 unsigned result = 0; 387 unsigned result = 0;
336 while (result < m_thresholds.size() && m_thresholds[result] <= ratio) 388 while (result < m_thresholds.size() && m_thresholds[result] <= ratio)
337 ++result; 389 ++result;
338 return result; 390 return result;
339 } 391 }
340 392
341 void IntersectionObserver::deliver() 393 void IntersectionObserver::deliver()
342 { 394 {
343
344 if (m_entries.isEmpty()) 395 if (m_entries.isEmpty())
345 return; 396 return;
346 397
347 HeapVector<Member<IntersectionObserverEntry>> entries; 398 HeapVector<Member<IntersectionObserverEntry>> entries;
348 entries.swap(m_entries); 399 entries.swap(m_entries);
349 m_callback->handleEvent(entries, *this); 400 m_callback->handleEvent(entries, *this);
350 } 401 }
351 402
352 DEFINE_TRACE(IntersectionObserver) 403 DEFINE_TRACE(IntersectionObserver)
353 { 404 {
354 visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObs erver::clearWeakMembers>(this); 405 visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObs erver::clearWeakMembers>(this);
355 visitor->trace(m_callback); 406 visitor->trace(m_callback);
356 visitor->trace(m_observations); 407 visitor->trace(m_observations);
357 visitor->trace(m_entries); 408 visitor->trace(m_entries);
358 } 409 }
359 410
360 } // namespace blink 411 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/IntersectionObserver.h ('k') | third_party/WebKit/Source/core/html/HTMLMediaElement.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698