| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. |
| 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| 11 * License as published by the Free Software Foundation; either | 11 * License as published by the Free Software Foundation; either |
| 12 * version 2 of the License, or (at your option) any later version. | 12 * version 2 of the License, or (at your option) any later version. |
| 13 * | 13 * |
| 14 * This library is distributed in the hope that it will be useful, | 14 * This library is distributed in the hope that it will be useful, |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 * Library General Public License for more details. | 17 * Library General Public License for more details. |
| 18 * | 18 * |
| 19 * You should have received a copy of the GNU Library General Public License | 19 * You should have received a copy of the GNU Library General Public License |
| 20 * along with this library; see the file COPYING.LIB. If not, write to | 20 * along with this library; see the file COPYING.LIB. If not, write to |
| 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 22 * Boston, MA 02110-1301, USA. | 22 * Boston, MA 02110-1301, USA. |
| 23 */ | 23 */ |
| 24 | 24 |
| 25 #include "sky/engine/config.h" | 25 #include "sky/engine/config.h" |
| 26 #include "sky/engine/core/dom/Node.h" | 26 #include "sky/engine/core/dom/Node.h" |
| 27 | 27 |
| 28 #include "base/trace_event/trace_event_impl.h" | 28 #include "base/trace_event/trace_event_impl.h" |
| 29 #include "gen/sky/core/HTMLNames.h" | 29 #include "gen/sky/core/HTMLNames.h" |
| 30 #include "sky/engine/bindings/core/v8/DOMDataStore.h" | 30 #include "sky/engine/bindings2/exception_state.h" |
| 31 #include "sky/engine/bindings/core/v8/ExceptionState.h" | |
| 32 #include "sky/engine/bindings/core/v8/ScriptCallStackFactory.h" | |
| 33 #include "sky/engine/bindings/core/v8/V8DOMWrapper.h" | |
| 34 #include "sky/engine/core/css/resolver/StyleResolver.h" | 31 #include "sky/engine/core/css/resolver/StyleResolver.h" |
| 35 #include "sky/engine/core/dom/Attr.h" | 32 #include "sky/engine/core/dom/Attr.h" |
| 36 #include "sky/engine/core/dom/Attribute.h" | 33 #include "sky/engine/core/dom/Attribute.h" |
| 37 #include "sky/engine/core/dom/ChildListMutationScope.h" | 34 #include "sky/engine/core/dom/ChildListMutationScope.h" |
| 38 #include "sky/engine/core/dom/Document.h" | 35 #include "sky/engine/core/dom/Document.h" |
| 39 #include "sky/engine/core/dom/DocumentFragment.h" | 36 #include "sky/engine/core/dom/DocumentFragment.h" |
| 40 #include "sky/engine/core/dom/DocumentMarkerController.h" | 37 #include "sky/engine/core/dom/DocumentMarkerController.h" |
| 41 #include "sky/engine/core/dom/Element.h" | 38 #include "sky/engine/core/dom/Element.h" |
| 42 #include "sky/engine/core/dom/ElementRareData.h" | 39 #include "sky/engine/core/dom/ElementRareData.h" |
| 43 #include "sky/engine/core/dom/ElementTraversal.h" | 40 #include "sky/engine/core/dom/ElementTraversal.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 67 #include "sky/engine/core/frame/Settings.h" | 64 #include "sky/engine/core/frame/Settings.h" |
| 68 #include "sky/engine/core/html/HTMLAnchorElement.h" | 65 #include "sky/engine/core/html/HTMLAnchorElement.h" |
| 69 #include "sky/engine/core/html/HTMLStyleElement.h" | 66 #include "sky/engine/core/html/HTMLStyleElement.h" |
| 70 #include "sky/engine/core/page/EventHandler.h" | 67 #include "sky/engine/core/page/EventHandler.h" |
| 71 #include "sky/engine/core/page/Page.h" | 68 #include "sky/engine/core/page/Page.h" |
| 72 #include "sky/engine/core/rendering/RenderBox.h" | 69 #include "sky/engine/core/rendering/RenderBox.h" |
| 73 #include "sky/engine/platform/EventDispatchForbiddenScope.h" | 70 #include "sky/engine/platform/EventDispatchForbiddenScope.h" |
| 74 #include "sky/engine/platform/JSONValues.h" | 71 #include "sky/engine/platform/JSONValues.h" |
| 75 #include "sky/engine/platform/Partitions.h" | 72 #include "sky/engine/platform/Partitions.h" |
| 76 #include "sky/engine/platform/TraceEvent.h" | 73 #include "sky/engine/platform/TraceEvent.h" |
| 74 #include "sky/engine/tonic/dart_gc_visitor.h" |
| 77 #include "sky/engine/wtf/HashSet.h" | 75 #include "sky/engine/wtf/HashSet.h" |
| 78 #include "sky/engine/wtf/PassOwnPtr.h" | 76 #include "sky/engine/wtf/PassOwnPtr.h" |
| 79 #include "sky/engine/wtf/RefCountedLeakCounter.h" | 77 #include "sky/engine/wtf/RefCountedLeakCounter.h" |
| 80 #include "sky/engine/wtf/Vector.h" | 78 #include "sky/engine/wtf/Vector.h" |
| 81 #include "sky/engine/wtf/text/CString.h" | 79 #include "sky/engine/wtf/text/CString.h" |
| 82 #include "sky/engine/wtf/text/StringBuilder.h" | 80 #include "sky/engine/wtf/text/StringBuilder.h" |
| 83 | 81 |
| 84 namespace blink { | 82 namespace blink { |
| 85 | 83 |
| 86 struct SameSizeAsNode : public EventTarget, public TreeShared<Node> { | 84 struct SameSizeAsNode : public EventTarget, public TreeShared<Node> { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 311 |
| 314 RenderObject* renderer = m_data.m_rareData->renderer(); | 312 RenderObject* renderer = m_data.m_rareData->renderer(); |
| 315 if (isElementNode()) | 313 if (isElementNode()) |
| 316 delete static_cast<ElementRareData*>(m_data.m_rareData); | 314 delete static_cast<ElementRareData*>(m_data.m_rareData); |
| 317 else | 315 else |
| 318 delete static_cast<NodeRareData*>(m_data.m_rareData); | 316 delete static_cast<NodeRareData*>(m_data.m_rareData); |
| 319 m_data.m_renderer = renderer; | 317 m_data.m_renderer = renderer; |
| 320 clearFlag(HasRareDataFlag); | 318 clearFlag(HasRareDataFlag); |
| 321 } | 319 } |
| 322 | 320 |
| 321 static const Node* rootForGC(const Node* node) |
| 322 { |
| 323 if (node->inDocument()) |
| 324 return &node->document(); |
| 325 while (Node* parent = node->parentOrShadowHostOrTemplateHostNode()) |
| 326 node = parent; |
| 327 return node; |
| 328 } |
| 329 |
| 330 void Node::AcceptDartGCVisitor(DartGCVisitor& visitor) const |
| 331 { |
| 332 visitor.AddToSetForRoot(rootForGC(this), dart_wrapper()); |
| 333 EventTarget::AcceptDartGCVisitor(visitor); |
| 334 } |
| 335 |
| 323 Node* Node::toNode() | 336 Node* Node::toNode() |
| 324 { | 337 { |
| 325 return this; | 338 return this; |
| 326 } | 339 } |
| 327 | 340 |
| 328 short Node::tabIndex() const | 341 short Node::tabIndex() const |
| 329 { | 342 { |
| 330 return 0; | 343 return 0; |
| 331 } | 344 } |
| 332 | 345 |
| 333 PassRefPtr<Node> Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, E
xceptionState& exceptionState) | 346 PassRefPtr<Node> Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, E
xceptionState& exceptionState) |
| 334 { | 347 { |
| 335 if (isContainerNode()) | 348 if (isContainerNode()) |
| 336 return toContainerNode(this)->insertBefore(newChild, refChild, exception
State); | 349 return toContainerNode(this)->insertBefore(newChild, refChild, exception
State); |
| 337 | 350 |
| 338 exceptionState.throwDOMException(HierarchyRequestError, "This node type does
not support this method."); | 351 exceptionState.ThrowDOMException(HierarchyRequestError, "This node type does
not support this method."); |
| 339 return nullptr; | 352 return nullptr; |
| 340 } | 353 } |
| 341 | 354 |
| 342 PassRefPtr<Node> Node::replaceChild(PassRefPtr<Node> newChild, PassRefPtr<Node>
oldChild, ExceptionState& exceptionState) | 355 PassRefPtr<Node> Node::replaceChild(PassRefPtr<Node> newChild, PassRefPtr<Node>
oldChild, ExceptionState& exceptionState) |
| 343 { | 356 { |
| 344 if (isContainerNode()) | 357 if (isContainerNode()) |
| 345 return toContainerNode(this)->replaceChild(newChild, oldChild, exception
State); | 358 return toContainerNode(this)->replaceChild(newChild, oldChild, exception
State); |
| 346 | 359 |
| 347 exceptionState.throwDOMException(HierarchyRequestError, "This node type doe
s not support this method."); | 360 exceptionState.ThrowDOMException(HierarchyRequestError, "This node type doe
s not support this method."); |
| 348 return nullptr; | 361 return nullptr; |
| 349 } | 362 } |
| 350 | 363 |
| 351 PassRefPtr<Node> Node::removeChild(PassRefPtr<Node> oldChild, ExceptionState& ex
ceptionState) | 364 PassRefPtr<Node> Node::removeChild(PassRefPtr<Node> oldChild, ExceptionState& ex
ceptionState) |
| 352 { | 365 { |
| 353 if (isContainerNode()) | 366 if (isContainerNode()) |
| 354 return toContainerNode(this)->removeChild(oldChild, exceptionState); | 367 return toContainerNode(this)->removeChild(oldChild, exceptionState); |
| 355 | 368 |
| 356 exceptionState.throwDOMException(NotFoundError, "This node type does not sup
port this method."); | 369 exceptionState.ThrowDOMException(NotFoundError, "This node type does not sup
port this method."); |
| 357 return nullptr; | 370 return nullptr; |
| 358 } | 371 } |
| 359 | 372 |
| 360 PassRefPtr<Node> Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& ex
ceptionState) | 373 PassRefPtr<Node> Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& ex
ceptionState) |
| 361 { | 374 { |
| 362 if (isContainerNode()) | 375 if (isContainerNode()) |
| 363 return toContainerNode(this)->appendChild(newChild, exceptionState); | 376 return toContainerNode(this)->appendChild(newChild, exceptionState); |
| 364 | 377 |
| 365 exceptionState.throwDOMException(HierarchyRequestError, "This node type does
not support this method."); | 378 exceptionState.ThrowDOMException(HierarchyRequestError, "This node type does
not support this method."); |
| 366 return nullptr; | 379 return nullptr; |
| 367 } | 380 } |
| 368 | 381 |
| 369 void Node::remove(ExceptionState& exceptionState) | 382 void Node::remove(ExceptionState& exceptionState) |
| 370 { | 383 { |
| 371 if (ContainerNode* parent = parentNode()) | 384 if (ContainerNode* parent = parentNode()) |
| 372 parent->removeChild(this, exceptionState); | 385 parent->removeChild(this, exceptionState); |
| 373 } | 386 } |
| 374 | 387 |
| 375 const AtomicString& Node::localName() const | 388 const AtomicString& Node::localName() const |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 | 488 |
| 476 void AppendAsTraceFormat(std::string* out) const override | 489 void AppendAsTraceFormat(std::string* out) const override |
| 477 { | 490 { |
| 478 out->append(m_value->toJSONString().utf8().data()); | 491 out->append(m_value->toJSONString().utf8().data()); |
| 479 } | 492 } |
| 480 | 493 |
| 481 private: | 494 private: |
| 482 RefPtr<JSONValue> m_value; | 495 RefPtr<JSONValue> m_value; |
| 483 }; | 496 }; |
| 484 | 497 |
| 485 void addJsStack(JSONArray* stackFrames) | |
| 486 { | |
| 487 RefPtr<ScriptCallStack> stack = createScriptCallStack(10); | |
| 488 if (!stack) | |
| 489 return; | |
| 490 for (size_t i = 0; i < stack->size(); i++) | |
| 491 stackFrames->pushString(stack->at(i).functionName()); | |
| 492 } | |
| 493 | |
| 494 scoped_refptr<base::debug::ConvertableToTraceFormat> jsonObjectForStyleInvalidat
ion(unsigned nodeCount, const Node* rootNode) | |
| 495 { | |
| 496 RefPtr<JSONObject> value = JSONObject::create(); | |
| 497 value->setNumber("node_count", nodeCount); | |
| 498 value->setString("root_node", rootNode->debugName()); | |
| 499 RefPtr<JSONArray> stack; | |
| 500 addJsStack(stack.get()); | |
| 501 value->setArray("js_stack", stack.release()); | |
| 502 return make_scoped_refptr(new JSONTraceValue(value)); | |
| 503 } | |
| 504 | |
| 505 } // namespace | 498 } // namespace |
| 506 | 499 |
| 507 unsigned Node::styledSubtreeSize() const | 500 unsigned Node::styledSubtreeSize() const |
| 508 { | 501 { |
| 509 unsigned nodeCount = 0; | 502 unsigned nodeCount = 0; |
| 510 | 503 |
| 511 for (const Node* node = this; node; node = NodeTraversal::next(*node, this))
{ | 504 for (const Node* node = this; node; node = NodeTraversal::next(*node, this))
{ |
| 512 if (node->isTextNode() || node->isElementNode()) | 505 if (node->isTextNode() || node->isElementNode()) |
| 513 nodeCount++; | 506 nodeCount++; |
| 514 if (ShadowRoot* root = node->shadowRoot()) | 507 if (ShadowRoot* root = node->shadowRoot()) |
| 515 nodeCount += root->styledSubtreeSize(); | 508 nodeCount += root->styledSubtreeSize(); |
| 516 } | 509 } |
| 517 | 510 |
| 518 return nodeCount; | 511 return nodeCount; |
| 519 } | 512 } |
| 520 | 513 |
| 521 void Node::traceStyleChange(StyleChangeType changeType) | 514 void Node::traceStyleChange(StyleChangeType changeType) |
| 522 { | 515 { |
| 523 static const unsigned kMinLoggedSize = 100; | 516 static const unsigned kMinLoggedSize = 100; |
| 524 unsigned nodeCount = styledSubtreeSize(); | 517 unsigned nodeCount = styledSubtreeSize(); |
| 525 if (nodeCount < kMinLoggedSize) | 518 if (nodeCount < kMinLoggedSize) |
| 526 return; | 519 return; |
| 527 | 520 |
| 528 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("style.debug"), | 521 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("style.debug"), |
| 529 "Node::setNeedsStyleRecalc", TRACE_EVENT_SCOPE_PROCESS, | 522 "Node::setNeedsStyleRecalc", TRACE_EVENT_SCOPE_PROCESS |
| 530 "data", jsonObjectForStyleInvalidation(nodeCount, this) | |
| 531 ); | 523 ); |
| 532 } | 524 } |
| 533 | 525 |
| 534 void Node::traceStyleChangeIfNeeded(StyleChangeType changeType) | 526 void Node::traceStyleChangeIfNeeded(StyleChangeType changeType) |
| 535 { | 527 { |
| 536 // TRACE_EVENT_CATEGORY_GROUP_ENABLED macro loads a global static bool into
our local bool. | 528 // TRACE_EVENT_CATEGORY_GROUP_ENABLED macro loads a global static bool into
our local bool. |
| 537 bool styleTracingEnabled; | 529 bool styleTracingEnabled; |
| 538 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("style.debug"),
&styleTracingEnabled); | 530 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("style.debug"),
&styleTracingEnabled); |
| 539 if (UNLIKELY(styleTracingEnabled)) | 531 if (UNLIKELY(styleTracingEnabled)) |
| 540 traceStyleChange(changeType); | 532 traceStyleChange(changeType); |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 return toCharacterData(this)->length(); | 1587 return toCharacterData(this)->length(); |
| 1596 case Node::ELEMENT_NODE: | 1588 case Node::ELEMENT_NODE: |
| 1597 case Node::DOCUMENT_NODE: | 1589 case Node::DOCUMENT_NODE: |
| 1598 case Node::DOCUMENT_FRAGMENT_NODE: | 1590 case Node::DOCUMENT_FRAGMENT_NODE: |
| 1599 return toContainerNode(this)->countChildren(); | 1591 return toContainerNode(this)->countChildren(); |
| 1600 } | 1592 } |
| 1601 ASSERT_NOT_REACHED(); | 1593 ASSERT_NOT_REACHED(); |
| 1602 return 0; | 1594 return 0; |
| 1603 } | 1595 } |
| 1604 | 1596 |
| 1605 v8::Handle<v8::Object> Node::wrap(v8::Handle<v8::Object> creationContext, v8::Is
olate* isolate) | |
| 1606 { | |
| 1607 ASSERT(!DOMDataStore::containsWrapperNonTemplate(this, isolate)); | |
| 1608 | |
| 1609 const WrapperTypeInfo* wrapperType = wrapperTypeInfo(); | |
| 1610 | |
| 1611 v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext
, wrapperType, toScriptWrappableBase(), isolate); | |
| 1612 if (UNLIKELY(wrapper.IsEmpty())) | |
| 1613 return wrapper; | |
| 1614 | |
| 1615 wrapperType->installConditionallyEnabledProperties(wrapper, isolate); | |
| 1616 V8DOMWrapper::associateObjectWithWrapperNonTemplate(this, wrapperType, wrapp
er, isolate); | |
| 1617 return wrapper; | |
| 1618 } | |
| 1619 | |
| 1620 } // namespace blink | 1597 } // namespace blink |
| 1621 | 1598 |
| 1622 #ifndef NDEBUG | 1599 #ifndef NDEBUG |
| 1623 | 1600 |
| 1624 void showNode(const blink::Node* node) | 1601 void showNode(const blink::Node* node) |
| 1625 { | 1602 { |
| 1626 if (node) | 1603 if (node) |
| 1627 node->showNode(""); | 1604 node->showNode(""); |
| 1628 } | 1605 } |
| 1629 | 1606 |
| 1630 void showTree(const blink::Node* node) | 1607 void showTree(const blink::Node* node) |
| 1631 { | 1608 { |
| 1632 if (node) | 1609 if (node) |
| 1633 node->showTreeForThis(); | 1610 node->showTreeForThis(); |
| 1634 } | 1611 } |
| 1635 | 1612 |
| 1636 void showNodePath(const blink::Node* node) | 1613 void showNodePath(const blink::Node* node) |
| 1637 { | 1614 { |
| 1638 if (node) | 1615 if (node) |
| 1639 node->showNodePathForThis(); | 1616 node->showNodePathForThis(); |
| 1640 } | 1617 } |
| 1641 | 1618 |
| 1642 #endif | 1619 #endif |
| OLD | NEW |