OLD | NEW |
---|---|
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/ExceptionCode.h" | 10 #include "core/dom/ExceptionCode.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 break; | 46 break; |
47 case DimensionToken: | 47 case DimensionToken: |
48 switch (token.unitType()) { | 48 switch (token.unitType()) { |
49 case CSSPrimitiveValue::UnitType::Pixels: | 49 case CSSPrimitiveValue::UnitType::Pixels: |
50 rootMargin.append(Length(static_cast<int>(floor(token.numericVal ue())), Fixed)); | 50 rootMargin.append(Length(static_cast<int>(floor(token.numericVal ue())), Fixed)); |
51 break; | 51 break; |
52 case CSSPrimitiveValue::UnitType::Percentage: | 52 case CSSPrimitiveValue::UnitType::Percentage: |
53 rootMargin.append(Length(token.numericValue(), Percent)); | 53 rootMargin.append(Length(token.numericValue(), Percent)); |
54 break; | 54 break; |
55 default: | 55 default: |
56 exceptionState.throwTypeError("rootMargin must be specified in p ixels or percent."); | 56 exceptionState.throwDOMException(SyntaxError, "rootMargin must b e specified in pixels or percent."); |
57 } | 57 } |
58 break; | 58 break; |
59 default: | 59 default: |
60 exceptionState.throwTypeError("rootMargin must be specified in pixel s or percent."); | 60 exceptionState.throwDOMException(SyntaxError, "rootMargin must be sp ecified in pixels or percent."); |
61 } | 61 } |
62 } | 62 } |
63 } | 63 } |
64 | 64 |
65 static void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vecto r<float>& thresholds, ExceptionState& exceptionState) | 65 static void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vecto r<float>& thresholds, ExceptionState& exceptionState) |
66 { | 66 { |
67 if (thresholdParameter.isDouble()) { | 67 if (thresholdParameter.isDouble()) { |
68 thresholds.append(static_cast<float>(thresholdParameter.getAsDouble())); | 68 thresholds.append(static_cast<float>(thresholdParameter.getAsDouble())); |
69 } else { | 69 } else { |
70 for (auto thresholdValue : thresholdParameter.getAsDoubleArray()) | 70 for (auto thresholdValue : thresholdParameter.getAsDoubleArray()) |
71 thresholds.append(static_cast<float>(thresholdValue)); | 71 thresholds.append(static_cast<float>(thresholdValue)); |
72 } | 72 } |
73 | 73 |
74 for (auto thresholdValue : thresholds) { | 74 for (auto thresholdValue : thresholds) { |
75 if (thresholdValue < 0.0 || thresholdValue > 1.0) { | 75 if (thresholdValue < 0.0 || thresholdValue > 1.0) { |
76 exceptionState.throwTypeError("Threshold values must be between 0 an d 1"); | 76 exceptionState.throwRangeError("Threshold values must be between 0 a nd 1"); |
77 break; | 77 break; |
78 } | 78 } |
79 } | 79 } |
80 | 80 |
81 std::sort(thresholds.begin(), thresholds.end()); | 81 std::sort(thresholds.begin(), thresholds.end()); |
82 } | 82 } |
83 | 83 |
84 IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni t& observerInit, IntersectionObserverCallback& callback, ExceptionState& excepti onState) | 84 IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni t& observerInit, IntersectionObserverCallback& callback, ExceptionState& excepti onState) |
85 { | 85 { |
86 RefPtrWillBeRawPtr<Node> root = observerInit.root(); | 86 RefPtrWillBeRawPtr<Node> root = observerInit.root(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 { | 168 { |
169 Node* node = rootNode(); | 169 Node* node = rootNode(); |
170 if (node->isDocumentNode()) | 170 if (node->isDocumentNode()) |
171 return toDocument(node)->layoutView(); | 171 return toDocument(node)->layoutView(); |
172 return toElement(node)->layoutObject(); | 172 return toElement(node)->layoutObject(); |
173 } | 173 } |
174 | 174 |
175 void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta te) | 175 void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta te) |
176 { | 176 { |
177 if (!m_root) { | 177 if (!m_root) { |
178 exceptionState.throwDOMException(HierarchyRequestError, "Invalid observe r: root element or containing document has been deleted."); | 178 exceptionState.throwDOMException(InvalidStateError, "Invalid observer: r oot element or containing document has been deleted."); |
ojan
2016/02/27 01:45:45
I thought we decided this case wouldn't throw?
szager1
2016/02/29 22:35:53
Initially, I had thought this method would still t
| |
179 return; | 179 return; |
180 } | 180 } |
181 if (!target) { | 181 if (!target) { |
182 exceptionState.throwTypeError("Observation target must be an element."); | 182 exceptionState.throwTypeError("Observation target must be an element."); |
183 return; | 183 return; |
184 } | 184 } |
185 if (m_root.get() == target) { | 185 if (m_root.get() == target) { |
186 exceptionState.throwDOMException(HierarchyRequestError, "Cannot use the same element for root and target."); | 186 exceptionState.throwDOMException(HierarchyRequestError, "Cannot use the same element for root and target."); |
187 return; | 187 return; |
188 } | 188 } |
189 | 189 |
190 // TODO(szager): Add a pointer to the spec that describes this policy. | 190 // TODO(szager): Add a pointer to the spec that describes this policy. |
191 bool shouldReportRootBounds = target->document().frame()->securityContext()- >securityOrigin()->canAccess(rootNode()->document().frame()->securityContext()-> securityOrigin()); | 191 bool shouldReportRootBounds = target->document().frame()->securityContext()- >securityOrigin()->canAccess(rootNode()->document().frame()->securityContext()-> securityOrigin()); |
192 if (!shouldReportRootBounds && hasPercentMargin()) { | 192 if (!shouldReportRootBounds && hasPercentMargin()) { |
193 exceptionState.throwDOMException(HierarchyRequestError, "Cannot observe a cross-origin target because the observer has a root margin value specified as a percent."); | 193 exceptionState.throwDOMException(HierarchyRequestError, "Cannot observe a cross-origin target because the observer has a root margin value specified as a percent."); |
194 return; | 194 return; |
195 } | 195 } |
196 | 196 |
197 if (target->ensureIntersectionObserverData().getObservationFor(*this)) | 197 if (target->ensureIntersectionObserverData().getObservationFor(*this)) |
198 return; | 198 return; |
199 | 199 |
200 IntersectionObservation* observation = new IntersectionObservation(*this, *t arget, shouldReportRootBounds); | 200 IntersectionObservation* observation = new IntersectionObservation(*this, *t arget, shouldReportRootBounds); |
201 target->ensureIntersectionObserverData().addObservation(*observation); | 201 target->ensureIntersectionObserverData().addObservation(*observation); |
202 m_observations.add(observation); | 202 m_observations.add(observation); |
203 } | 203 } |
204 | 204 |
205 void IntersectionObserver::unobserve(Element* target, ExceptionState&) | 205 void IntersectionObserver::unobserve(Element* target) |
206 { | 206 { |
207 if (!target || !target->intersectionObserverData()) | 207 if (!target || !target->intersectionObserverData()) |
208 return; | 208 return; |
209 // TODO(szager): unobserve callback | 209 // TODO(szager): unobserve callback |
210 if (IntersectionObservation* observation = target->intersectionObserverData( )->getObservationFor(*this)) | 210 if (IntersectionObservation* observation = target->intersectionObserverData( )->getObservationFor(*this)) |
211 observation->disconnect(); | 211 observation->disconnect(); |
212 } | 212 } |
213 | 213 |
214 void IntersectionObserver::computeIntersectionObservations() | 214 void IntersectionObserver::computeIntersectionObservations() |
215 { | 215 { |
(...skipping 25 matching lines...) Expand all Loading... | |
241 HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords( ) | 241 HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords( ) |
242 { | 242 { |
243 HeapVector<Member<IntersectionObserverEntry>> entries; | 243 HeapVector<Member<IntersectionObserverEntry>> entries; |
244 entries.swap(m_entries); | 244 entries.swap(m_entries); |
245 return entries; | 245 return entries; |
246 } | 246 } |
247 | 247 |
248 Element* IntersectionObserver::root() const | 248 Element* IntersectionObserver::root() const |
249 { | 249 { |
250 Node* node = rootNode(); | 250 Node* node = rootNode(); |
251 if (node->isDocumentNode()) | 251 if (node && !node->isDocumentNode()) |
252 return nullptr; | 252 return toElement(node); |
253 return toElement(node); | 253 return nullptr; |
254 } | 254 } |
255 | 255 |
256 static void appendLength(StringBuilder& stringBuilder, const Length& length) | 256 static void appendLength(StringBuilder& stringBuilder, const Length& length) |
257 { | 257 { |
258 stringBuilder.appendNumber(length.intValue()); | 258 stringBuilder.appendNumber(length.intValue()); |
259 if (length.type() == Percent) | 259 if (length.type() == Percent) |
260 stringBuilder.append('%'); | 260 stringBuilder.append('%'); |
261 else | 261 else |
262 stringBuilder.append("px", 2); | 262 stringBuilder.append("px", 2); |
263 } | 263 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 { | 342 { |
343 #if ENABLE(OILPAN) | 343 #if ENABLE(OILPAN) |
344 visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObs erver::clearWeakMembers>(this); | 344 visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObs erver::clearWeakMembers>(this); |
345 #endif | 345 #endif |
346 visitor->trace(m_callback); | 346 visitor->trace(m_callback); |
347 visitor->trace(m_observations); | 347 visitor->trace(m_observations); |
348 visitor->trace(m_entries); | 348 visitor->trace(m_entries); |
349 } | 349 } |
350 | 350 |
351 } // namespace blink | 351 } // namespace blink |
OLD | NEW |