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/custom/CustomElementsRegistry.h" | 5 #include "core/dom/custom/CustomElementsRegistry.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
8 #include "bindings/core/v8/ScriptValue.h" | 8 #include "bindings/core/v8/ScriptValue.h" |
9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
10 #include "core/dom/Element.h" | 10 #include "core/dom/Element.h" |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 | 261 |
262 DEFINE_INLINE_VIRTUAL_TRACE() | 262 DEFINE_INLINE_VIRTUAL_TRACE() |
263 { | 263 { |
264 TestCustomElementDefinition::trace(visitor); | 264 TestCustomElementDefinition::trace(visitor); |
265 visitor->trace(m_element); | 265 visitor->trace(m_element); |
266 } | 266 } |
267 | 267 |
268 // TODO(dominicc): Make this class collect a vector of what's | 268 // TODO(dominicc): Make this class collect a vector of what's |
269 // upgraded; it will be useful in more tests. | 269 // upgraded; it will be useful in more tests. |
270 Member<Element> m_element; | 270 Member<Element> m_element; |
271 uint32_t m_invocationCount; | 271 enum MethodType { |
| 272 Constructor, |
| 273 ConnectedCallback, |
| 274 DisconnectedCallback, |
| 275 AttributeChangedCallback, |
| 276 }; |
| 277 Vector<MethodType> m_logs; |
| 278 |
| 279 struct AttributeChanged { |
| 280 QualifiedName name; |
| 281 AtomicString oldValue; |
| 282 AtomicString newValue; |
| 283 }; |
| 284 Vector<AttributeChanged> m_attributeChanged; |
| 285 |
| 286 void clear() |
| 287 { |
| 288 m_logs.clear(); |
| 289 m_attributeChanged.clear(); |
| 290 } |
272 | 291 |
273 bool runConstructor(Element* element) override | 292 bool runConstructor(Element* element) override |
274 { | 293 { |
275 m_invocationCount++; | 294 m_logs.append(Constructor); |
276 m_element = element; | 295 m_element = element; |
277 return TestCustomElementDefinition::runConstructor(element); | 296 return TestCustomElementDefinition::runConstructor(element); |
278 } | 297 } |
| 298 |
| 299 bool hasConnectedCallback() const override { return true; } |
| 300 bool hasDisconnectedCallback() const override { return true; } |
| 301 bool hasAttributeChangedCallback(const QualifiedName&) const override { retu
rn true; } |
| 302 |
| 303 void runConnectedCallback(Element* element) override |
| 304 { |
| 305 m_logs.append(ConnectedCallback); |
| 306 EXPECT_EQ(element, m_element); |
| 307 } |
| 308 |
| 309 void runDisconnectedCallback(Element* element) override |
| 310 { |
| 311 m_logs.append(DisconnectedCallback); |
| 312 EXPECT_EQ(element, m_element); |
| 313 } |
| 314 |
| 315 void runAttributeChangedCallback(Element* element, const QualifiedName& name
, const AtomicString& oldValue, const AtomicString& newValue) override |
| 316 { |
| 317 m_logs.append(AttributeChangedCallback); |
| 318 EXPECT_EQ(element, m_element); |
| 319 m_attributeChanged.append(AttributeChanged { name, oldValue, newValue })
; |
| 320 } |
279 }; | 321 }; |
280 | 322 |
281 class LogUpgradeBuilder final : public CustomElementDefinitionBuilder { | 323 class LogUpgradeBuilder final : public CustomElementDefinitionBuilder { |
282 STACK_ALLOCATED(); | 324 STACK_ALLOCATED(); |
283 WTF_MAKE_NONCOPYABLE(LogUpgradeBuilder); | 325 WTF_MAKE_NONCOPYABLE(LogUpgradeBuilder); |
284 public: | 326 public: |
285 LogUpgradeBuilder() { } | 327 LogUpgradeBuilder() { } |
286 | 328 |
287 bool checkConstructorIntrinsics() override { return true; } | 329 bool checkConstructorIntrinsics() override { return true; } |
288 bool checkConstructorNotRegistered() override { return true; } | 330 bool checkConstructorNotRegistered() override { return true; } |
289 bool checkPrototype() override { return true; } | 331 bool checkPrototype() override { return true; } |
290 bool rememberOriginalProperties() override { return true; } | 332 bool rememberOriginalProperties() override { return true; } |
291 CustomElementDefinition* build( | 333 CustomElementDefinition* build( |
292 const CustomElementDescriptor& descriptor) { | 334 const CustomElementDescriptor& descriptor) { |
293 return new LogUpgradeDefinition(descriptor); | 335 return new LogUpgradeDefinition(descriptor); |
294 } | 336 } |
295 }; | 337 }; |
296 | 338 |
297 TEST_F(CustomElementsRegistryFrameTest, define_upgradesInDocumentElements) | 339 TEST_F(CustomElementsRegistryFrameTest, define_upgradesInDocumentElements) |
298 { | 340 { |
299 ScriptForbiddenScope doNotRelyOnScript; | 341 ScriptForbiddenScope doNotRelyOnScript; |
300 | 342 |
301 Element* element = CreateElement("a-a").inDocument(&document()); | 343 Element* element = CreateElement("a-a").inDocument(&document()); |
| 344 element->setAttribute(QualifiedName(nullAtom, "attr1", HTMLNames::xhtmlNames
paceURI), "v1"); |
| 345 element->setBooleanAttribute(HTMLNames::contenteditableAttr, true); |
302 document().documentElement()->appendChild(element); | 346 document().documentElement()->appendChild(element); |
303 | 347 |
304 LogUpgradeBuilder builder; | 348 LogUpgradeBuilder builder; |
305 NonThrowableExceptionState shouldNotThrow; | 349 NonThrowableExceptionState shouldNotThrow; |
306 { | 350 { |
307 CEReactionsScope reactions; | 351 CEReactionsScope reactions; |
308 registry().define( | 352 registry().define( |
309 "a-a", | 353 "a-a", |
310 builder, | 354 builder, |
311 ElementRegistrationOptions(), | 355 ElementRegistrationOptions(), |
312 shouldNotThrow); | 356 shouldNotThrow); |
313 } | 357 } |
314 LogUpgradeDefinition* definition = | 358 LogUpgradeDefinition* definition = |
315 static_cast<LogUpgradeDefinition*>(registry().definitionForName("a-a")); | 359 static_cast<LogUpgradeDefinition*>(registry().definitionForName("a-a")); |
316 EXPECT_EQ(1u, definition->m_invocationCount) | 360 EXPECT_EQ(LogUpgradeDefinition::Constructor, definition->m_logs[0]) |
317 << "defining the element should have 'upgraded' the existing element"; | 361 << "defining the element should have 'upgraded' the existing element"; |
318 EXPECT_EQ(element, definition->m_element) | 362 EXPECT_EQ(element, definition->m_element) |
319 << "the existing a-a element should have been upgraded"; | 363 << "the existing a-a element should have been upgraded"; |
| 364 |
| 365 EXPECT_EQ(LogUpgradeDefinition::AttributeChangedCallback, definition->m_logs
[1]) |
| 366 << "Upgrade should invoke attributeChangedCallback for all attributes"; |
| 367 EXPECT_EQ("attr1", definition->m_attributeChanged[0].name); |
| 368 EXPECT_EQ(nullAtom, definition->m_attributeChanged[0].oldValue); |
| 369 EXPECT_EQ("v1", definition->m_attributeChanged[0].newValue); |
| 370 |
| 371 EXPECT_EQ(LogUpgradeDefinition::AttributeChangedCallback, definition->m_logs
[2]) |
| 372 << "Upgrade should invoke attributeChangedCallback for all attributes"; |
| 373 EXPECT_EQ("contenteditable", definition->m_attributeChanged[1].name); |
| 374 EXPECT_EQ(nullAtom, definition->m_attributeChanged[1].oldValue); |
| 375 EXPECT_EQ(emptyAtom, definition->m_attributeChanged[1].newValue); |
| 376 EXPECT_EQ(2u, definition->m_attributeChanged.size()) |
| 377 << "Upgrade should invoke attributeChangedCallback for all attributes"; |
| 378 |
| 379 EXPECT_EQ(LogUpgradeDefinition::ConnectedCallback, definition->m_logs[3]) |
| 380 << "upgrade should invoke connectedCallback"; |
| 381 |
| 382 EXPECT_EQ(4u, definition->m_logs.size()) |
| 383 << "upgrade should not invoke other callbacks"; |
| 384 } |
| 385 |
| 386 TEST_F(CustomElementsRegistryFrameTest, attributeChangedCallback) |
| 387 { |
| 388 ScriptForbiddenScope doNotRelyOnScript; |
| 389 |
| 390 Element* element = CreateElement("a-a").inDocument(&document()); |
| 391 document().documentElement()->appendChild(element); |
| 392 |
| 393 LogUpgradeBuilder builder; |
| 394 NonThrowableExceptionState shouldNotThrow; |
| 395 { |
| 396 CEReactionsScope reactions; |
| 397 registry().define( |
| 398 "a-a", |
| 399 builder, |
| 400 ElementRegistrationOptions(), |
| 401 shouldNotThrow); |
| 402 } |
| 403 LogUpgradeDefinition* definition = |
| 404 static_cast<LogUpgradeDefinition*>(registry().definitionForName("a-a")); |
| 405 |
| 406 definition->clear(); |
| 407 { |
| 408 CEReactionsScope reactions; |
| 409 element->setAttribute(QualifiedName(nullAtom, "attr2", HTMLNames::xhtmlN
amespaceURI), "v2"); |
| 410 } |
| 411 EXPECT_EQ(LogUpgradeDefinition::AttributeChangedCallback, definition->m_logs
[0]) |
| 412 << "Adding an attribute should invoke attributeChangedCallback"; |
| 413 EXPECT_EQ(1u, definition->m_attributeChanged.size()) |
| 414 << "Adding an attribute should invoke attributeChangedCallback"; |
| 415 EXPECT_EQ("attr2", definition->m_attributeChanged[0].name); |
| 416 EXPECT_EQ(nullAtom, definition->m_attributeChanged[0].oldValue); |
| 417 EXPECT_EQ("v2", definition->m_attributeChanged[0].newValue); |
| 418 |
| 419 EXPECT_EQ(1u, definition->m_logs.size()) |
| 420 << "upgrade should not invoke other callbacks"; |
| 421 } |
| 422 |
| 423 TEST_F(CustomElementsRegistryFrameTest, disconnectedCallback) |
| 424 { |
| 425 ScriptForbiddenScope doNotRelyOnScript; |
| 426 |
| 427 Element* element = CreateElement("a-a").inDocument(&document()); |
| 428 document().documentElement()->appendChild(element); |
| 429 |
| 430 LogUpgradeBuilder builder; |
| 431 NonThrowableExceptionState shouldNotThrow; |
| 432 { |
| 433 CEReactionsScope reactions; |
| 434 registry().define( |
| 435 "a-a", |
| 436 builder, |
| 437 ElementRegistrationOptions(), |
| 438 shouldNotThrow); |
| 439 } |
| 440 LogUpgradeDefinition* definition = |
| 441 static_cast<LogUpgradeDefinition*>(registry().definitionForName("a-a")); |
| 442 |
| 443 definition->clear(); |
| 444 { |
| 445 CEReactionsScope reactions; |
| 446 element->remove(shouldNotThrow); |
| 447 } |
| 448 EXPECT_EQ(LogUpgradeDefinition::DisconnectedCallback, definition->m_logs[0]) |
| 449 << "remove() should invoke disconnectedCallback"; |
| 450 |
| 451 EXPECT_EQ(1u, definition->m_logs.size()) |
| 452 << "remove() should not invoke other callbacks"; |
320 } | 453 } |
321 | 454 |
322 // TODO(dominicc): Add tests which adjust the "is" attribute when type | 455 // TODO(dominicc): Add tests which adjust the "is" attribute when type |
323 // extensions are implemented. | 456 // extensions are implemented. |
324 | 457 |
325 } // namespace blink | 458 } // namespace blink |
OLD | NEW |