summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/dom
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/WebKit/Source/core/dom
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/dom')
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp107
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Attr.cpp115
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Attr.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Attr.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CDATASection.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CharacterData.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp106
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNode.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNode.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp)17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClassCollection.h (renamed from chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h)38
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRect.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRect.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRectList.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp525
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Clipboard.h140
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Clipboard.idl43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Comment.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Comment.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Comment.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp536
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNode.h262
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp158
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h240
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMError.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMError.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMException.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMException.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMException.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp134
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringList.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURL.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Document.cpp2925
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Document.h765
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Document.idl83
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/NodeList.cpp)31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentInit.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp118
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h110
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp136
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentParser.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp167
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp207
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentType.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentType.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Element.cpp1778
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Element.h382
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Element.idl107
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementData.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementData.h148
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h (renamed from chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h)17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementRareData.h202
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h302
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/Promise.h)32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h (renamed from chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h)51
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Entity.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Entity.idl25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp168
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IconURL.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IconURL.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h193
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h198
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessageChannel.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessagePort.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessagePort.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Microtask.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Microtask.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationCallback.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp119
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserver.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationRecord.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NameNodeList.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp249
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlow.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Node.cpp871
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Node.h364
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Node.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilter.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIterator.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/Traversal.cpp)15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h (renamed from chromium/third_party/WebKit/Source/core/dom/Traversal.h)57
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeList.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeList.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRareData.h283
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp281
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp170
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h106
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Notation.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ParentNode.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ParentNode.idl40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PendingScript.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Position.cpp126
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Position.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PositionIterator.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp199
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Promise.idl46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PseudoElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/QualifiedName.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Range.cpp657
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Range.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Range.idl25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp144
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp177
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h (renamed from chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h)44
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SecurityContext.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp531
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleElement.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp485
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleEngine.h146
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp140
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h (renamed from chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h)54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp221
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h100
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp)29
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagCollection.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagNodeList.h91
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Text.cpp95
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Text.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Text.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Touch.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Touch.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Touch.idl24
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchController.cpp162
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchController.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchList.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchList.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchList.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TransformSource.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp247
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScope.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp233
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h116
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeShared.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeWalker.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/URL.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/URLUtils.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WheelController.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/ClipboardAccessPolicy.h)26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/XMLDocument.h (renamed from chromium/third_party/WebKit/Source/core/dom/WheelController.h)56
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp (renamed from chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp)44
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp134
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h (renamed from chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h)46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h (renamed from chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp)43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h (renamed from chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h)28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp155
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h86
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp137
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp151
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h35
360 files changed, 14370 insertions, 12640 deletions
diff --git a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp
index be52d0f70fd..78e88e8c6e6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp
@@ -34,7 +34,7 @@ namespace WebCore {
ActiveDOMObject::ActiveDOMObject(ExecutionContext* executionContext)
: ContextLifecycleObserver(executionContext, ActiveDOMObjectType)
, m_pendingActivityCount(0)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_suspendIfNeededCalled(false)
#endif
{
@@ -58,7 +58,7 @@ ActiveDOMObject::~ActiveDOMObject()
void ActiveDOMObject::suspendIfNeeded()
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
ASSERT(!m_suspendIfNeededCalled);
m_suspendIfNeededCalled = true;
#endif
@@ -83,4 +83,21 @@ void ActiveDOMObject::stop()
{
}
+void ActiveDOMObject::didMoveToNewExecutionContext(ExecutionContext* context)
+{
+ observeContext(context);
+
+ if (context->activeDOMObjectsAreStopped()) {
+ stop();
+ return;
+ }
+
+ if (context->activeDOMObjectsAreSuspended()) {
+ suspend();
+ return;
+ }
+
+ resume();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h
index 1157363cb3b..e35637c4d4c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h
@@ -29,7 +29,6 @@
#include "core/dom/ContextLifecycleObserver.h"
#include "wtf/Assertions.h"
-#include "wtf/Forward.h"
namespace WebCore {
@@ -40,7 +39,7 @@ public:
// suspendIfNeeded() should be called exactly once after object construction to synchronize
// the suspend state with that in ExecutionContext.
void suspendIfNeeded();
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool suspendIfNeededCalled() const { return m_suspendIfNeededCalled; }
#endif
@@ -57,6 +56,8 @@ public:
virtual void resume();
virtual void stop();
+ void didMoveToNewExecutionContext(ExecutionContext*);
+
protected:
virtual ~ActiveDOMObject();
@@ -76,7 +77,7 @@ protected:
private:
unsigned m_pendingActivityCount;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool m_suspendIfNeededCalled;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp
new file mode 100644
index 00000000000..9be6d8335f6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/Document.h"
+
+#include "core/testing/DummyPageHolder.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class MockActiveDOMObject : public ActiveDOMObject {
+public:
+ MockActiveDOMObject(ExecutionContext* context) : ActiveDOMObject(context) { }
+
+ MOCK_METHOD0(suspend, void());
+ MOCK_METHOD0(resume, void());
+ MOCK_METHOD0(stop, void());
+};
+
+class ActiveDOMObjectTest : public ::testing::Test {
+protected:
+ ActiveDOMObjectTest();
+
+ Document& srcDocument() const { return m_srcPageHolder->document(); }
+ Document& destDocument() const { return m_destPageHolder->document(); }
+ MockActiveDOMObject& activeDOMObject() { return m_activeDOMObject; }
+
+private:
+ OwnPtr<DummyPageHolder> m_srcPageHolder;
+ OwnPtr<DummyPageHolder> m_destPageHolder;
+ MockActiveDOMObject m_activeDOMObject;
+};
+
+ActiveDOMObjectTest::ActiveDOMObjectTest()
+ : m_srcPageHolder(DummyPageHolder::create(IntSize(800, 600)))
+ , m_destPageHolder(DummyPageHolder::create(IntSize(800, 600)))
+ , m_activeDOMObject(&m_srcPageHolder->document())
+{
+ m_activeDOMObject.suspendIfNeeded();
+}
+
+TEST_F(ActiveDOMObjectTest, NewContextObserved)
+{
+ unsigned initialSrcCount = srcDocument().activeDOMObjectCount();
+ unsigned initialDestCount = destDocument().activeDOMObjectCount();
+
+ EXPECT_CALL(activeDOMObject(), resume());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+
+ EXPECT_EQ(initialSrcCount - 1, srcDocument().activeDOMObjectCount());
+ EXPECT_EQ(initialDestCount + 1, destDocument().activeDOMObjectCount());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToActiveDocument)
+{
+ EXPECT_CALL(activeDOMObject(), resume());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToSuspendedDocument)
+{
+ destDocument().suspendScheduledTasks();
+
+ EXPECT_CALL(activeDOMObject(), suspend());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToStoppedDocument)
+{
+ destDocument().detach();
+
+ EXPECT_CALL(activeDOMObject(), stop());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+} // unnamed namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/Attr.cpp b/chromium/third_party/WebKit/Source/core/dom/Attr.cpp
index b67b2818f65..802bc19f555 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Attr.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Attr.cpp
@@ -23,11 +23,10 @@
#include "config.h"
#include "core/dom/Attr.h"
-#include "XMLNSNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/ExceptionCode.h"
#include "core/dom/Text.h"
#include "core/events/ScopedEventQueue.h"
#include "core/frame/UseCounter.h"
@@ -49,24 +48,24 @@ Attr::Attr(Element& element, const QualifiedName& name)
Attr::Attr(Document& document, const QualifiedName& name, const AtomicString& standaloneValue)
: ContainerNode(&document)
- , m_element(0)
+ , m_element(nullptr)
, m_name(name)
- , m_standaloneValue(standaloneValue)
+ , m_standaloneValueOrAttachedLocalName(standaloneValue)
, m_ignoreChildrenChanged(0)
{
ScriptWrappable::init(this);
}
-PassRefPtr<Attr> Attr::create(Element& element, const QualifiedName& name)
+PassRefPtrWillBeRawPtr<Attr> Attr::create(Element& element, const QualifiedName& name)
{
- RefPtr<Attr> attr = adoptRef(new Attr(element, name));
+ RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeNoop(new Attr(element, name));
attr->createTextChild();
return attr.release();
}
-PassRefPtr<Attr> Attr::create(Document& document, const QualifiedName& name, const AtomicString& value)
+PassRefPtrWillBeRawPtr<Attr> Attr::create(Document& document, const QualifiedName& name, const AtomicString& value)
{
- RefPtr<Attr> attr = adoptRef(new Attr(document, name, value));
+ RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeNoop(new Attr(document, name, value));
attr->createTextChild();
return attr.release();
}
@@ -75,11 +74,26 @@ Attr::~Attr()
{
}
+const QualifiedName Attr::qualifiedName() const
+{
+ if (m_element && !m_standaloneValueOrAttachedLocalName.isNull()) {
+ // In the unlikely case the Element attribute has a local name
+ // that differs by case, construct the qualified name based on
+ // it. This is the qualified name that must be used when
+ // looking up the attribute on the element.
+ return QualifiedName(m_name.prefix(), m_standaloneValueOrAttachedLocalName, m_name.namespaceURI());
+ }
+
+ return m_name;
+}
+
void Attr::createTextChild()
{
+#if !ENABLE(OILPAN)
ASSERT(refCount());
+#endif
if (!value().isEmpty()) {
- RefPtr<Text> textNode = document().createTextNode(value().string());
+ RefPtrWillBeRawPtr<Text> textNode = document().createTextNode(value().string());
// This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
// but much more efficiently.
@@ -90,31 +104,6 @@ void Attr::createTextChild()
}
}
-void Attr::setPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
-{
- UseCounter::count(document(), UseCounter::AttributeSetPrefix);
-
- checkSetPrefix(prefix, exceptionState);
- if (exceptionState.hadException())
- return;
-
- if (prefix == xmlnsAtom && namespaceURI() != XMLNSNames::xmlnsNamespaceURI) {
- exceptionState.throwDOMException(NamespaceError, "The prefix '" + xmlnsAtom + "' may not be used on the namespace '" + namespaceURI() + "'.");
- return;
- }
-
- if (this->qualifiedName() == xmlnsAtom) {
- exceptionState.throwDOMException(NamespaceError, "The prefix '" + prefix + "' may not be used as a namespace prefix for attributes whose qualified name is '" + xmlnsAtom + "'.");
- return;
- }
-
- const AtomicString& newPrefix = prefix.isEmpty() ? nullAtom : prefix;
-
- if (m_element)
- elementAttribute().setPrefix(newPrefix);
- m_name.setPrefix(newPrefix);
-}
-
void Attr::setValue(const AtomicString& value)
{
EventQueueScope scope;
@@ -123,14 +112,15 @@ void Attr::setValue(const AtomicString& value)
if (m_element)
elementAttribute().setValue(value);
else
- m_standaloneValue = value;
+ m_standaloneValueOrAttachedLocalName = value;
createTextChild();
m_ignoreChildrenChanged--;
- invalidateNodeListCachesInAncestors(&m_name, m_element);
+ QualifiedName name = qualifiedName();
+ invalidateNodeListCachesInAncestors(&name, m_element);
}
-void Attr::setValue(const AtomicString& value, ExceptionState&)
+void Attr::setValueInternal(const AtomicString& value)
{
if (m_element)
m_element->willModifyAttribute(qualifiedName(), this->value(), value);
@@ -141,14 +131,30 @@ void Attr::setValue(const AtomicString& value, ExceptionState&)
m_element->didModifyAttribute(qualifiedName(), value);
}
+const AtomicString& Attr::valueForBindings() const
+{
+ UseCounter::count(document(), UseCounter::AttrGetValue);
+ return value();
+}
+
+void Attr::setValueForBindings(const AtomicString& value)
+{
+ UseCounter::count(document(), UseCounter::AttrSetValue);
+ if (m_element)
+ UseCounter::count(document(), UseCounter::AttrSetValueWithElement);
+ setValueInternal(value);
+}
+
void Attr::setNodeValue(const String& v)
{
- setValue(v, IGNORE_EXCEPTION);
+ // Attr uses AtomicString type for its value to save memory as there
+ // is duplication among Elements' attributes values.
+ setValueInternal(AtomicString(v));
}
-PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> Attr::cloneNode(bool /*deep*/)
{
- RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
+ RefPtrWillBeRawPtr<Attr> clone = adoptRefWillBeNoop(new Attr(document(), m_name, value()));
cloneChildNodes(clone.get());
return clone.release();
}
@@ -164,7 +170,8 @@ void Attr::childrenChanged(bool, Node*, Node*, int)
if (m_ignoreChildrenChanged > 0)
return;
- invalidateNodeListCachesInAncestors(&qualifiedName(), m_element);
+ QualifiedName name = qualifiedName();
+ invalidateNodeListCachesInAncestors(&name, m_element);
StringBuilder valueBuilder;
for (Node *n = firstChild(); n; n = n->nextSibling()) {
@@ -179,44 +186,44 @@ void Attr::childrenChanged(bool, Node*, Node*, int)
if (m_element)
elementAttribute().setValue(newValue);
else
- m_standaloneValue = newValue;
+ m_standaloneValueOrAttachedLocalName = newValue;
if (m_element)
m_element->attributeChanged(qualifiedName(), newValue);
}
-bool Attr::isId() const
-{
- return qualifiedName().matches(document().idAttributeName());
-}
-
const AtomicString& Attr::value() const
{
if (m_element)
return m_element->getAttribute(qualifiedName());
- return m_standaloneValue;
+ return m_standaloneValueOrAttachedLocalName;
}
Attribute& Attr::elementAttribute()
{
ASSERT(m_element);
ASSERT(m_element->elementData());
- return *m_element->ensureUniqueElementData()->getAttributeItem(qualifiedName());
+ return *m_element->ensureUniqueElementData().findAttributeByName(qualifiedName());
}
void Attr::detachFromElementWithValue(const AtomicString& value)
{
ASSERT(m_element);
- ASSERT(m_standaloneValue.isNull());
- m_standaloneValue = value;
- m_element = 0;
+ m_standaloneValueOrAttachedLocalName = value;
+ m_element = nullptr;
}
-void Attr::attachToElement(Element* element)
+void Attr::attachToElement(Element* element, const AtomicString& attachedLocalName)
{
ASSERT(!m_element);
m_element = element;
- m_standaloneValue = nullAtom;
+ m_standaloneValueOrAttachedLocalName = attachedLocalName;
+}
+
+void Attr::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ ContainerNode::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/Attr.h b/chromium/third_party/WebKit/Source/core/dom/Attr.h
index 40d812b3997..b6b2b4d362c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Attr.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Attr.h
@@ -30,9 +30,7 @@
namespace WebCore {
-class CSSStyleDeclaration;
class ExceptionState;
-class MutableStylePropertySet;
// Attr can have Text children
// therefore it has to be a fullblown Node. The plan
@@ -42,30 +40,30 @@ class MutableStylePropertySet;
class Attr FINAL : public ContainerNode {
public:
- static PassRefPtr<Attr> create(Element&, const QualifiedName&);
- static PassRefPtr<Attr> create(Document&, const QualifiedName&, const AtomicString& value);
+ static PassRefPtrWillBeRawPtr<Attr> create(Element&, const QualifiedName&);
+ static PassRefPtrWillBeRawPtr<Attr> create(Document&, const QualifiedName&, const AtomicString& value);
virtual ~Attr();
- String name() const { return qualifiedName().toString(); }
+ String name() const { return m_name.toString(); }
bool specified() const { return true; }
Element* ownerElement() const { return m_element; }
const AtomicString& value() const;
- void setValue(const AtomicString&, ExceptionState&);
void setValue(const AtomicString&);
- const QualifiedName& qualifiedName() const { return m_name; }
+ const AtomicString& valueForBindings() const;
+ void setValueForBindings(const AtomicString&);
- bool isId() const;
+ const QualifiedName qualifiedName() const;
- void attachToElement(Element*);
+ void attachToElement(Element*, const AtomicString&);
void detachFromElementWithValue(const AtomicString&);
virtual const AtomicString& localName() const OVERRIDE { return m_name.localName(); }
virtual const AtomicString& namespaceURI() const OVERRIDE { return m_name.namespaceURI(); }
- virtual const AtomicString& prefix() const OVERRIDE { return m_name.prefix(); }
+ const AtomicString& prefix() const { return m_name.prefix(); }
- virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
private:
Attr(Element&, const QualifiedName&);
@@ -73,25 +71,31 @@ private:
void createTextChild();
+ void setValueInternal(const AtomicString&);
+
virtual String nodeName() const OVERRIDE { return name(); }
virtual NodeType nodeType() const OVERRIDE { return ATTRIBUTE_NODE; }
virtual String nodeValue() const OVERRIDE { return value(); }
- virtual void setNodeValue(const String&);
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
+ virtual void setNodeValue(const String&) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
- virtual bool isAttributeNode() const { return true; }
- virtual bool childTypeAllowed(NodeType) const;
+ virtual bool isAttributeNode() const OVERRIDE { return true; }
+ virtual bool childTypeAllowed(NodeType) const OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
Attribute& elementAttribute();
// Attr wraps either an element/name, or a name/value pair (when it's a standalone Node.)
// Note that m_name is always set, but m_element/m_standaloneValue may be null.
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
QualifiedName m_name;
- AtomicString m_standaloneValue;
+ // Holds the value if it is a standalone Node, or the local name of the
+ // attribute it is attached to on an Element. The latter may (letter case)
+ // differ from m_name's local name. As these two modes are non-overlapping,
+ // use a single field.
+ AtomicString m_standaloneValueOrAttachedLocalName;
unsigned m_ignoreChildrenChanged;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Attr.idl b/chromium/third_party/WebKit/Source/core/dom/Attr.idl
index 00d9205a929..9c1fb6c82a5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Attr.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Attr.idl
@@ -26,20 +26,18 @@ interface Attr : Node {
[MeasureAs=AttributeSpecified] readonly attribute boolean specified;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, RaisesException=Setter, CustomElementCallbacks] attribute DOMString value;
+ [ImplementedAs=valueForBindings, TreatReturnedNullStringAs=Null, TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString value;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, DeprecateAs=AttrNodeValue, ImplementedAs=valueForBindings] attribute DOMString nodeValue;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, DeprecateAs=AttrTextContent, ImplementedAs=valueForBindings] attribute DOMString textContent;
// DOM Level 2
- [MeasureAs=AttributeOwnerElement] readonly attribute Element ownerElement;
-
- // DOM Level 3
-
- [MeasureAs=AttributeIsId] readonly attribute boolean isId;
+ [DeprecateAs=AttributeOwnerElement] readonly attribute Element ownerElement;
// DOM 4
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, RaisesException=Setter] attribute DOMString prefix;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString namespaceURI;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString localName;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString prefix;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString namespaceURI;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString localName;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp b/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp
index ec61f0995a0..5ae5bbf8ee4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp
@@ -32,9 +32,9 @@ inline CDATASection::CDATASection(Document& document, const String& data)
ScriptWrappable::init(this);
}
-PassRefPtr<CDATASection> CDATASection::create(Document& document, const String& data)
+PassRefPtrWillBeRawPtr<CDATASection> CDATASection::create(Document& document, const String& data)
{
- return adoptRef(new CDATASection(document, data));
+ return adoptRefWillBeNoop(new CDATASection(document, data));
}
String CDATASection::nodeName() const
@@ -47,12 +47,7 @@ Node::NodeType CDATASection::nodeType() const
return CDATA_SECTION_NODE;
}
-bool CDATASection::childTypeAllowed(NodeType) const
-{
- return false;
-}
-
-PassRefPtr<Text> CDATASection::cloneWithData(const String& data)
+PassRefPtrWillBeRawPtr<Text> CDATASection::cloneWithData(const String& data)
{
return create(document(), data);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/CDATASection.h b/chromium/third_party/WebKit/Source/core/dom/CDATASection.h
index 338866f02ec..6efcfcc147d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CDATASection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CDATASection.h
@@ -29,15 +29,14 @@ namespace WebCore {
class CDATASection FINAL : public Text {
public:
- static PassRefPtr<CDATASection> create(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<CDATASection> create(Document&, const String&);
private:
CDATASection(Document&, const String&);
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual bool childTypeAllowed(NodeType) const;
- virtual PassRefPtr<Text> cloneWithData(const String&) OVERRIDE;
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Text> cloneWithData(const String&) OVERRIDE;
};
DEFINE_NODE_TYPE_CASTS(CDATASection, nodeType() == Node::CDATA_SECTION_NODE);
diff --git a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
index 074d6b2ee81..123c036df47 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
@@ -31,13 +31,13 @@
#include "config.h"
#include "core/dom/CSSSelectorWatch.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSSelectorList.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "core/rendering/style/StyleRareNonInheritedData.h"
namespace WebCore {
@@ -54,10 +54,10 @@ CSSSelectorWatch::CSSSelectorWatch(Document& document)
CSSSelectorWatch& CSSSelectorWatch::from(Document& document)
{
- CSSSelectorWatch* watch = static_cast<CSSSelectorWatch*>(DocumentSupplement::from(&document, kSupplementName));
+ CSSSelectorWatch* watch = static_cast<CSSSelectorWatch*>(DocumentSupplement::from(document, kSupplementName));
if (!watch) {
watch = new CSSSelectorWatch(document);
- DocumentSupplement::provideTo(&document, kSupplementName, adoptPtr(watch));
+ DocumentSupplement::provideTo(document, kSupplementName, adoptPtrWillBeNoop(watch));
}
return *watch;
}
@@ -69,7 +69,7 @@ void CSSSelectorWatch::callbackSelectorChangeTimerFired(Timer<CSSSelectorWatch>*
if (m_timerExpirations < 1) {
m_timerExpirations++;
- m_callbackSelectorChangeTimer.startOneShot(0);
+ m_callbackSelectorChangeTimer.startOneShot(0, FROM_HERE);
return;
}
if (m_document.frame()) {
@@ -125,13 +125,13 @@ void CSSSelectorWatch::updateSelectorMatches(const Vector<String>& removedSelect
} else {
m_timerExpirations = 0;
if (!m_callbackSelectorChangeTimer.isActive())
- m_callbackSelectorChangeTimer.startOneShot(0);
+ m_callbackSelectorChangeTimer.startOneShot(0, FROM_HERE);
}
}
static bool allCompound(const CSSSelectorList& selectorList)
{
- for (const CSSSelector* selector = selectorList.first(); selector; selector = selectorList.next(selector)) {
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = selectorList.next(*selector)) {
if (!selector->isCompound())
return false;
}
@@ -141,8 +141,7 @@ static bool allCompound(const CSSSelectorList& selectorList)
void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors)
{
m_watchedCallbackSelectors.clear();
- CSSParserContext context(UASheetMode);
- CSSParser parser(context);
+ BisonCSSParser parser(CSSParserContext(UASheetMode, 0));
const CSSProperty callbackProperty(CSSPropertyInternalCallback, CSSPrimitiveValue::createIdentifier(CSSValueInternalPresence));
const RefPtr<StylePropertySet> callbackPropertySet = ImmutableStylePropertySet::create(&callbackProperty, 1, UASheetMode);
@@ -157,7 +156,7 @@ void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors)
if (!allCompound(selectorList))
continue;
- RefPtr<StyleRule> rule = StyleRule::create();
+ RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create();
rule->wrapperAdoptSelectorList(selectorList);
rule->setProperties(callbackPropertySet);
m_watchedCallbackSelectors.append(rule.release());
@@ -165,4 +164,10 @@ void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors)
m_document.changedSelectorWatch();
}
+void CSSSelectorWatch::trace(Visitor* visitor)
+{
+ visitor->trace(m_watchedCallbackSelectors);
+ DocumentSupplement::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
index e1cbbed5608..35756c7a24b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
@@ -43,24 +43,27 @@
namespace WebCore {
-class CSSSelectorWatch : public DocumentSupplement {
+class CSSSelectorWatch FINAL : public NoBaseWillBeGarbageCollectedFinalized<CSSSelectorWatch>, public DocumentSupplement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(CSSSelectorWatch);
public:
virtual ~CSSSelectorWatch() { }
static CSSSelectorWatch& from(Document&);
void watchCSSSelectors(const Vector<String>& selectors);
- const Vector<RefPtr<StyleRule> >& watchedCallbackSelectors() const { return m_watchedCallbackSelectors; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedCallbackSelectors() const { return m_watchedCallbackSelectors; }
void updateSelectorMatches(const Vector<String>& removedSelectors, const Vector<String>& addedSelectors);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- CSSSelectorWatch(Document&);
+ explicit CSSSelectorWatch(Document&);
void callbackSelectorChangeTimerFired(Timer<CSSSelectorWatch>*);
Document& m_document;
- Vector<RefPtr<StyleRule> > m_watchedCallbackSelectors;
+ WillBeHeapVector<RefPtrWillBeMember<StyleRule> > m_watchedCallbackSelectors;
// Maps a CSS selector string with a -webkit-callback property to the number
// of matching RenderStyle objects in this document.
diff --git a/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp b/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp
index d0344f255cd..fce49e276d4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp
@@ -31,10 +31,8 @@
#include "core/dom/Text.h"
#include "core/editing/FrameSelection.h"
#include "core/events/MutationEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/inspector/InspectorInstrumentation.h"
-
-using namespace std;
+#include "wtf/CheckedArithmetic.h"
namespace WebCore {
@@ -49,7 +47,7 @@ void CharacterData::setData(const String& data)
if (m_data == nonNullData)
return;
- RefPtr<CharacterData> protect = this;
+ RefPtrWillBeRawPtr<CharacterData> protect(this);
unsigned oldLength = length();
@@ -70,7 +68,7 @@ String CharacterData::substringData(unsigned offset, unsigned count, ExceptionSt
void CharacterData::parserAppendData(const String& string)
{
unsigned oldLength = m_data.length();
- m_data.append(string);
+ m_data = m_data + string;
ASSERT(!renderer() || isTextNode());
if (isTextNode())
@@ -106,45 +104,49 @@ void CharacterData::insertData(unsigned offset, const String& data, ExceptionSta
document().didInsertText(this, offset, data.length());
}
-void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionState& exceptionState, RecalcStyleBehavior recalcStyleBehavior)
+static bool validateOffsetCount(unsigned offset, unsigned count, unsigned length, unsigned& realCount, ExceptionState& exceptionState)
{
- if (offset > length()) {
- exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is greater than the node's length (" + String::number(length()) + ").");
- return;
+ if (offset > length) {
+ exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is greater than the node's length (" + String::number(length) + ").");
+ return false;
}
- unsigned realCount;
- if (offset + count > length())
- realCount = length() - offset;
+ Checked<unsigned, RecordOverflow> offsetCount = offset;
+ offsetCount += count;
+
+ if (offsetCount.hasOverflowed() || offset + count > length)
+ realCount = length - offset;
else
realCount = count;
+ return true;
+}
+
+void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionState& exceptionState, RecalcStyleBehavior recalcStyleBehavior)
+{
+ unsigned realCount = 0;
+ if (!validateOffsetCount(offset, count, length(), realCount, exceptionState))
+ return;
+
String newStr = m_data;
newStr.remove(offset, realCount);
- setDataAndUpdate(newStr, offset, count, 0, recalcStyleBehavior);
+ setDataAndUpdate(newStr, offset, realCount, 0, recalcStyleBehavior);
document().didRemoveText(this, offset, realCount);
}
void CharacterData::replaceData(unsigned offset, unsigned count, const String& data, ExceptionState& exceptionState)
{
- if (offset > length()) {
- exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is greater than the node's length (" + String::number(length()) + ").");
+ unsigned realCount = 0;
+ if (!validateOffsetCount(offset, count, length(), realCount, exceptionState))
return;
- }
-
- unsigned realCount;
- if (offset + count > length())
- realCount = length() - offset;
- else
- realCount = count;
String newStr = m_data;
newStr.remove(offset, realCount);
newStr.insert(data, offset);
- setDataAndUpdate(newStr, offset, count, data.length());
+ setDataAndUpdate(newStr, offset, realCount, data.length());
// update the markers for spell checking and grammar checking
document().didRemoveText(this, offset, realCount);
@@ -176,7 +178,7 @@ void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfRep
toText(this)->updateTextRenderer(offsetOfReplacedData, oldLength, recalcStyleBehavior);
if (nodeType() == PROCESSING_INSTRUCTION_NODE)
- toProcessingInstruction(this)->checkStyleSheet();
+ toProcessingInstruction(this)->didAttributeChanged();
if (document().frame())
document().frame()->selection().didUpdateCharacterData(this, offsetOfReplacedData, oldLength, newLength);
@@ -187,7 +189,7 @@ void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfRep
void CharacterData::didModifyData(const String& oldData)
{
- if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this))
+ if (OwnPtrWillBeRawPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this))
mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
if (parentNode())
@@ -195,7 +197,7 @@ void CharacterData::didModifyData(const String& oldData)
if (!isInShadowTree()) {
if (document().hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
- dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, 0, oldData, m_data));
+ dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, nullptr, oldData, m_data));
dispatchSubtreeModifiedEvent();
}
InspectorInstrumentation::characterDataModified(this);
diff --git a/chromium/third_party/WebKit/Source/core/dom/CharacterData.h b/chromium/third_party/WebKit/Source/core/dom/CharacterData.h
index 11636228cc7..a89eccdf833 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CharacterData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CharacterData.h
@@ -33,7 +33,7 @@ class ExceptionState;
class CharacterData : public Node {
public:
void atomize();
- String data() const { return m_data; }
+ const String& data() const { return m_data; }
void setData(const String&);
unsigned length() const { return m_data.length(); }
String substringData(unsigned offset, unsigned count, ExceptionState&);
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp
new file mode 100644
index 00000000000..555da1cd3b9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp
@@ -0,0 +1,106 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/ChildFrameDisconnector.h"
+
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+#ifndef NDEBUG
+static unsigned checkConnectedSubframeCountIsConsistent(Node&);
+#endif
+
+void ChildFrameDisconnector::disconnect(DisconnectPolicy policy)
+{
+#ifndef NDEBUG
+ checkConnectedSubframeCountIsConsistent(m_root);
+#endif
+
+ if (!m_root.connectedSubframeCount())
+ return;
+
+ if (policy == RootAndDescendants) {
+ collectFrameOwners(m_root);
+ } else {
+ for (Node* child = m_root.firstChild(); child; child = child->nextSibling())
+ collectFrameOwners(*child);
+ }
+
+ disconnectCollectedFrameOwners();
+}
+
+void ChildFrameDisconnector::collectFrameOwners(Node& root)
+{
+ if (!root.connectedSubframeCount())
+ return;
+
+ if (root.isHTMLElement() && root.isFrameOwnerElement())
+ m_frameOwners.append(&toHTMLFrameOwnerElement(root));
+
+ for (Node* child = root.firstChild(); child; child = child->nextSibling())
+ collectFrameOwners(*child);
+
+ ElementShadow* shadow = root.isElementNode() ? toElement(root).shadow() : 0;
+ if (shadow)
+ collectFrameOwners(*shadow);
+}
+
+void ChildFrameDisconnector::disconnectCollectedFrameOwners()
+{
+ // Must disable frame loading in the subtree so an unload handler cannot
+ // insert more frames and create loaded frames in detached subtrees.
+ SubframeLoadingDisabler disabler(m_root);
+
+ for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
+ HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
+ // Don't need to traverse up the tree for the first owner since no
+ // script could have moved it.
+ if (!i || m_root.containsIncludingShadowDOM(owner))
+ owner->disconnectContentFrame();
+ }
+}
+
+void ChildFrameDisconnector::collectFrameOwners(ElementShadow& shadow)
+{
+ for (ShadowRoot* root = shadow.youngestShadowRoot(); root; root = root->olderShadowRoot())
+ collectFrameOwners(*root);
+}
+
+#ifndef NDEBUG
+static unsigned checkConnectedSubframeCountIsConsistent(Node& node)
+{
+ unsigned count = 0;
+
+ if (node.isElementNode()) {
+ if (node.isFrameOwnerElement() && toHTMLFrameOwnerElement(node).contentFrame())
+ count++;
+
+ if (ElementShadow* shadow = toElement(node).shadow()) {
+ for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ count += checkConnectedSubframeCountIsConsistent(*root);
+ }
+ }
+
+ for (Node* child = node.firstChild(); child; child = child->nextSibling())
+ count += checkConnectedSubframeCountIsConsistent(*child);
+
+ // If we undercount there's possibly a security bug since we'd leave frames
+ // in subtrees outside the document.
+ ASSERT(node.connectedSubframeCount() >= count);
+
+ // If we overcount it's safe, but not optimal because it means we'll traverse
+ // through the document in ChildFrameDisconnector looking for frames that have
+ // already been disconnected.
+ ASSERT(node.connectedSubframeCount() == count);
+
+ return count;
+}
+#endif
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h
new file mode 100644
index 00000000000..d77e9086f64
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ChildFrameDisconnector_h
+#define ChildFrameDisconnector_h
+
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class ElementShadow;
+class HTMLFrameOwnerElement;
+class Node;
+
+class ChildFrameDisconnector {
+ STACK_ALLOCATED();
+public:
+ enum DisconnectPolicy {
+ RootAndDescendants,
+ DescendantsOnly
+ };
+
+ explicit ChildFrameDisconnector(Node& root)
+ : m_root(root)
+ {
+ }
+
+ void disconnect(DisconnectPolicy = RootAndDescendants);
+
+private:
+ void collectFrameOwners(Node&);
+ void collectFrameOwners(ElementShadow&);
+ void disconnectCollectedFrameOwners();
+
+ WillBeHeapVector<RefPtrWillBeMember<HTMLFrameOwnerElement>, 10> m_frameOwners;
+ Node& m_root;
+};
+
+} // namespace WebCore
+
+#endif // ChildFrameDisconnector_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp
index 1d00364cac5..73593055290 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp
@@ -39,36 +39,47 @@
namespace WebCore {
-typedef HashMap<Node*, ChildListMutationAccumulator*> AccumulatorMap;
+// The accumulator map is used to make sure that there is only one mutation
+// accumulator for a given node even if there are multiple ChildListMutationScopes
+// on the stack. The map is always empty when there are no ChildListMutationScopes
+// on the stack.
+typedef WillBeHeapHashMap<RawPtrWillBeMember<Node>, RawPtrWillBeMember<ChildListMutationAccumulator> > AccumulatorMap;
+
static AccumulatorMap& accumulatorMap()
{
- DEFINE_STATIC_LOCAL(AccumulatorMap, map, ());
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<AccumulatorMap>, map, (adoptPtrWillBeNoop(new AccumulatorMap())));
+ return *map;
}
-ChildListMutationAccumulator::ChildListMutationAccumulator(PassRefPtr<Node> target, PassOwnPtr<MutationObserverInterestGroup> observers)
+ChildListMutationAccumulator::ChildListMutationAccumulator(PassRefPtrWillBeRawPtr<Node> target, PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> observers)
: m_target(target)
- , m_lastAdded(0)
+ , m_lastAdded(nullptr)
, m_observers(observers)
+ , m_mutationScopes(0)
{
}
-ChildListMutationAccumulator::~ChildListMutationAccumulator()
+void ChildListMutationAccumulator::leaveMutationScope()
{
- if (!isEmpty())
- enqueueMutationRecord();
- accumulatorMap().remove(m_target.get());
+ ASSERT(m_mutationScopes > 0);
+ if (!--m_mutationScopes) {
+ if (!isEmpty())
+ enqueueMutationRecord();
+ accumulatorMap().remove(m_target.get());
+ }
}
-PassRefPtr<ChildListMutationAccumulator> ChildListMutationAccumulator::getOrCreate(Node& target)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ChildListMutationAccumulator);
+
+PassRefPtrWillBeRawPtr<ChildListMutationAccumulator> ChildListMutationAccumulator::getOrCreate(Node& target)
{
- AccumulatorMap::AddResult result = accumulatorMap().add(&target, 0);
- RefPtr<ChildListMutationAccumulator> accumulator;
+ AccumulatorMap::AddResult result = accumulatorMap().add(&target, nullptr);
+ RefPtrWillBeRawPtr<ChildListMutationAccumulator> accumulator;
if (!result.isNewEntry)
- accumulator = result.iterator->value;
+ accumulator = result.storedValue->value;
else {
- accumulator = adoptRef(new ChildListMutationAccumulator(PassRefPtr<Node>(target), MutationObserverInterestGroup::createForChildListMutation(target)));
- result.iterator->value = accumulator.get();
+ accumulator = adoptRefWillBeNoop(new ChildListMutationAccumulator(PassRefPtrWillBeRawPtr<Node>(target), MutationObserverInterestGroup::createForChildListMutation(target)));
+ result.storedValue->value = accumulator.get();
}
return accumulator.release();
}
@@ -78,11 +89,11 @@ inline bool ChildListMutationAccumulator::isAddedNodeInOrder(Node* child)
return isEmpty() || (m_lastAdded == child->previousSibling() && m_nextSibling == child->nextSibling());
}
-void ChildListMutationAccumulator::childAdded(PassRefPtr<Node> prpChild)
+void ChildListMutationAccumulator::childAdded(PassRefPtrWillBeRawPtr<Node> prpChild)
{
ASSERT(hasObservers());
- RefPtr<Node> child = prpChild;
+ RefPtrWillBeRawPtr<Node> child = prpChild;
if (!isAddedNodeInOrder(child.get()))
enqueueMutationRecord();
@@ -101,11 +112,11 @@ inline bool ChildListMutationAccumulator::isRemovedNodeInOrder(Node* child)
return isEmpty() || m_nextSibling == child;
}
-void ChildListMutationAccumulator::willRemoveChild(PassRefPtr<Node> prpChild)
+void ChildListMutationAccumulator::willRemoveChild(PassRefPtrWillBeRawPtr<Node> prpChild)
{
ASSERT(hasObservers());
- RefPtr<Node> child = prpChild;
+ RefPtrWillBeRawPtr<Node> child = prpChild;
if (!m_addedNodes.isEmpty() || !isRemovedNodeInOrder(child.get()))
enqueueMutationRecord();
@@ -125,11 +136,11 @@ void ChildListMutationAccumulator::enqueueMutationRecord()
ASSERT(hasObservers());
ASSERT(!isEmpty());
- RefPtr<NodeList> addedNodes = StaticNodeList::adopt(m_addedNodes);
- RefPtr<NodeList> removedNodes = StaticNodeList::adopt(m_removedNodes);
- RefPtr<MutationRecord> record = MutationRecord::createChildList(m_target, addedNodes.release(), removedNodes.release(), m_previousSibling.release(), m_nextSibling.release());
+ RefPtrWillBeRawPtr<StaticNodeList> addedNodes = StaticNodeList::adopt(m_addedNodes);
+ RefPtrWillBeRawPtr<StaticNodeList> removedNodes = StaticNodeList::adopt(m_removedNodes);
+ RefPtrWillBeRawPtr<MutationRecord> record = MutationRecord::createChildList(m_target, addedNodes.release(), removedNodes.release(), m_previousSibling.release(), m_nextSibling.release());
m_observers->enqueueMutationRecord(record.release());
- m_lastAdded = 0;
+ m_lastAdded = nullptr;
ASSERT(isEmpty());
}
@@ -146,4 +157,15 @@ bool ChildListMutationAccumulator::isEmpty()
return result;
}
+void ChildListMutationAccumulator::trace(Visitor* visitor)
+{
+ visitor->trace(m_target);
+ visitor->trace(m_removedNodes);
+ visitor->trace(m_addedNodes);
+ visitor->trace(m_previousSibling);
+ visitor->trace(m_nextSibling);
+ visitor->trace(m_lastAdded);
+ visitor->trace(m_observers);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h
index d847d826a6d..b232335f4d0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h
@@ -34,6 +34,7 @@
#include "core/dom/Document.h"
#include "core/dom/MutationObserver.h"
#include "core/dom/Node.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/RefCounted.h"
@@ -43,58 +44,85 @@ namespace WebCore {
class MutationObserverInterestGroup;
// ChildListMutationAccumulator is not meant to be used directly; ChildListMutationScope is the public interface.
-class ChildListMutationAccumulator : public RefCounted<ChildListMutationAccumulator> {
+//
+// One ChildListMutationAccumulator for a given Node is shared between all the
+// active ChildListMutationScopes for that Node. Once the last ChildListMutationScope
+// is destructed the accumulator enqueues a mutation record for the recorded
+// mutations and the accumulator can be garbage collected.
+class ChildListMutationAccumulator FINAL : public RefCountedWillBeGarbageCollected<ChildListMutationAccumulator> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ChildListMutationAccumulator);
public:
- static PassRefPtr<ChildListMutationAccumulator> getOrCreate(Node&);
- ~ChildListMutationAccumulator();
+ static PassRefPtrWillBeRawPtr<ChildListMutationAccumulator> getOrCreate(Node&);
- void childAdded(PassRefPtr<Node>);
- void willRemoveChild(PassRefPtr<Node>);
+ void childAdded(PassRefPtrWillBeRawPtr<Node>);
+ void willRemoveChild(PassRefPtrWillBeRawPtr<Node>);
bool hasObservers() const { return m_observers; }
+ // Register and unregister mutation scopes that are using this mutation
+ // accumulator.
+ void enterMutationScope() { m_mutationScopes++; }
+ void leaveMutationScope();
+
+ void trace(Visitor*);
+
private:
- ChildListMutationAccumulator(PassRefPtr<Node>, PassOwnPtr<MutationObserverInterestGroup>);
+ ChildListMutationAccumulator(PassRefPtrWillBeRawPtr<Node>, PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup>);
void enqueueMutationRecord();
bool isEmpty();
bool isAddedNodeInOrder(Node*);
bool isRemovedNodeInOrder(Node*);
- RefPtr<Node> m_target;
+ RefPtrWillBeMember<Node> m_target;
+
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_removedNodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_addedNodes;
+ RefPtrWillBeMember<Node> m_previousSibling;
+ RefPtrWillBeMember<Node> m_nextSibling;
+ RawPtrWillBeMember<Node> m_lastAdded;
- Vector<RefPtr<Node> > m_removedNodes;
- Vector<RefPtr<Node> > m_addedNodes;
- RefPtr<Node> m_previousSibling;
- RefPtr<Node> m_nextSibling;
- Node* m_lastAdded;
+ OwnPtrWillBeMember<MutationObserverInterestGroup> m_observers;
- OwnPtr<MutationObserverInterestGroup> m_observers;
+ unsigned m_mutationScopes;
};
-class ChildListMutationScope {
+class ChildListMutationScope FINAL {
WTF_MAKE_NONCOPYABLE(ChildListMutationScope);
+ STACK_ALLOCATED();
public:
explicit ChildListMutationScope(Node& target)
{
- if (target.document().hasMutationObserversOfType(MutationObserver::ChildList))
+ if (target.document().hasMutationObserversOfType(MutationObserver::ChildList)) {
m_accumulator = ChildListMutationAccumulator::getOrCreate(target);
+ // Register another user of the accumulator.
+ m_accumulator->enterMutationScope();
+ }
+ }
+
+ ~ChildListMutationScope()
+ {
+ if (m_accumulator) {
+ // Unregister a user of the accumulator. If this is the last user
+ // the accumulator will enqueue a mutation record for the mutations.
+ m_accumulator->leaveMutationScope();
+ }
}
void childAdded(Node& child)
{
if (m_accumulator && m_accumulator->hasObservers())
- m_accumulator->childAdded(PassRefPtr<Node>(child));
+ m_accumulator->childAdded(&child);
}
void willRemoveChild(Node& child)
{
if (m_accumulator && m_accumulator->hasObservers())
- m_accumulator->willRemoveChild(PassRefPtr<Node>(child));
+ m_accumulator->willRemoveChild(&child);
}
private:
- RefPtr<ChildListMutationAccumulator> m_accumulator;
+ RefPtrWillBeMember<ChildListMutationAccumulator> m_accumulator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNode.h b/chromium/third_party/WebKit/Source/core/dom/ChildNode.h
new file mode 100644
index 00000000000..19bcc5a602f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNode.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ChildNode_h
+#define ChildNode_h
+
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/Node.h"
+
+namespace WebCore {
+
+class ChildNode {
+public:
+ static Element* previousElementSibling(Node& node)
+ {
+ return ElementTraversal::previousSibling(node);
+ }
+
+ static Element* nextElementSibling(Node& node)
+ {
+ return ElementTraversal::nextSibling(node);
+ }
+
+ static void remove(Node& node, ExceptionState& exceptionState)
+ {
+ return node.remove(exceptionState);
+ }
+};
+
+} // namespace WebCore
+
+#endif // ChildNode_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl b/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl
index 21441f63506..38ccf66bd57 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl
@@ -20,12 +20,13 @@
* Boston, MA 02110-1301, USA.
*/
+// http://dom.spec.whatwg.org/#interface-childnode
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface ChildNode {
[PerWorldBindings] readonly attribute Element previousElementSibling;
[PerWorldBindings] readonly attribute Element nextElementSibling;
[RaisesException, CustomElementCallbacks] void remove();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp
index 4144c04cbe5..c1a895cb932 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp
@@ -1,8 +1,9 @@
-/**
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,21 +29,50 @@
namespace WebCore {
-ChildNodeList::ChildNodeList(PassRefPtr<Node> node)
- : LiveNodeList(node, ChildNodeListType, DoNotInvalidateOnAttributeChanges)
+ChildNodeList::ChildNodeList(ContainerNode& parent)
+ : m_parent(parent)
{
}
+Node* ChildNodeList::virtualOwnerNode() const
+{
+ return &ownerNode();
+}
+
ChildNodeList::~ChildNodeList()
{
- ownerNode()->nodeLists()->removeChildNodeList(this);
+#if !ENABLE(OILPAN)
+ m_parent->nodeLists()->removeChildNodeList(this);
+#endif
+}
+
+Node* ChildNodeList::traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const
+{
+ ASSERT(currentOffset < offset);
+ Node* next = &currentNode;
+ while ((next = next->nextSibling())) {
+ if (++currentOffset == offset)
+ return next;
+ }
+ return 0;
+}
+
+Node* ChildNodeList::traverseBackwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const
+{
+ ASSERT(currentOffset > offset);
+ Node* previous = &currentNode;
+ while ((previous = previous->previousSibling())) {
+ if (--currentOffset == offset)
+ return previous;
+ }
+ return 0;
}
-bool ChildNodeList::nodeMatches(Element* testNode) const
+void ChildNodeList::trace(Visitor* visitor)
{
- // This function will be called only by LiveNodeList::namedItem,
- // for an element that was located with getElementById.
- return testNode->parentNode() == rootNode();
+ visitor->trace(m_parent);
+ visitor->trace(m_collectionIndexCache);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h
index 46f5beab4b1..d3a871246cd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h
@@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,26 +25,52 @@
#ifndef ChildNodeList_h
#define ChildNodeList_h
-#include "core/dom/LiveNodeList.h"
+#include "core/dom/NodeList.h"
+#include "core/html/CollectionIndexCache.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class ChildNodeList FINAL : public LiveNodeList {
+class ChildNodeList FINAL : public NodeList {
public:
- static PassRefPtr<ChildNodeList> create(PassRefPtr<Node> rootNode)
+ static PassRefPtrWillBeRawPtr<ChildNodeList> create(ContainerNode& rootNode)
{
- return adoptRef(new ChildNodeList(rootNode));
+ return adoptRefWillBeNoop(new ChildNodeList(rootNode));
}
virtual ~ChildNodeList();
-protected:
- explicit ChildNodeList(PassRefPtr<Node> rootNode);
+ // DOM API.
+ virtual unsigned length() const OVERRIDE { return m_collectionIndexCache.nodeCount(*this); }
+ virtual Node* item(unsigned index) const OVERRIDE { return m_collectionIndexCache.nodeAt(*this, index); }
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ // Non-DOM API.
+ void invalidateCache() { m_collectionIndexCache.invalidate(); }
+ ContainerNode& ownerNode() const { return *m_parent; }
+
+ ContainerNode& rootNode() const { return ownerNode(); }
+
+ // CollectionIndexCache API.
+ bool canTraverseBackward() const { return true; }
+ Node* traverseToFirstElement() const { return rootNode().firstChild(); }
+ Node* traverseToLastElement() const { return rootNode().lastChild(); }
+ Node* traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const;
+ Node* traverseBackwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit ChildNodeList(ContainerNode& rootNode);
+
+ virtual bool isChildNodeList() const OVERRIDE { return true; }
+ virtual Node* virtualOwnerNode() const OVERRIDE;
+
+ RefPtrWillBeMember<ContainerNode> m_parent;
+ mutable CollectionIndexCache<ChildNodeList, Node> m_collectionIndexCache;
};
+DEFINE_TYPE_CASTS(ChildNodeList, NodeList, nodeList, nodeList->isChildNodeList(), nodeList.isChildNodeList());
+
} // namespace WebCore
#endif // ChildNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp
index 8b362182679..04e2bdcb920 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp
@@ -28,28 +28,25 @@
*/
#include "config.h"
-#include "core/dom/ClassNodeList.h"
+#include "core/dom/ClassCollection.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRareData.h"
namespace WebCore {
-ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames)
- : LiveNodeList(rootNode, ClassNodeListType, InvalidateOnClassAttrChange)
+ClassCollection::ClassCollection(ContainerNode& rootNode, const AtomicString& classNames)
+ : HTMLCollection(rootNode, ClassCollectionType, DoesNotOverrideItemAfter)
, m_classNames(classNames, document().inQuirksMode())
, m_originalClassNames(classNames)
{
}
-ClassNodeList::~ClassNodeList()
+ClassCollection::~ClassCollection()
{
- ownerNode()->nodeLists()->removeCacheWithName(this, ClassNodeListType, m_originalClassNames);
-}
-
-bool ClassNodeList::nodeMatches(Element* testNode) const
-{
- return nodeMatchesInlined(testNode);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, ClassCollectionType, m_originalClassNames);
+#endif
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.h
index 2e08ea81928..d9ddd3b3e17 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.h
@@ -27,49 +27,51 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ClassNodeList_h
-#define ClassNodeList_h
+#ifndef ClassCollection_h
+#define ClassCollection_h
#include "core/dom/Element.h"
-#include "core/dom/LiveNodeList.h"
-#include "core/dom/Node.h"
#include "core/dom/SpaceSplitString.h"
+#include "core/html/HTMLCollection.h"
namespace WebCore {
-class ClassNodeList FINAL : public LiveNodeList {
+class ClassCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<ClassNodeList> create(PassRefPtr<Node> rootNode, const String& classNames)
+ // classNames argument is an AtomicString because it is common for Elements to share the same class names.
+ // It is also used to construct a SpaceSplitString (m_classNames) and its constructor requires an AtomicString.
+ static PassRefPtrWillBeRawPtr<ClassCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& classNames)
{
- return adoptRef(new ClassNodeList(rootNode, classNames));
+ ASSERT_UNUSED(type, type == ClassCollectionType);
+ return adoptRefWillBeNoop(new ClassCollection(rootNode, classNames));
}
- virtual ~ClassNodeList();
+ virtual ~ClassCollection();
- bool nodeMatchesInlined(Element*) const;
+ bool elementMatches(const Element&) const;
private:
- ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames);
-
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ ClassCollection(ContainerNode& rootNode, const AtomicString& classNames);
SpaceSplitString m_classNames;
- String m_originalClassNames;
+ AtomicString m_originalClassNames;
};
-inline bool ClassNodeList::nodeMatchesInlined(Element* testNode) const
+DEFINE_TYPE_CASTS(ClassCollection, LiveNodeListBase, collection, collection->type() == ClassCollectionType, collection.type() == ClassCollectionType);
+
+inline bool ClassCollection::elementMatches(const Element& testElement) const
{
- if (!testNode->hasClass())
+ if (!testElement.hasClass())
return false;
if (!m_classNames.size())
return false;
// FIXME: DOM4 allows getElementsByClassName to return non StyledElement.
// https://bugs.webkit.org/show_bug.cgi?id=94718
- if (!testNode->isStyledElement())
+ if (!testElement.isStyledElement())
return false;
- return testNode->classNames().containsAll(m_classNames);
+ return testElement.classNames().containsAll(m_classNames);
}
} // namespace WebCore
-#endif // ClassNodeList_h
+#endif // ClassCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRect.h b/chromium/third_party/WebKit/Source/core/dom/ClientRect.h
index 3ef3b24f3b4..2fdaeab14dd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRect.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRect.h
@@ -29,33 +29,45 @@
#include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/FloatRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
- class IntRect;
+class IntRect;
- class ClientRect : public ScriptWrappable, public RefCounted<ClientRect> {
- public:
- static PassRefPtr<ClientRect> create() { return adoptRef(new ClientRect); }
- static PassRefPtr<ClientRect> create(const IntRect& rect) { return adoptRef(new ClientRect(rect)); }
- static PassRefPtr<ClientRect> create(const FloatRect& rect) { return adoptRef(new ClientRect(rect)); }
+class ClientRect FINAL : public RefCountedWillBeGarbageCollectedFinalized<ClientRect>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<ClientRect> create()
+ {
+ return adoptRefWillBeNoop(new ClientRect);
+ }
+ static PassRefPtrWillBeRawPtr<ClientRect> create(const IntRect& rect)
+ {
+ return adoptRefWillBeNoop(new ClientRect(rect));
+ }
+ static PassRefPtrWillBeRawPtr<ClientRect> create(const FloatRect& rect)
+ {
+ return adoptRefWillBeNoop(new ClientRect(rect));
+ }
- float top() const { return m_rect.y(); }
- float right() const { return m_rect.maxX(); }
- float bottom() const { return m_rect.maxY(); }
- float left() const { return m_rect.x(); }
- float width() const { return m_rect.width(); }
- float height() const { return m_rect.height(); }
+ float top() const { return m_rect.y(); }
+ float right() const { return m_rect.maxX(); }
+ float bottom() const { return m_rect.maxY(); }
+ float left() const { return m_rect.x(); }
+ float width() const { return m_rect.width(); }
+ float height() const { return m_rect.height(); }
- private:
- ClientRect();
- explicit ClientRect(const IntRect&);
- explicit ClientRect(const FloatRect&);
+ void trace(Visitor*) { }
- FloatRect m_rect;
- };
+private:
+ ClientRect();
+ explicit ClientRect(const IntRect&);
+ explicit ClientRect(const FloatRect&);
+
+ FloatRect m_rect;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl b/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl
index ffdcfdddeb3..4fae5d7f938 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl
@@ -25,6 +25,7 @@
*/
[
+ WillBeGarbageCollected,
] interface ClientRect {
readonly attribute float top;
readonly attribute float right;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp
index c7d054c1594..78288826534 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp
@@ -64,4 +64,9 @@ ClientRect* ClientRectList::item(unsigned index)
return m_list[index].get();
}
+void ClientRectList::trace(Visitor* visitor)
+{
+ visitor->trace(m_list);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h
index 0639714f74e..789ca22c712 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h
@@ -29,6 +29,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/FloatQuad.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -37,20 +38,28 @@ namespace WebCore {
class ClientRect;
-class ClientRectList : public RefCounted<ClientRectList>, public ScriptWrappable {
+class ClientRectList FINAL : public RefCountedWillBeGarbageCollectedFinalized<ClientRectList>, public ScriptWrappable {
public:
- static PassRefPtr<ClientRectList> create() { return adoptRef(new ClientRectList); }
- static PassRefPtr<ClientRectList> create(const Vector<FloatQuad>& quads) { return adoptRef(new ClientRectList(quads)); }
+ static PassRefPtrWillBeRawPtr<ClientRectList> create()
+ {
+ return adoptRefWillBeNoop(new ClientRectList);
+ }
+ static PassRefPtrWillBeRawPtr<ClientRectList> create(const Vector<FloatQuad>& quads)
+ {
+ return adoptRefWillBeNoop(new ClientRectList(quads));
+ }
~ClientRectList();
unsigned length() const;
ClientRect* item(unsigned index);
+ void trace(Visitor*);
+
private:
ClientRectList();
explicit ClientRectList(const Vector<FloatQuad>&);
- Vector<RefPtr<ClientRect> > m_list;
+ WillBeHeapVector<RefPtrWillBeMember<ClientRect> > m_list;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl
index 7f6b1988c79..bf1454225c6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl
@@ -25,6 +25,7 @@
*/
[
+ WillBeGarbageCollected,
] interface ClientRectList {
readonly attribute unsigned long length;
getter ClientRect item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp b/chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp
deleted file mode 100644
index 4a16d84f8ef..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/Clipboard.h"
-
-#include "HTMLNames.h"
-#include "core/dom/DataTransferItem.h"
-#include "core/dom/DataTransferItemList.h"
-#include "core/editing/markup.h"
-#include "core/fetch/ImageResource.h"
-#include "core/fileapi/FileList.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/frame/Frame.h"
-#include "core/platform/DragImage.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
-#include "core/rendering/RenderImage.h"
-#include "core/rendering/RenderObject.h"
-#include "platform/MIMETypeRegistry.h"
-#include "platform/clipboard/ClipboardMimeTypes.h"
-#include "platform/clipboard/ClipboardUtilities.h"
-
-namespace WebCore {
-
-// These "conversion" methods are called by both WebCore and WebKit, and never make sense to JS, so we don't
-// worry about security for these. They don't allow access to the pasteboard anyway.
-static DragOperation dragOpFromIEOp(const String& op)
-{
- // yep, it's really just this fixed set
- if (op == "uninitialized")
- return DragOperationEvery;
- if (op == "none")
- return DragOperationNone;
- if (op == "copy")
- return DragOperationCopy;
- if (op == "link")
- return DragOperationLink;
- if (op == "move")
- return (DragOperation)(DragOperationGeneric | DragOperationMove);
- if (op == "copyLink")
- return (DragOperation)(DragOperationCopy | DragOperationLink);
- if (op == "copyMove")
- return (DragOperation)(DragOperationCopy | DragOperationGeneric | DragOperationMove);
- if (op == "linkMove")
- return (DragOperation)(DragOperationLink | DragOperationGeneric | DragOperationMove);
- if (op == "all")
- return DragOperationEvery;
- return DragOperationPrivate; // really a marker for "no conversion"
-}
-
-static String IEOpFromDragOp(DragOperation op)
-{
- bool moveSet = !!((DragOperationGeneric | DragOperationMove) & op);
-
- if ((moveSet && (op & DragOperationCopy) && (op & DragOperationLink))
- || (op == DragOperationEvery))
- return "all";
- if (moveSet && (op & DragOperationCopy))
- return "copyMove";
- if (moveSet && (op & DragOperationLink))
- return "linkMove";
- if ((op & DragOperationCopy) && (op & DragOperationLink))
- return "copyLink";
- if (moveSet)
- return "move";
- if (op & DragOperationCopy)
- return "copy";
- if (op & DragOperationLink)
- return "link";
- return "none";
-}
-
-// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
-// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
-static String normalizeType(const String& type, bool* convertToURL = 0)
-{
- String cleanType = type.stripWhiteSpace().lower();
- if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
- return mimeTypeTextPlain;
- if (cleanType == mimeTypeURL) {
- if (convertToURL)
- *convertToURL = true;
- return mimeTypeTextURIList;
- }
- return cleanType;
-}
-
-PassRefPtr<Clipboard> Clipboard::create(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtr<ChromiumDataObject> dataObject)
-{
- return adoptRef(new Clipboard(type, policy , dataObject));
-}
-
-Clipboard::~Clipboard()
-{
-}
-
-void Clipboard::setDropEffect(const String &effect)
-{
- if (!isForDragAndDrop())
- return;
-
- // The attribute must ignore any attempts to set it to a value other than none, copy, link, and move.
- if (effect != "none" && effect != "copy" && effect != "link" && effect != "move")
- return;
-
- // FIXME: The spec actually allows this in all circumstances, even though there's no point in
- // setting the drop effect when this condition is not true.
- if (canReadTypes())
- m_dropEffect = effect;
-}
-
-void Clipboard::setEffectAllowed(const String &effect)
-{
- if (!isForDragAndDrop())
- return;
-
- if (dragOpFromIEOp(effect) == DragOperationPrivate) {
- // This means that there was no conversion, and the effectAllowed that
- // we are passed isn't a valid effectAllowed, so we should ignore it,
- // and not set m_effectAllowed.
-
- // The attribute must ignore any attempts to set it to a value other than
- // none, copy, copyLink, copyMove, link, linkMove, move, all, and uninitialized.
- return;
- }
-
-
- if (canWriteData())
- m_effectAllowed = effect;
-}
-
-void Clipboard::clearData(const String& type)
-{
- if (!canWriteData())
- return;
-
- if (type.isNull())
- m_dataObject->clearAll();
- else
- m_dataObject->clearData(normalizeType(type));
-}
-
-String Clipboard::getData(const String& type) const
-{
- if (!canReadData())
- return String();
-
- bool convertToURL = false;
- String data = m_dataObject->getData(normalizeType(type, &convertToURL));
- if (!convertToURL)
- return data;
- return convertURIListToURL(data);
-}
-
-bool Clipboard::setData(const String& type, const String& data)
-{
- if (!canWriteData())
- return false;
-
- return m_dataObject->setData(normalizeType(type), data);
-}
-
-// extensions beyond IE's API
-Vector<String> Clipboard::types() const
-{
- Vector<String> types;
- if (!canReadTypes())
- return types;
-
- ListHashSet<String> typesSet = m_dataObject->types();
- types.appendRange(typesSet.begin(), typesSet.end());
- return types;
-}
-
-PassRefPtr<FileList> Clipboard::files() const
-{
- RefPtr<FileList> files = FileList::create();
- if (!canReadData())
- return files.release();
-
- for (size_t i = 0; i < m_dataObject->length(); ++i) {
- if (m_dataObject->item(i)->kind() == ChromiumDataObjectItem::FileKind) {
- RefPtr<Blob> blob = m_dataObject->item(i)->getAsFile();
- if (blob && blob->isFile())
- files->append(toFile(blob.get()));
- }
- }
-
- return files.release();
-}
-
-void Clipboard::setDragImage(Element* image, int x, int y, ExceptionState& exceptionState)
-{
- if (!isForDragAndDrop())
- return;
-
- if (!image) {
- exceptionState.throwTypeError("setDragImage: Invalid first argument");
- return;
- }
- IntPoint location(x, y);
- if (image->hasTagName(HTMLNames::imgTag) && !image->inDocument())
- setDragImageResource(toHTMLImageElement(image)->cachedImage(), location);
- else
- setDragImageElement(image, location);
-}
-
-void Clipboard::setDragImageResource(ImageResource* img, const IntPoint& loc)
-{
- setDragImage(img, 0, loc);
-}
-
-void Clipboard::setDragImageElement(Node* node, const IntPoint& loc)
-{
- setDragImage(0, node, loc);
-}
-
-PassOwnPtr<DragImage> Clipboard::createDragImage(IntPoint& loc, Frame* frame) const
-{
- if (m_dragImageElement) {
- loc = m_dragLoc;
- return frame->nodeImage(m_dragImageElement.get());
- }
- if (m_dragImage) {
- loc = m_dragLoc;
- return DragImage::create(m_dragImage->image());
- }
- return nullptr;
-}
-
-static ImageResource* getImageResource(Element* element)
-{
- // Attempt to pull ImageResource from element
- ASSERT(element);
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isImage())
- return 0;
-
- RenderImage* image = toRenderImage(renderer);
- if (image->cachedImage() && !image->cachedImage()->errorOccurred())
- return image->cachedImage();
-
- return 0;
-}
-
-static void writeImageToDataObject(ChromiumDataObject* dataObject, Element* element, const KURL& url)
-{
- // Shove image data into a DataObject for use as a file
- ImageResource* cachedImage = getImageResource(element);
- if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded())
- return;
-
- SharedBuffer* imageBuffer = cachedImage->imageForRenderer(element->renderer())->data();
- if (!imageBuffer || !imageBuffer->size())
- return;
-
- String imageExtension = cachedImage->image()->filenameExtension();
- ASSERT(!imageExtension.isEmpty());
-
- // Determine the filename for the file contents of the image.
- String filename = cachedImage->response().suggestedFilename();
- if (filename.isEmpty())
- filename = url.lastPathComponent();
-
- String fileExtension;
- if (filename.isEmpty()) {
- filename = element->getAttribute(HTMLNames::altAttr);
- } else {
- // Strip any existing extension. Assume that alt text is usually not a filename.
- int extensionIndex = filename.reverseFind('.');
- if (extensionIndex != -1) {
- fileExtension = filename.substring(extensionIndex + 1);
- filename.truncate(extensionIndex);
- }
- }
-
- if (!fileExtension.isEmpty() && fileExtension != imageExtension) {
- String imageMimeType = MIMETypeRegistry::getMIMETypeForExtension(imageExtension);
- ASSERT(imageMimeType.startsWith("image/"));
- // Use the file extension only if it has imageMimeType: it's untrustworthy otherwise.
- if (imageMimeType == MIMETypeRegistry::getMIMETypeForExtension(fileExtension))
- imageExtension = fileExtension;
- }
-
- imageExtension = "." + imageExtension;
- validateFilename(filename, imageExtension);
-
- dataObject->addSharedBuffer(filename + imageExtension, imageBuffer);
-}
-
-void Clipboard::declareAndWriteDragImage(Element* element, const KURL& url, const String& title)
-{
- if (!m_dataObject)
- return;
-
- m_dataObject->setURLAndTitle(url, title);
-
- // Write the bytes in the image to the file format.
- writeImageToDataObject(m_dataObject.get(), element, url);
-
- // Put img tag on the clipboard referencing the image
- m_dataObject->setData(mimeTypeTextHTML, createMarkup(element, IncludeNode, 0, ResolveAllURLs));
-}
-
-void Clipboard::writeURL(const KURL& url, const String& title)
-{
- if (!m_dataObject)
- return;
- ASSERT(!url.isEmpty());
-
- m_dataObject->setURLAndTitle(url, title);
-
- // The URL can also be used as plain text.
- m_dataObject->setData(mimeTypeTextPlain, url.string());
-
- // The URL can also be used as an HTML fragment.
- m_dataObject->setHTMLAndBaseURL(urlToMarkup(url, title), url);
-}
-
-void Clipboard::writeRange(Range* selectedRange, Frame* frame)
-{
- ASSERT(selectedRange);
- if (!m_dataObject)
- return;
-
- m_dataObject->setHTMLAndBaseURL(createMarkup(selectedRange, 0, AnnotateForInterchange, false, ResolveNonLocalURLs), frame->document()->url());
-
- String str = frame->selectedTextForClipboard();
-#if OS(WIN)
- replaceNewlinesWithWindowsStyleNewlines(str);
-#endif
- replaceNBSPWithSpace(str);
- m_dataObject->setData(mimeTypeTextPlain, str);
-}
-
-void Clipboard::writePlainText(const String& text)
-{
- if (!m_dataObject)
- return;
-
- String str = text;
-#if OS(WIN)
- replaceNewlinesWithWindowsStyleNewlines(str);
-#endif
- replaceNBSPWithSpace(str);
-
- m_dataObject->setData(mimeTypeTextPlain, str);
-}
-
-bool Clipboard::hasData()
-{
- ASSERT(isForDragAndDrop());
-
- return m_dataObject->length() > 0;
-}
-
-void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
-{
- // once you go numb, can never go back
- ASSERT(m_policy != ClipboardNumb || policy == ClipboardNumb);
- m_policy = policy;
-}
-
-bool Clipboard::canReadTypes() const
-{
- return m_policy == ClipboardReadable || m_policy == ClipboardTypesReadable || m_policy == ClipboardWritable;
-}
-
-bool Clipboard::canReadData() const
-{
- return m_policy == ClipboardReadable || m_policy == ClipboardWritable;
-}
-
-bool Clipboard::canWriteData() const
-{
- return m_policy == ClipboardWritable;
-}
-
-bool Clipboard::canSetDragImage() const
-{
- return m_policy == ClipboardImageWritable || m_policy == ClipboardWritable;
-}
-
-DragOperation Clipboard::sourceOperation() const
-{
- DragOperation op = dragOpFromIEOp(m_effectAllowed);
- ASSERT(op != DragOperationPrivate);
- return op;
-}
-
-DragOperation Clipboard::destinationOperation() const
-{
- DragOperation op = dragOpFromIEOp(m_dropEffect);
- ASSERT(op == DragOperationCopy || op == DragOperationNone || op == DragOperationLink || op == (DragOperation)(DragOperationGeneric | DragOperationMove) || op == DragOperationEvery);
- return op;
-}
-
-void Clipboard::setSourceOperation(DragOperation op)
-{
- ASSERT_ARG(op, op != DragOperationPrivate);
- m_effectAllowed = IEOpFromDragOp(op);
-}
-
-void Clipboard::setDestinationOperation(DragOperation op)
-{
- ASSERT_ARG(op, op == DragOperationCopy || op == DragOperationNone || op == DragOperationLink || op == DragOperationGeneric || op == DragOperationMove || op == (DragOperation)(DragOperationGeneric | DragOperationMove));
- m_dropEffect = IEOpFromDragOp(op);
-}
-
-bool Clipboard::hasDropZoneType(const String& keyword)
-{
- if (keyword.startsWith("file:"))
- return hasFileOfType(keyword.substring(5));
-
- if (keyword.startsWith("string:"))
- return hasStringOfType(keyword.substring(7));
-
- return false;
-}
-
-PassRefPtr<DataTransferItemList> Clipboard::items()
-{
- // FIXME: According to the spec, we are supposed to return the same collection of items each
- // time. We now return a wrapper that always wraps the *same* set of items, so JS shouldn't be
- // able to tell, but we probably still want to fix this.
- return DataTransferItemList::create(this, m_dataObject);
-}
-
-PassRefPtr<ChromiumDataObject> Clipboard::dataObject() const
-{
- return m_dataObject;
-}
-
-Clipboard::Clipboard(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtr<ChromiumDataObject> dataObject)
- : m_policy(policy)
- , m_dropEffect("uninitialized")
- , m_effectAllowed("uninitialized")
- , m_clipboardType(type)
- , m_dataObject(dataObject)
-{
- ScriptWrappable::init(this);
-}
-
-void Clipboard::setDragImage(ImageResource* image, Node* node, const IntPoint& loc)
-{
- if (!canSetDragImage())
- return;
-
- m_dragImage = image;
- m_dragLoc = loc;
- m_dragImageElement = node;
-}
-
-bool Clipboard::hasFileOfType(const String& type) const
-{
- if (!canReadTypes())
- return false;
-
- RefPtr<FileList> fileList = files();
- if (fileList->isEmpty())
- return false;
-
- for (unsigned f = 0; f < fileList->length(); f++) {
- if (equalIgnoringCase(fileList->item(f)->type(), type))
- return true;
- }
- return false;
-}
-
-bool Clipboard::hasStringOfType(const String& type) const
-{
- if (!canReadTypes())
- return false;
-
- return types().contains(type);
-}
-
-DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
-{
- if (dragOperation == "copy")
- return DragOperationCopy;
- if (dragOperation == "move")
- return DragOperationMove;
- if (dragOperation == "link")
- return DragOperationLink;
- return DragOperationNone;
-}
-
-String convertDragOperationToDropZoneOperation(DragOperation operation)
-{
- switch (operation) {
- case DragOperationCopy:
- return String("copy");
- case DragOperationMove:
- return String("move");
- case DragOperationLink:
- return String("link");
- default:
- return String("copy");
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Clipboard.h b/chromium/third_party/WebKit/Source/core/dom/Clipboard.h
deleted file mode 100644
index dfe22710e76..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Clipboard.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Clipboard_h
-#define Clipboard_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/ClipboardAccessPolicy.h"
-#include "core/fetch/ResourcePtr.h"
-#include "core/page/DragActions.h"
-#include "platform/geometry/IntPoint.h"
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class ChromiumDataObject;
-class DataTransferItemList;
-class DragImage;
-class Element;
-class ExceptionState;
-class FileList;
-class Frame;
-class ImageResource;
-class Node;
-class Range;
-
-// State available during IE's events for drag and drop and copy/paste
-class Clipboard : public RefCounted<Clipboard>, public ScriptWrappable {
-public:
- // Whether this clipboard is serving a drag-drop or copy-paste request.
- enum ClipboardType {
- CopyAndPaste,
- DragAndDrop,
- };
-
- static PassRefPtr<Clipboard> create(ClipboardType, ClipboardAccessPolicy, PassRefPtr<ChromiumDataObject>);
- ~Clipboard();
-
- bool isForCopyAndPaste() const { return m_clipboardType == CopyAndPaste; }
- bool isForDragAndDrop() const { return m_clipboardType == DragAndDrop; }
-
- String dropEffect() const { return dropEffectIsUninitialized() ? "none" : m_dropEffect; }
- void setDropEffect(const String&);
- bool dropEffectIsUninitialized() const { return m_dropEffect == "uninitialized"; }
- String effectAllowed() const { return m_effectAllowed; }
- void setEffectAllowed(const String&);
-
- void clearData(const String& type = String());
- String getData(const String& type) const;
- bool setData(const String& type, const String& data);
-
- // extensions beyond IE's API
- Vector<String> types() const;
- PassRefPtr<FileList> files() const;
-
- IntPoint dragLocation() const { return m_dragLoc; }
- void setDragImage(Element*, int x, int y, ExceptionState&);
- ImageResource* dragImageResource() const { return m_dragImage.get(); }
- void setDragImageResource(ImageResource*, const IntPoint&);
- Node* dragImageElement() const { return m_dragImageElement.get(); }
- void setDragImageElement(Node*, const IntPoint&);
-
- PassOwnPtr<DragImage> createDragImage(IntPoint& dragLocation, Frame*) const;
- void declareAndWriteDragImage(Element*, const KURL&, const String& title);
- void writeURL(const KURL&, const String&);
- void writeRange(Range*, Frame*);
- void writePlainText(const String&);
-
- bool hasData();
-
- void setAccessPolicy(ClipboardAccessPolicy);
- bool canReadTypes() const;
- bool canReadData() const;
- bool canWriteData() const;
- // Note that the spec doesn't actually allow drag image modification outside the dragstart
- // event. This capability is maintained for backwards compatiblity for ports that have
- // supported this in the past. On many ports, attempting to set a drag image outside the
- // dragstart operation is a no-op anyway.
- bool canSetDragImage() const;
-
- DragOperation sourceOperation() const;
- DragOperation destinationOperation() const;
- void setSourceOperation(DragOperation);
- void setDestinationOperation(DragOperation);
-
- bool hasDropZoneType(const String&);
-
- PassRefPtr<DataTransferItemList> items();
-
- PassRefPtr<ChromiumDataObject> dataObject() const;
-
-private:
- Clipboard(ClipboardType, ClipboardAccessPolicy, PassRefPtr<ChromiumDataObject>);
-
- void setDragImage(ImageResource*, Node*, const IntPoint&);
-
- bool hasFileOfType(const String&) const;
- bool hasStringOfType(const String&) const;
-
- // Instead of using this member directly, prefer to use the can*() methods above.
- ClipboardAccessPolicy m_policy;
- String m_dropEffect;
- String m_effectAllowed;
- ClipboardType m_clipboardType;
- RefPtr<ChromiumDataObject> m_dataObject;
-
- IntPoint m_dragLoc;
- ResourcePtr<ImageResource> m_dragImage;
- RefPtr<Node> m_dragImageElement;
-};
-
-DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation);
-String convertDragOperationToDropZoneOperation(DragOperation);
-
-} // namespace WebCore
-
-#endif // Clipboard_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Clipboard.idl b/chromium/third_party/WebKit/Source/core/dom/Clipboard.idl
deleted file mode 100644
index 695f70d4866..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Clipboard.idl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
-] interface Clipboard {
- [TreatReturnedNullStringAs=Undefined] attribute DOMString dropEffect;
- [TreatReturnedNullStringAs=Undefined] attribute DOMString effectAllowed;
- readonly attribute DOMString[] types;
- readonly attribute FileList files;
-
- void clearData(optional DOMString type);
- DOMString getData(DOMString type);
- boolean setData(DOMString type, DOMString data);
- [RaisesException] void setDragImage(Element image, long x, long y);
-
- readonly attribute DataTransferItemList items;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/Comment.cpp b/chromium/third_party/WebKit/Source/core/dom/Comment.cpp
index 90fb91b2ab8..03c5e98a70b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Comment.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Comment.cpp
@@ -32,9 +32,9 @@ inline Comment::Comment(Document& document, const String& text)
ScriptWrappable::init(this);
}
-PassRefPtr<Comment> Comment::create(Document& document, const String& text)
+PassRefPtrWillBeRawPtr<Comment> Comment::create(Document& document, const String& text)
{
- return adoptRef(new Comment(document, text));
+ return adoptRefWillBeNoop(new Comment(document, text));
}
String Comment::nodeName() const
@@ -47,14 +47,9 @@ Node::NodeType Comment::nodeType() const
return COMMENT_NODE;
}
-PassRefPtr<Node> Comment::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> Comment::cloneNode(bool /*deep*/)
{
return create(document(), data());
}
-bool Comment::childTypeAllowed(NodeType) const
-{
- return false;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Comment.h b/chromium/third_party/WebKit/Source/core/dom/Comment.h
index b0625f4be12..fc68b5264ef 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Comment.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Comment.h
@@ -31,15 +31,14 @@ class ExecutionContext;
class Comment FINAL : public CharacterData {
public:
- static PassRefPtr<Comment> create(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<Comment> create(Document&, const String&);
private:
Comment(Document&, const String&);
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
- virtual bool childTypeAllowed(NodeType) const;
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
};
DEFINE_NODE_TYPE_CASTS(Comment, nodeType() == Node::COMMENT_NODE);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Comment.idl b/chromium/third_party/WebKit/Source/core/dom/Comment.idl
index 0297e953064..3af73b24d5b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Comment.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Comment.idl
@@ -18,7 +18,7 @@
*/
[
- Constructor([Default=NullString] optional DOMString data),
+ Constructor(optional DOMString data = null),
ConstructorCallWith=Document,
] interface Comment : CharacterData {
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index ba1ac83c663..18da27a211a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -24,33 +24,41 @@
#include "core/dom/ContainerNode.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ChildFrameDisconnector.h"
#include "core/dom/ChildListMutationScope.h"
+#include "core/dom/ClassCollection.h"
#include "core/dom/ContainerNodeAlgorithms.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
+#include "core/dom/NameNodeList.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeChildRemovalTracker.h"
#include "core/dom/NodeRareData.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/NodeTraversal.h"
+#include "core/dom/ScriptForbiddenScope.h"
+#include "core/dom/SelectorQuery.h"
+#include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/MutationEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/html/HTMLCollection.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/html/RadioNodeList.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidget.h"
-
-using namespace std;
namespace WebCore {
+using namespace HTMLNames;
+
static void dispatchChildInsertionEvents(Node&);
static void dispatchChildRemovalEvents(Node&);
-ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
-
#ifndef NDEBUG
unsigned NoEventDispatchAssertion::s_count = 0;
#endif
@@ -67,19 +75,18 @@ static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes,
toContainerNode(node).removeChildren();
}
+#if !ENABLE(OILPAN)
void ContainerNode::removeDetachedChildren()
{
- if (connectedSubframeCount()) {
- for (Node* child = firstChild(); child; child = child->nextSibling())
- child->updateAncestorConnectedSubframeCountForRemoval();
- }
+ ASSERT(!connectedSubframeCount());
ASSERT(needsAttach());
removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
}
+#endif
void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
{
- while (RefPtr<Node> child = oldParent.firstChild()) {
+ while (RefPtrWillBeRawPtr<Node> child = oldParent.firstChild()) {
oldParent.parserRemoveChild(*child);
treeScope().adoptIfNeeded(*child);
parserAppendChild(child.get());
@@ -88,8 +95,11 @@ void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
ContainerNode::~ContainerNode()
{
+ ASSERT(needsAttach());
+#if !ENABLE(OILPAN)
willBeDeletedFromDocument();
removeDetachedChildren();
+#endif
}
bool ContainerNode::isChildTypeAllowed(const Node& child) const
@@ -97,7 +107,7 @@ bool ContainerNode::isChildTypeAllowed(const Node& child) const
if (!child.isDocumentFragment())
return childTypeAllowed(child.nodeType());
- for (Node* node = child.firstChild(); node; node = node->nextSibling()) {
+ for (Node* node = toDocumentFragment(child).firstChild(); node; node = node->nextSibling()) {
if (!childTypeAllowed(node->nodeType()))
return false;
}
@@ -106,7 +116,7 @@ bool ContainerNode::isChildTypeAllowed(const Node& child) const
bool ContainerNode::containsConsideringHostElements(const Node& newChild) const
{
- if (isInShadowTree() || document() == document().templateDocument())
+ if (isInShadowTree() || document().isTemplateDocument())
return newChild.containsIncludingHostElements(*this);
return newChild.contains(this);
}
@@ -165,13 +175,15 @@ bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, Ex
return true;
}
-void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
+void ContainerNode::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
{
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
// insertBefore(node, 0) is equivalent to appendChild(node)
if (!refChild) {
@@ -193,7 +205,7 @@ void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
return;
- RefPtr<Node> next = refChild;
+ RefPtrWillBeRawPtr<Node> next = refChild;
NodeVector targets;
collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState);
@@ -235,6 +247,7 @@ void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
{
NoEventDispatchAssertion assertNoEventDispatch;
+ ScriptForbiddenScope forbidScript;
ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
ASSERT(!newChild.nextSibling());
@@ -245,11 +258,11 @@ void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
ASSERT(m_lastChild != prev);
nextChild.setPreviousSibling(&newChild);
if (prev) {
- ASSERT(m_firstChild != nextChild);
+ ASSERT(firstChild() != nextChild);
ASSERT(prev->nextSibling() == nextChild);
prev->setNextSibling(&newChild);
} else {
- ASSERT(m_firstChild == nextChild);
+ ASSERT(firstChild() == nextChild);
m_firstChild = &newChild;
}
newChild.setParentOrShadowHostNode(this);
@@ -257,14 +270,28 @@ void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
newChild.setNextSibling(&nextChild);
}
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChild)
+void ContainerNode::appendChildCommon(Node& child)
+{
+ child.setParentOrShadowHostNode(this);
+
+ if (m_lastChild) {
+ child.setPreviousSibling(m_lastChild);
+ m_lastChild->setNextSibling(&child);
+ } else {
+ setFirstChild(&child);
+ }
+
+ setLastChild(&child);
+}
+
+void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node& nextChild)
{
ASSERT(newChild);
ASSERT(nextChild.parentNode() == this);
ASSERT(!newChild->isDocumentFragment());
- ASSERT(!hasTagName(HTMLNames::templateTag));
+ ASSERT(!isHTMLTemplateElement(this));
- if (nextChild.previousSibling() == newChild || nextChild == newChild) // nothing to do
+ if (nextChild.previousSibling() == newChild || &nextChild == newChild) // nothing to do
return;
if (document() != newChild->document())
@@ -278,16 +305,18 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChil
childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
- ChildNodeInsertionNotifier(*this).notify(*newChild);
+ notifyNodeInserted(*newChild);
}
-void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
+void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
{
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
if (oldChild == newChild) // nothing to do
return;
@@ -309,10 +338,11 @@ void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
ChildListMutationScope mutation(*this);
- RefPtr<Node> next = oldChild->nextSibling();
+ RefPtrWillBeRawPtr<Node> next = oldChild->nextSibling();
// Remove the node we're replacing
- RefPtr<Node> removedChild = oldChild;
+ RefPtrWillBeRawPtr<Node> protectRemovedChild = oldChild;
+ ASSERT_UNUSED(protectRemovedChild, protectRemovedChild);
removeChild(oldChild, exceptionState);
if (exceptionState.hadException())
return;
@@ -357,7 +387,7 @@ void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
if (next)
insertBeforeCommon(*next, child);
else
- appendChildToContainer(child, *this);
+ appendChildCommon(child);
}
updateTreeAfterInsertion(child);
@@ -382,7 +412,7 @@ void ContainerNode::willRemoveChildren()
getChildNodes(*this, children);
ChildListMutationScope mutation(*this);
- for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
+ for (NodeVector::const_iterator it = children.begin(); it != children.end(); ++it) {
ASSERT(*it);
Node& child = **it;
mutation.willRemoveChild(child);
@@ -398,25 +428,37 @@ void ContainerNode::disconnectDescendantFrames()
ChildFrameDisconnector(*this).disconnect();
}
+void ContainerNode::trace(Visitor* visitor)
+{
+ visitor->trace(m_firstChild);
+ visitor->trace(m_lastChild);
+ Node::trace(visitor);
+}
+
void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState)
{
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
// NotFoundError: Raised if oldChild is not a child of this node.
- if (!oldChild || oldChild->parentNode() != this) {
+ // FIXME: We should never really get PseudoElements in here, but editing will sometimes
+ // attempt to remove them still. We should fix that and enable this ASSERT.
+ // ASSERT(!oldChild->isPseudoElement())
+ if (!oldChild || oldChild->parentNode() != this || oldChild->isPseudoElement()) {
exceptionState.throwDOMException(NotFoundError, "The node to be removed is not a child of this node.");
return;
}
- RefPtr<Node> child = oldChild;
+ RefPtrWillBeRawPtr<Node> child = oldChild;
document().removeFocusedElementOfSubtree(child.get());
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->removeFullScreenElementOfSubtree(child.get());
// Events fired when blurring currently focused node might have moved this
@@ -435,13 +477,13 @@ void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState)
}
{
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
Node* prev = child->previousSibling();
Node* next = child->nextSibling();
removeBetween(prev, next, *child);
childrenChanged(false, prev, next, -1);
- ChildNodeRemovalNotifier(*this).notify(*child);
+ notifyNodeRemoved(*child);
}
dispatchSubtreeModifiedEvent();
}
@@ -459,9 +501,9 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
nextChild->setPreviousSibling(previousChild);
if (previousChild)
previousChild->setNextSibling(nextChild);
- if (m_firstChild == oldChild)
+ if (m_firstChild == &oldChild)
m_firstChild = nextChild;
- if (m_lastChild == oldChild)
+ if (m_lastChild == &oldChild)
m_lastChild = previousChild;
oldChild.setPreviousSibling(0);
@@ -487,7 +529,7 @@ void ContainerNode::parserRemoveChild(Node& oldChild)
removeBetween(prev, next, oldChild);
childrenChanged(true, prev, next, -1);
- ChildNodeRemovalNotifier(*this).notify(oldChild);
+ notifyNodeRemoved(oldChild);
}
// this differs from other remove functions because it forcibly removes all the children,
@@ -498,9 +540,9 @@ void ContainerNode::removeChildren()
return;
// The container node can be removed from event handlers.
- RefPtr<ContainerNode> protect(this);
+ RefPtrWillBeRawPtr<ContainerNode> protect(this);
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->removeFullScreenElementOfSubtree(this, true);
// Do any prep work needed before actually starting to detach
@@ -519,16 +561,16 @@ void ContainerNode::removeChildren()
document().removeFocusedElementOfSubtree(this, true);
// Removing a node from a selection can cause widget updates.
- document().nodeChildrenWillBeRemoved(this);
+ document().nodeChildrenWillBeRemoved(*this);
}
NodeVector removedChildren;
{
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
{
NoEventDispatchAssertion assertNoEventDispatch;
- removedChildren.reserveInitialCapacity(childNodeCount());
+ removedChildren.reserveInitialCapacity(countChildren());
while (m_firstChild) {
removedChildren.append(m_firstChild);
removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
@@ -538,19 +580,21 @@ void ContainerNode::removeChildren()
childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
for (size_t i = 0; i < removedChildren.size(); ++i)
- ChildNodeRemovalNotifier(*this).notify(*removedChildren[i]);
+ notifyNodeRemoved(*removedChildren[i]);
}
dispatchSubtreeModifiedEvent();
}
-void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& exceptionState)
+void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& exceptionState)
{
- RefPtr<ContainerNode> protect(this);
+ RefPtrWillBeRawPtr<ContainerNode> protect(this);
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
// Make sure adding the new child is ok
if (!checkAcceptChild(newChild.get(), 0, exceptionState))
@@ -586,12 +630,12 @@ void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& excep
if (child.parentNode())
break;
- treeScope().adoptIfNeeded(child);
-
- // Append child to the end of the list
{
NoEventDispatchAssertion assertNoEventDispatch;
- appendChildToContainer(child, *this);
+ ScriptForbiddenScope forbidScript;
+
+ treeScope().adoptIfNeeded(child);
+ appendChildCommon(child);
}
updateTreeAfterInsertion(child);
@@ -600,30 +644,86 @@ void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& excep
dispatchSubtreeModifiedEvent();
}
-void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
+void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild)
{
ASSERT(newChild);
ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
ASSERT(!newChild->isDocumentFragment());
- ASSERT(!hasTagName(HTMLNames::templateTag));
+ ASSERT(!isHTMLTemplateElement(this));
if (document() != newChild->document())
document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
Node* last = m_lastChild;
+
{
NoEventDispatchAssertion assertNoEventDispatch;
- // FIXME: This method should take a PassRefPtr.
- appendChildToContainer(*newChild, *this);
+ ScriptForbiddenScope forbidScript;
+
treeScope().adoptIfNeeded(*newChild);
+ appendChildCommon(*newChild);
+ newChild->updateAncestorConnectedSubframeCountForInsertion();
+ ChildListMutationScope(*this).childAdded(*newChild);
}
- newChild->updateAncestorConnectedSubframeCountForInsertion();
+ childrenChanged(true, last, 0, 1);
+ notifyNodeInserted(*newChild);
+}
- ChildListMutationScope(*this).childAdded(*newChild);
+void ContainerNode::notifyNodeInserted(Node& root)
+{
+ ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- childrenChanged(true, last, 0, 1);
- ChildNodeInsertionNotifier(*this).notify(*newChild);
+ InspectorInstrumentation::didInsertDOMNode(&root);
+
+ RefPtrWillBeRawPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protectNode(root);
+
+ NodeVector postInsertionNotificationTargets;
+ notifyNodeInsertedInternal(root, postInsertionNotificationTargets);
+
+ for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) {
+ Node* targetNode = postInsertionNotificationTargets[i].get();
+ if (targetNode->inDocument())
+ targetNode->didNotifySubtreeInsertionsToDocument();
+ }
+}
+
+void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInsertionNotificationTargets)
+{
+ NoEventDispatchAssertion assertNoEventDispatch;
+ ScriptForbiddenScope forbidScript;
+
+ for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+ // As an optimization we don't notify leaf nodes when when inserting
+ // into detached subtrees.
+ if (!inDocument() && !node->isContainerNode())
+ continue;
+ if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node->insertedInto(this))
+ postInsertionNotificationTargets.append(node);
+ for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
+ notifyNodeInsertedInternal(*shadowRoot, postInsertionNotificationTargets);
+ }
+}
+
+void ContainerNode::notifyNodeRemoved(Node& root)
+{
+ ScriptForbiddenScope forbidScript;
+ NoEventDispatchAssertion assertNoEventDispatch;
+
+ Document& document = root.document();
+ for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+ // As an optimization we skip notifying Text nodes and other leaf nodes
+ // of removal when they're not in the Document tree since the virtual
+ // call to removedFrom is not needed.
+ if (!node->inDocument() && !node->isContainerNode())
+ continue;
+ if (document.cssTarget() == node)
+ document.setCSSTarget(nullptr);
+ node->removedFrom(this);
+ for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
+ notifyNodeRemoved(*shadowRoot);
+ }
}
void ContainerNode::attach(const AttachContext& context)
@@ -646,7 +746,7 @@ void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int chil
if (!changedByParser && childCountDelta)
document().updateRangesAfterChildrenChanged(this);
invalidateNodeListCachesInAncestors();
- if (childCountDelta > 0 && inActiveDocument()) {
+ if (childCountDelta > 0 && !childNeedsStyleRecalc()) {
setChildNeedsStyleRecalc();
markAncestorsWithChildNeedsStyleRecalc();
}
@@ -666,7 +766,6 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
return false;
// What is this code really trying to do?
RenderObject* o = renderer();
- RenderObject* p = o;
if (!o->isInline() || o->isReplaced()) {
point = o->localToAbsolute(FloatPoint(), UseTransforms);
@@ -675,9 +774,9 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
// find the next text/image child, to get a position
while (o) {
- p = o;
- if (o->firstChild()) {
- o = o->firstChild();
+ RenderObject* p = o;
+ if (RenderObject* oFirstChild = o->slowFirstChild()) {
+ o = oFirstChild;
} else if (o->nextSibling()) {
o = o->nextSibling();
} else {
@@ -703,7 +802,7 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
} else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
point = FloatPoint();
if (o->isText() && toRenderText(o)->firstTextBox()) {
- point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root()->lineTop());
+ point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root().lineTop().toFloat());
} else if (o->isBox()) {
RenderBox* box = toRenderBox(o);
point.moveBy(box->location());
@@ -736,8 +835,8 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
// find the last text/image child, to get a position
while (o) {
- if (o->lastChild()) {
- o = o->lastChild();
+ if (RenderObject* oLastChild = o->slowLastChild()) {
+ o = oLastChild;
} else if (o->previousSibling()) {
o = o->previousSibling();
} else {
@@ -800,12 +899,18 @@ void ContainerNode::focusStateChanged()
// renderer we can just ignore the state change.
if (!renderer())
return;
- // FIXME: This could probably setNeedsStyleRecalc(LocalStyleChange) in the affectedByFocus case
- // and only setNeedsStyleRecalc(SubtreeStyleChange) in the childrenAffectedByFocus case.
- if (renderStyle()->affectedByFocus() || (isElementNode() && toElement(this)->childrenAffectedByFocus()))
- setNeedsStyleRecalc();
+
+ if (styleChangeType() < SubtreeStyleChange) {
+ if (renderStyle()->affectedByFocus() && renderStyle()->hasPseudoStyle(FIRST_LETTER))
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus())
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoFocus, *toElement(this));
+ else if (renderStyle()->affectedByFocus())
+ setNeedsStyleRecalc(LocalStyleChange);
+ }
+
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), FocusState);
+ RenderTheme::theme().stateChanged(renderer(), FocusControlState);
}
void ContainerNode::setFocus(bool received)
@@ -816,9 +921,15 @@ void ContainerNode::setFocus(bool received)
Node::setFocus(received);
focusStateChanged();
+
+ if (renderer() || received)
+ return;
+
// If :focus sets display: none, we lose focus but still need to recalc our style.
- if (!renderer() && !received)
- setNeedsStyleRecalc();
+ if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus() && styleChangeType() < SubtreeStyleChange)
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoFocus, *toElement(this));
+ else
+ setNeedsStyleRecalc(LocalStyleChange);
}
void ContainerNode::setActive(bool down)
@@ -830,10 +941,17 @@ void ContainerNode::setActive(bool down)
// FIXME: Why does this not need to handle the display: none transition like :hover does?
if (renderer()) {
- if (renderStyle()->affectedByActive() || (isElementNode() && toElement(this)->childrenAffectedByActive()))
- setNeedsStyleRecalc();
+ if (styleChangeType() < SubtreeStyleChange) {
+ if (renderStyle()->affectedByActive() && renderStyle()->hasPseudoStyle(FIRST_LETTER))
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByActive())
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoActive, *toElement(this));
+ else if (renderStyle()->affectedByActive())
+ setNeedsStyleRecalc(LocalStyleChange);
+ }
+
if (renderStyle()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), PressedState);
+ RenderTheme::theme().stateChanged(renderer(), PressedControlState);
}
}
@@ -846,49 +964,34 @@ void ContainerNode::setHovered(bool over)
// If :hover sets display: none we lose our hover but still need to recalc our style.
if (!renderer()) {
- if (!over)
- setNeedsStyleRecalc();
+ if (over)
+ return;
+ if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover() && styleChangeType() < SubtreeStyleChange)
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoHover, *toElement(this));
+ else
+ setNeedsStyleRecalc(LocalStyleChange);
return;
}
- if (renderer()) {
- if (renderStyle()->affectedByHover() || (isElementNode() && toElement(this)->childrenAffectedByHover()))
- setNeedsStyleRecalc();
- if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), HoverState);
+ if (styleChangeType() < SubtreeStyleChange) {
+ if (renderStyle()->affectedByHover() && renderStyle()->hasPseudoStyle(FIRST_LETTER))
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover())
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoHover, *toElement(this));
+ else if (renderStyle()->affectedByHover())
+ setNeedsStyleRecalc(LocalStyleChange);
}
-}
-
-PassRefPtr<HTMLCollection> ContainerNode::children()
-{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, NodeChildren);
-}
-
-Element* ContainerNode::firstElementChild() const
-{
- return ElementTraversal::firstWithin(*this);
-}
-Element* ContainerNode::lastElementChild() const
-{
- Node* n = lastChild();
- while (n && !n->isElementNode())
- n = n->previousSibling();
- return toElement(n);
+ if (renderer()->style()->hasAppearance())
+ RenderTheme::theme().stateChanged(renderer(), HoverControlState);
}
-unsigned ContainerNode::childElementCount() const
+PassRefPtrWillBeRawPtr<HTMLCollection> ContainerNode::children()
{
- unsigned count = 0;
- Node* n = firstChild();
- while (n) {
- count += n->isElementNode();
- n = n->nextSibling();
- }
- return count;
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, NodeChildren);
}
-unsigned ContainerNode::childNodeCount() const
+unsigned ContainerNode::countChildren() const
{
unsigned count = 0;
Node *n;
@@ -897,7 +1000,7 @@ unsigned ContainerNode::childNodeCount() const
return count;
}
-Node *ContainerNode::childNode(unsigned index) const
+Node* ContainerNode::traverseToChildAt(unsigned index) const
{
unsigned i;
Node *n = firstChild();
@@ -906,6 +1009,33 @@ Node *ContainerNode::childNode(unsigned index) const
return n;
}
+PassRefPtrWillBeRawPtr<Element> ContainerNode::querySelector(const AtomicString& selectors, ExceptionState& exceptionState)
+{
+ if (selectors.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
+ return nullptr;
+ }
+
+ SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
+ if (!selectorQuery)
+ return nullptr;
+ return selectorQuery->queryFirst(*this);
+}
+
+PassRefPtrWillBeRawPtr<StaticNodeList> ContainerNode::querySelectorAll(const AtomicString& selectors, ExceptionState& exceptionState)
+{
+ if (selectors.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
+ return nullptr;
+ }
+
+ SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
+ if (!selectorQuery)
+ return nullptr;
+
+ return selectorQuery->queryAll(*this);
+}
+
static void dispatchChildInsertionEvents(Node& child)
{
if (child.isInShadowTree())
@@ -913,8 +1043,8 @@ static void dispatchChildInsertionEvents(Node& child)
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- RefPtr<Node> c(child);
- RefPtr<Document> document(child.document());
+ RefPtrWillBeRawPtr<Node> c(child);
+ RefPtrWillBeRawPtr<Document> document(child.document());
if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInserted, true, c->parentNode()));
@@ -937,8 +1067,8 @@ static void dispatchChildRemovalEvents(Node& child)
InspectorInstrumentation::willRemoveDOMNode(&child);
- RefPtr<Node> c(child);
- RefPtr<Document> document(child.document());
+ RefPtrWillBeRawPtr<Node> c(child);
+ RefPtrWillBeRawPtr<Document> document(child.document());
// dispatch pre-removal mutation events
if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
@@ -956,18 +1086,196 @@ static void dispatchChildRemovalEvents(Node& child)
void ContainerNode::updateTreeAfterInsertion(Node& child)
{
+#if !ENABLE(OILPAN)
ASSERT(refCount());
ASSERT(child.refCount());
+#endif
ChildListMutationScope(*this).childAdded(child);
childrenChanged(false, child.previousSibling(), child.nextSibling(), 1);
- ChildNodeInsertionNotifier(*this).notify(child);
+ notifyNodeInserted(child);
dispatchChildInsertionEvents(child);
}
+bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const
+{
+ return rareData()->hasRestyleFlag(mask);
+}
+
+bool ContainerNode::hasRestyleFlagsInternal() const
+{
+ return rareData()->hasRestyleFlags();
+}
+
+void ContainerNode::setRestyleFlag(DynamicRestyleFlags mask)
+{
+ ASSERT(isElementNode() || isShadowRoot());
+ ensureRareData().setRestyleFlag(mask);
+}
+
+void ContainerNode::checkForChildrenAdjacentRuleChanges()
+{
+ bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
+ bool hasIndirectAdjacentRules = childrenAffectedByIndirectAdjacentRules();
+
+ if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
+ return;
+
+ unsigned forceCheckOfNextElementCount = 0;
+ bool forceCheckOfAnyElementSibling = false;
+ Document& document = this->document();
+
+ for (Element* child = ElementTraversal::firstChild(*this); child; child = ElementTraversal::nextSibling(*child)) {
+ bool childRulesChanged = child->needsStyleRecalc() && child->styleChangeType() >= SubtreeStyleChange;
+
+ if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
+ child->setNeedsStyleRecalc(SubtreeStyleChange);
+
+ if (childRulesChanged && hasDirectAdjacentRules)
+ forceCheckOfNextElementCount = document.styleEngine()->maxDirectAdjacentSelectors();
+ else if (forceCheckOfNextElementCount)
+ --forceCheckOfNextElementCount;
+
+ forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
+ }
+}
+
+void ContainerNode::checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || styleChangeType() >= SubtreeStyleChange)
+ return;
+
+ if (needsStyleRecalc() && childrenAffectedByPositionalRules())
+ return;
+
+ // Forward positional selectors include nth-child, nth-of-type, first-of-type and only-of-type.
+ // The indirect adjacent selector is the ~ selector.
+ // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
+ // We have to invalidate everything following the insertion point in the forward and indirect adjacent case,
+ // and everything before the insertion point in the backward case.
+ // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
+ // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
+ // here. recalcStyle will then force a walk of the children when it sees that this has happened.
+ if (((childrenAffectedByForwardPositionalRules() || childrenAffectedByIndirectAdjacentRules()) && afterChange)
+ || (childrenAffectedByBackwardPositionalRules() && beforeChange)) {
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ return;
+ }
+
+ // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
+ // In the DOM case, we only need to do something if |afterChange| is not 0.
+ // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
+ if (childrenAffectedByFirstChildRules() && afterChange) {
+ // Find our new first child.
+ Element* newFirstChild = ElementTraversal::firstWithin(*this);
+ RenderStyle* newFirstChildStyle = newFirstChild ? newFirstChild->renderStyle() : 0;
+
+ // Find the first element node following |afterChange|
+ Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : ElementTraversal::nextSibling(*afterChange);
+ RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertion ? firstElementAfterInsertion->renderStyle() : 0;
+
+ // This is the insert/append case.
+ if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertionStyle && firstElementAfterInsertionStyle->firstChildState())
+ firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange);
+
+ // We also have to handle node removal.
+ if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState()))
+ newFirstChild->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
+ // In the DOM case, we only need to do something if |afterChange| is not 0.
+ if (childrenAffectedByLastChildRules() && beforeChange) {
+ // Find our new last child.
+ Node* newLastChild = ElementTraversal::lastChild(*this);
+ RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyle() : 0;
+
+ // Find the last element node going backwards from |beforeChange|
+ Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? beforeChange : ElementTraversal::previousSibling(*beforeChange);
+ RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertion ? lastElementBeforeInsertion->renderStyle() : 0;
+
+ if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertionStyle && lastElementBeforeInsertionStyle->lastChildState())
+ lastElementBeforeInsertion->setNeedsStyleRecalc(SubtreeStyleChange);
+
+ // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
+ // to match now.
+ if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChildStyle->lastChildState()))
+ newLastChild->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
+ // that could be affected by this DOM change.
+ if (childrenAffectedByDirectAdjacentRules() && afterChange) {
+ if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : ElementTraversal::nextSibling(*afterChange))
+ firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+}
+
+PassRefPtrWillBeRawPtr<TagCollection> ContainerNode::getElementsByTagName(const AtomicString& localName)
+{
+ if (localName.isNull())
+ return nullptr;
+
+ if (document().isHTMLDocument())
+ return ensureRareData().ensureNodeLists().addCache<HTMLTagCollection>(*this, HTMLTagCollectionType, localName);
+ return ensureRareData().ensureNodeLists().addCache<TagCollection>(*this, TagCollectionType, localName);
+}
+
+PassRefPtrWillBeRawPtr<TagCollection> ContainerNode::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
+{
+ if (localName.isNull())
+ return nullptr;
+
+ if (namespaceURI == starAtom)
+ return getElementsByTagName(localName);
+
+ return ensureRareData().ensureNodeLists().addCache(*this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
+}
+
+// Takes an AtomicString in argument because it is common for elements to share the same name attribute.
+// Therefore, the NameNodeList factory function expects an AtomicString type.
+PassRefPtrWillBeRawPtr<NameNodeList> ContainerNode::getElementsByName(const AtomicString& elementName)
+{
+ return ensureRareData().ensureNodeLists().addCache<NameNodeList>(*this, NameNodeListType, elementName);
+}
+
+// Takes an AtomicString in argument because it is common for elements to share the same set of class names.
+// Therefore, the ClassNodeList factory function expects an AtomicString type.
+PassRefPtrWillBeRawPtr<ClassCollection> ContainerNode::getElementsByClassName(const AtomicString& classNames)
+{
+ return ensureRareData().ensureNodeLists().addCache<ClassCollection>(*this, ClassCollectionType, classNames);
+}
+
+PassRefPtrWillBeRawPtr<RadioNodeList> ContainerNode::radioNodeList(const AtomicString& name, bool onlyMatchImgElements)
+{
+ ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
+ CollectionType type = onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType;
+ return ensureRareData().ensureNodeLists().addCache<RadioNodeList>(*this, type, name);
+}
+
+Element* ContainerNode::getElementById(const AtomicString& id) const
+{
+ if (isInTreeScope()) {
+ // Fast path if we are in a tree scope: call getElementById() on tree scope
+ // and check if the matching element is in our subtree.
+ Element* element = treeScope().getElementById(id);
+ if (!element)
+ return 0;
+ if (element->isDescendantOf(this))
+ return element;
+ }
+
+ // Fall back to traversing our subtree. In case of duplicate ids, the first element found will be returned.
+ for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
+ if (element->getIdAttribute() == id)
+ return element;
+ }
+ return 0;
+}
+
#ifndef NDEBUG
bool childAttachedAllowedWhenAttachingChildren(ContainerNode* node)
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h
index d64d78275f9..4df98d42119 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h
@@ -31,82 +31,76 @@
namespace WebCore {
+class ClassCollection;
class ExceptionState;
class FloatPoint;
class HTMLCollection;
+class StaticNodeList;
+class TagCollection;
namespace Private {
template<class GenericNode, class GenericNodeContainer>
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
}
-class NoEventDispatchAssertion {
-public:
- NoEventDispatchAssertion()
- {
-#ifndef NDEBUG
- if (!isMainThread())
- return;
- s_count++;
-#endif
- }
-
- ~NoEventDispatchAssertion()
- {
-#ifndef NDEBUG
- if (!isMainThread())
- return;
- ASSERT(s_count);
- s_count--;
-#endif
- }
-
-#ifndef NDEBUG
- static bool isEventDispatchForbidden()
- {
- if (!isMainThread())
- return false;
- return s_count;
- }
-#endif
-
-private:
-#ifndef NDEBUG
- static unsigned s_count;
-#endif
+enum DynamicRestyleFlags {
+ ChildrenOrSiblingsAffectedByFocus = 1 << 0,
+ ChildrenOrSiblingsAffectedByHover = 1 << 1,
+ ChildrenOrSiblingsAffectedByActive = 1 << 2,
+ ChildrenOrSiblingsAffectedByDrag = 1 << 3,
+ ChildrenAffectedByFirstChildRules = 1 << 4,
+ ChildrenAffectedByLastChildRules = 1 << 5,
+ ChildrenAffectedByDirectAdjacentRules = 1 << 6,
+ ChildrenAffectedByIndirectAdjacentRules = 1 << 7,
+ ChildrenAffectedByForwardPositionalRules = 1 << 8,
+ ChildrenAffectedByBackwardPositionalRules = 1 << 9,
+
+ NumberOfDynamicRestyleFlags = 10,
};
+// This constant controls how much buffer is initially allocated
+// for a Node Vector that is used to store child Nodes of a given Node.
+// FIXME: Optimize the value.
+const int initialNodeVectorSize = 11;
+typedef WillBeHeapVector<RefPtrWillBeMember<Node>, initialNodeVectorSize> NodeVector;
+
class ContainerNode : public Node {
public:
virtual ~ContainerNode();
Node* firstChild() const { return m_firstChild; }
Node* lastChild() const { return m_lastChild; }
- bool hasChildNodes() const { return m_firstChild; }
+ bool hasChildren() const { return m_firstChild; }
bool hasOneChild() const { return m_firstChild && !m_firstChild->nextSibling(); }
bool hasOneTextChild() const { return hasOneChild() && m_firstChild->isTextNode(); }
+ bool hasChildCount(unsigned) const;
- // ParentNode interface API
- PassRefPtr<HTMLCollection> children();
- Element* firstElementChild() const;
- Element* lastElementChild() const;
- unsigned childElementCount() const;
+ PassRefPtrWillBeRawPtr<HTMLCollection> children();
- unsigned childNodeCount() const;
- Node* childNode(unsigned index) const;
+ unsigned countChildren() const;
+ Node* traverseToChildAt(unsigned index) const;
- void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
- void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ PassRefPtrWillBeRawPtr<Element> querySelector(const AtomicString& selectors, ExceptionState&);
+ PassRefPtrWillBeRawPtr<StaticNodeList> querySelectorAll(const AtomicString& selectors, ExceptionState&);
+
+ void insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
void removeChild(Node* child, ExceptionState& = ASSERT_NO_EXCEPTION);
- void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+
+ Element* getElementById(const AtomicString& id) const;
+ PassRefPtrWillBeRawPtr<TagCollection> getElementsByTagName(const AtomicString&);
+ PassRefPtrWillBeRawPtr<TagCollection> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
+ PassRefPtrWillBeRawPtr<NameNodeList> getElementsByName(const AtomicString& elementName);
+ PassRefPtrWillBeRawPtr<ClassCollection> getElementsByClassName(const AtomicString& classNames);
+ PassRefPtrWillBeRawPtr<RadioNodeList> radioNodeList(const AtomicString&, bool onlyMatchImgElements = false);
// These methods are only used during parsing.
// They don't send DOM mutation events or handle reparenting.
- // However, arbitrary code may be run by beforeload handlers.
- void parserAppendChild(PassRefPtr<Node>);
+ void parserAppendChild(PassRefPtrWillBeRawPtr<Node>);
void parserRemoveChild(Node&);
- void parserInsertBefore(PassRefPtr<Node> newChild, Node& refChild);
+ void parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node& refChild);
void parserTakeAllChildrenFrom(ContainerNode&);
void removeChildren();
@@ -115,12 +109,51 @@ public:
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual LayoutRect boundingBox() const OVERRIDE;
+ virtual LayoutRect boundingBox() const OVERRIDE FINAL;
virtual void setFocus(bool) OVERRIDE;
void focusStateChanged();
virtual void setActive(bool = true) OVERRIDE;
virtual void setHovered(bool = true) OVERRIDE;
+ bool childrenOrSiblingsAffectedByFocus() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByFocus); }
+ void setChildrenOrSiblingsAffectedByFocus() { setRestyleFlag(ChildrenOrSiblingsAffectedByFocus); }
+
+ bool childrenOrSiblingsAffectedByHover() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByHover); }
+ void setChildrenOrSiblingsAffectedByHover() { setRestyleFlag(ChildrenOrSiblingsAffectedByHover); }
+
+ bool childrenOrSiblingsAffectedByActive() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByActive); }
+ void setChildrenOrSiblingsAffectedByActive() { setRestyleFlag(ChildrenOrSiblingsAffectedByActive); }
+
+ bool childrenOrSiblingsAffectedByDrag() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByDrag); }
+ void setChildrenOrSiblingsAffectedByDrag() { setRestyleFlag(ChildrenOrSiblingsAffectedByDrag); }
+
+ bool childrenAffectedByPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules) || hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
+
+ bool childrenAffectedByFirstChildRules() const { return hasRestyleFlag(ChildrenAffectedByFirstChildRules); }
+ void setChildrenAffectedByFirstChildRules() { setRestyleFlag(ChildrenAffectedByFirstChildRules); }
+
+ bool childrenAffectedByLastChildRules() const { return hasRestyleFlag(ChildrenAffectedByLastChildRules); }
+ void setChildrenAffectedByLastChildRules() { setRestyleFlag(ChildrenAffectedByLastChildRules); }
+
+ bool childrenAffectedByDirectAdjacentRules() const { return hasRestyleFlag(ChildrenAffectedByDirectAdjacentRules); }
+ void setChildrenAffectedByDirectAdjacentRules() { setRestyleFlag(ChildrenAffectedByDirectAdjacentRules); }
+
+ bool childrenAffectedByIndirectAdjacentRules() const { return hasRestyleFlag(ChildrenAffectedByIndirectAdjacentRules); }
+ void setChildrenAffectedByIndirectAdjacentRules() { setRestyleFlag(ChildrenAffectedByIndirectAdjacentRules); }
+
+ bool childrenAffectedByForwardPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules); }
+ void setChildrenAffectedByForwardPositionalRules() { setRestyleFlag(ChildrenAffectedByForwardPositionalRules); }
+
+ bool childrenAffectedByBackwardPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
+ void setChildrenAffectedByBackwardPositionalRules() { setRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
+
+ // FIXME: These methods should all be renamed to something better than "check",
+ // since it's not clear that they alter the style bits of siblings and children.
+ void checkForChildrenAdjacentRuleChanges();
+ void checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta);
+
+ bool childrenSupportStyleSharing() const { return !hasRestyleFlags(); }
+
// -----------------------------------------------------------------------------
// Notification of document structure changes (see core/dom/Node.h for more notification methods)
@@ -130,28 +163,40 @@ public:
void disconnectDescendantFrames();
- virtual bool childShouldCreateRenderer(const Node& child) const { return true; }
+ virtual void trace(Visitor*) OVERRIDE;
+
+ void notifyNodeInserted(Node&);
+ void notifyNodeRemoved(Node&);
protected:
ContainerNode(TreeScope*, ConstructionType = CreateContainer);
template<class GenericNode, class GenericNodeContainer>
- friend void appendChildToContainer(GenericNode& child, GenericNodeContainer&);
-
- template<class GenericNode, class GenericNodeContainer>
friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
+#if !ENABLE(OILPAN)
void removeDetachedChildren();
+#endif
+
void setFirstChild(Node* child) { m_firstChild = child; }
void setLastChild(Node* child) { m_lastChild = child; }
private:
void removeBetween(Node* previousChild, Node* nextChild, Node& oldChild);
void insertBeforeCommon(Node& nextChild, Node& oldChild);
+ void appendChildCommon(Node& child);
void updateTreeAfterInsertion(Node& child);
void willRemoveChildren();
void willRemoveChild(Node& child);
+ void notifyNodeInsertedInternal(Node&, NodeVector& postInsertionNotificationTargets);
+
+ bool hasRestyleFlag(DynamicRestyleFlags mask) const { return hasRareData() && hasRestyleFlagInternal(mask); }
+ bool hasRestyleFlags() const { return hasRareData() && hasRestyleFlagsInternal(); }
+ void setRestyleFlag(DynamicRestyleFlags);
+ bool hasRestyleFlagInternal(DynamicRestyleFlags) const;
+ bool hasRestyleFlagsInternal() const;
+
inline bool checkAcceptChildGuaranteedNodeTypes(const Node& newChild, ExceptionState&) const;
inline bool checkAcceptChild(const Node* newChild, const Node* oldChild, ExceptionState&) const;
inline bool containsConsideringHostElements(const Node&) const;
@@ -163,8 +208,8 @@ private:
bool getUpperLeftCorner(FloatPoint&) const;
bool getLowerRightCorner(FloatPoint&) const;
- Node* m_firstChild;
- Node* m_lastChild;
+ RawPtrWillBeMember<Node> m_firstChild;
+ RawPtrWillBeMember<Node> m_lastChild;
};
#ifndef NDEBUG
@@ -173,10 +218,20 @@ bool childAttachedAllowedWhenAttachingChildren(ContainerNode*);
DEFINE_NODE_TYPE_CASTS(ContainerNode, isContainerNode());
+inline bool ContainerNode::hasChildCount(unsigned count) const
+{
+ Node* child = m_firstChild;
+ while (count && child) {
+ child = child->nextSibling();
+ --count;
+ }
+ return !count && !child;
+}
+
inline ContainerNode::ContainerNode(TreeScope* treeScope, ConstructionType type)
: Node(treeScope, type)
- , m_firstChild(0)
- , m_lastChild(0)
+ , m_firstChild(nullptr)
+ , m_lastChild(nullptr)
{
}
@@ -201,18 +256,18 @@ inline void ContainerNode::detachChildren(const AttachContext& context)
child->detach(childrenContext);
}
-inline unsigned Node::childNodeCount() const
+inline unsigned Node::countChildren() const
{
if (!isContainerNode())
return 0;
- return toContainerNode(this)->childNodeCount();
+ return toContainerNode(this)->countChildren();
}
-inline Node* Node::childNode(unsigned index) const
+inline Node* Node::traverseToChildAt(unsigned index) const
{
if (!isContainerNode())
return 0;
- return toContainerNode(this)->childNode(index);
+ return toContainerNode(this)->traverseToChildAt(index);
}
inline Node* Node::firstChild() const
@@ -229,20 +284,26 @@ inline Node* Node::lastChild() const
return toContainerNode(this)->lastChild();
}
-inline Node* Node::highestAncestor() const
+inline Node& Node::highestAncestorOrSelf() const
{
Node* node = const_cast<Node*>(this);
Node* highest = node;
for (; node; node = node->parentNode())
highest = node;
- return highest;
+ return *highest;
}
-// This constant controls how much buffer is initially allocated
-// for a Node Vector that is used to store child Nodes of a given Node.
-// FIXME: Optimize the value.
-const int initialNodeVectorSize = 11;
-typedef Vector<RefPtr<Node>, initialNodeVectorSize> NodeVector;
+inline ContainerNode* Node::parentElementOrShadowRoot() const
+{
+ ContainerNode* parent = parentNode();
+ return parent && (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0;
+}
+
+inline ContainerNode* Node::parentElementOrDocumentFragment() const
+{
+ ContainerNode* parent = parentNode();
+ return parent && (parent->isElementNode() || parent->isDocumentFragment()) ? parent : 0;
+}
inline void getChildNodes(Node& node, NodeVector& nodes)
{
@@ -251,71 +312,6 @@ inline void getChildNodes(Node& node, NodeVector& nodes)
nodes.append(child);
}
-class ChildNodesLazySnapshot {
- WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot);
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit ChildNodesLazySnapshot(Node& parentNode)
- : m_currentNode(parentNode.firstChild())
- , m_currentIndex(0)
- {
- m_nextSnapshot = latestSnapshot;
- latestSnapshot = this;
- }
-
- ~ChildNodesLazySnapshot()
- {
- latestSnapshot = m_nextSnapshot;
- }
-
- // Returns 0 if there is no next Node.
- PassRefPtr<Node> nextNode()
- {
- if (LIKELY(!hasSnapshot())) {
- RefPtr<Node> node = m_currentNode;
- if (node)
- m_currentNode = node->nextSibling();
- return node.release();
- }
- Vector<RefPtr<Node> >& nodeVector = *m_childNodes;
- if (m_currentIndex >= nodeVector.size())
- return 0;
- return nodeVector[m_currentIndex++];
- }
-
- void takeSnapshot()
- {
- if (hasSnapshot())
- return;
- m_childNodes = adoptPtr(new Vector<RefPtr<Node> >());
- Node* node = m_currentNode.get();
- while (node) {
- m_childNodes->append(node);
- node = node->nextSibling();
- }
- }
-
- ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; }
- bool hasSnapshot() { return !!m_childNodes.get(); }
-
- static void takeChildNodesLazySnapshot()
- {
- ChildNodesLazySnapshot* snapshot = latestSnapshot;
- while (snapshot && !snapshot->hasSnapshot()) {
- snapshot->takeSnapshot();
- snapshot = snapshot->nextSnapshot();
- }
- }
-
-private:
- static ChildNodesLazySnapshot* latestSnapshot;
-
- RefPtr<Node> m_currentNode;
- unsigned m_currentIndex;
- OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated.
- ChildNodesLazySnapshot* m_nextSnapshot;
-};
-
} // namespace WebCore
#endif // ContainerNode_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp b/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp
deleted file mode 100644
index 4c55b46355d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/dom/ContainerNodeAlgorithms.h"
-
-#include "core/dom/Element.h"
-#include "core/dom/shadow/ElementShadow.h"
-#include "core/dom/shadow/ShadowRoot.h"
-
-namespace WebCore {
-
-class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
-public:
- explicit ShadowRootVector(ElementShadow* tree)
- {
- for (ShadowRoot* root = tree->youngestShadowRoot(); root; root = root->olderShadowRoot())
- append(root);
- }
-};
-
-void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode& node)
-{
- ChildNodesLazySnapshot snapshot(node);
- while (RefPtr<Node> child = snapshot.nextNode()) {
- // If we have been removed from the document during this loop, then
- // we don't want to tell the rest of our children that they've been
- // inserted into the document because they haven't.
- if (node.inDocument() && child->parentNode() == node)
- notifyNodeInsertedIntoDocument(*child);
- }
-
- if (!node.isElementNode())
- return;
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- ShadowRootVector roots(shadow);
- for (size_t i = 0; i < roots.size(); ++i) {
- if (node.inDocument() && roots[i]->host() == node)
- notifyNodeInsertedIntoDocument(*roots[i]);
- }
- }
-}
-
-void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(ContainerNode& node)
-{
- for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
- if (child->isContainerNode())
- notifyNodeInsertedIntoTree(toContainerNode(*child));
- }
-
- for (ShadowRoot* root = node.youngestShadowRoot(); root; root = root->olderShadowRoot())
- notifyNodeInsertedIntoTree(*root);
-}
-
-void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode& node)
-{
- ChildNodesLazySnapshot snapshot(node);
- while (RefPtr<Node> child = snapshot.nextNode()) {
- // If we have been added to the document during this loop, then we
- // don't want to tell the rest of our children that they've been
- // removed from the document because they haven't.
- if (!node.inDocument() && child->parentNode() == node)
- notifyNodeRemovedFromDocument(*child);
- }
-
- if (!node.isElementNode())
- return;
-
- if (node.document().cssTarget() == node)
- node.document().setCSSTarget(0);
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- ShadowRootVector roots(shadow);
- for (size_t i = 0; i < roots.size(); ++i) {
- if (!node.inDocument() && roots[i]->host() == node)
- notifyNodeRemovedFromDocument(*roots[i]);
- }
- }
-}
-
-void ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree(ContainerNode& node)
-{
- for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
- if (child->isContainerNode())
- notifyNodeRemovedFromTree(toContainerNode(*child));
- }
-
- if (!node.isElementNode())
- return;
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- ShadowRootVector roots(shadow);
- for (size_t i = 0; i < roots.size(); ++i)
- notifyNodeRemovedFromTree(*roots[i]);
- }
-}
-
-void ChildFrameDisconnector::collectFrameOwners(ElementShadow& shadow)
-{
- for (ShadowRoot* root = shadow.youngestShadowRoot(); root; root = root->olderShadowRoot())
- collectFrameOwners(*root);
-}
-
-#ifndef NDEBUG
-unsigned assertConnectedSubrameCountIsConsistent(Node& node)
-{
- unsigned count = 0;
-
- if (node.isElementNode()) {
- if (node.isFrameOwnerElement() && toHTMLFrameOwnerElement(node).contentFrame())
- count++;
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
- count += assertConnectedSubrameCountIsConsistent(*root);
- }
- }
-
- for (Node* child = node.firstChild(); child; child = child->nextSibling())
- count += assertConnectedSubrameCountIsConsistent(*child);
-
- // If we undercount there's possibly a security bug since we'd leave frames
- // in subtrees outside the document.
- ASSERT(node.connectedSubframeCount() >= count);
-
- // If we overcount it's safe, but not optimal because it means we'll traverse
- // through the document in ChildFrameDisconnector looking for frames that have
- // already been disconnected.
- ASSERT(node.connectedSubframeCount() == count);
-
- return count;
-}
-#endif
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h b/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h
index b863c252f2f..67691aade58 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h
@@ -23,49 +23,10 @@
#define ContainerNodeAlgorithms_h
#include "core/dom/Document.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/inspector/InspectorInstrumentation.h"
#include "wtf/Assertions.h"
namespace WebCore {
-class ChildNodeInsertionNotifier {
-public:
- explicit ChildNodeInsertionNotifier(ContainerNode& insertionPoint)
- : m_insertionPoint(insertionPoint)
- {
- }
-
- void notify(Node&);
-
-private:
- void notifyDescendantInsertedIntoDocument(ContainerNode&);
- void notifyDescendantInsertedIntoTree(ContainerNode&);
- void notifyNodeInsertedIntoDocument(Node&);
- void notifyNodeInsertedIntoTree(ContainerNode&);
-
- ContainerNode& m_insertionPoint;
- Vector< RefPtr<Node> > m_postInsertionNotificationTargets;
-};
-
-class ChildNodeRemovalNotifier {
-public:
- explicit ChildNodeRemovalNotifier(ContainerNode& insertionPoint)
- : m_insertionPoint(insertionPoint)
- {
- }
-
- void notify(Node&);
-
-private:
- void notifyDescendantRemovedFromDocument(ContainerNode&);
- void notifyDescendantRemovedFromTree(ContainerNode&);
- void notifyNodeRemovedFromDocument(Node&);
- void notifyNodeRemovedFromTree(ContainerNode&);
-
- ContainerNode& m_insertionPoint;
-};
-
namespace Private {
template<class GenericNode, class GenericNodeContainer>
@@ -73,6 +34,7 @@ namespace Private {
}
+#if !ENABLE(OILPAN)
// Helper functions for TreeShared-derived classes, which have a 'Node' style interface
// This applies to 'ContainerNode' and 'SVGElementInstance'
template<class GenericNode, class GenericNodeContainer>
@@ -96,62 +58,17 @@ inline void removeDetachedChildrenInContainer(GenericNodeContainer& container)
if (next == 0)
tail = 0;
- if (n->hasChildNodes())
+ if (n->hasChildren())
Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n));
delete n;
}
}
-
-template<class GenericNode, class GenericNodeContainer>
-inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& container)
-{
- child.setParentOrShadowHostNode(&container);
-
- GenericNode* lastChild = container.lastChild();
- if (lastChild) {
- child.setPreviousSibling(lastChild);
- lastChild->setNextSibling(&child);
- } else {
- container.setFirstChild(&child);
- }
-
- container.setLastChild(&child);
-}
+#endif
// Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace
namespace Private {
- template<class GenericNode, class GenericNodeContainer, bool dispatchRemovalNotification>
- struct NodeRemovalDispatcher {
- static void dispatch(GenericNode&, GenericNodeContainer&)
- {
- // no-op, by default
- }
- };
-
- template<class GenericNode, class GenericNodeContainer>
- struct NodeRemovalDispatcher<GenericNode, GenericNodeContainer, true> {
- static void dispatch(GenericNode& node, GenericNodeContainer& container)
- {
- // Clean up any TreeScope to a removed tree.
- if (Document* containerDocument = container.ownerDocument())
- containerDocument->adoptIfNeeded(node);
- if (node.inDocument())
- ChildNodeRemovalNotifier(container).notify(node);
- }
- };
-
- template<class GenericNode>
- struct ShouldDispatchRemovalNotification {
- static const bool value = false;
- };
-
- template<>
- struct ShouldDispatchRemovalNotification<Node> {
- static const bool value = true;
- };
-
template<class GenericNode, class GenericNodeContainer>
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container)
{
@@ -180,8 +97,10 @@ namespace Private {
tail = n;
} else {
- RefPtr<GenericNode> protect(n); // removedFromDocument may remove remove all references to this node.
- NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container);
+ RefPtrWillBeRawPtr<GenericNode> protect(n); // removedFromDocument may remove all references to this node.
+ container.document().adoptIfNeeded(*n);
+ if (n->inDocument())
+ container.notifyNodeRemoved(*n);
}
}
@@ -190,151 +109,6 @@ namespace Private {
} // namespace Private
-inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node& node)
-{
- ASSERT(m_insertionPoint.inDocument());
- RefPtr<Node> protect(node);
- if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(&m_insertionPoint))
- m_postInsertionNotificationTargets.append(&node);
- if (node.isContainerNode())
- notifyDescendantInsertedIntoDocument(toContainerNode(node));
-}
-
-inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree(ContainerNode& node)
-{
- NoEventDispatchAssertion assertNoEventDispatch;
- ASSERT(!m_insertionPoint.inDocument());
-
- if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(&m_insertionPoint))
- m_postInsertionNotificationTargets.append(&node);
- notifyDescendantInsertedIntoTree(node);
-}
-
-inline void ChildNodeInsertionNotifier::notify(Node& node)
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- InspectorInstrumentation::didInsertDOMNode(&node);
-
- RefPtr<Document> protectDocument(node.document());
- RefPtr<Node> protectNode(node);
-
- if (m_insertionPoint.inDocument())
- notifyNodeInsertedIntoDocument(node);
- else if (node.isContainerNode())
- notifyNodeInsertedIntoTree(toContainerNode(node));
-
- for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i) {
- Node* targetNode = m_postInsertionNotificationTargets[i].get();
- if (targetNode->inDocument())
- targetNode->didNotifySubtreeInsertionsToDocument();
- }
-}
-
-inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument(Node& node)
-{
- ASSERT(m_insertionPoint.inDocument());
- node.removedFrom(&m_insertionPoint);
-
- if (node.isContainerNode())
- notifyDescendantRemovedFromDocument(toContainerNode(node));
-}
-
-inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromTree(ContainerNode& node)
-{
- NoEventDispatchAssertion assertNoEventDispatch;
- ASSERT(!m_insertionPoint.inDocument());
-
- node.removedFrom(&m_insertionPoint);
- notifyDescendantRemovedFromTree(node);
-}
-
-inline void ChildNodeRemovalNotifier::notify(Node& node)
-{
- if (node.inDocument()) {
- notifyNodeRemovedFromDocument(node);
- node.document().notifyRemovePendingSheetIfNeeded();
- } else if (node.isContainerNode())
- notifyNodeRemovedFromTree(toContainerNode(node));
-}
-
-class ChildFrameDisconnector {
-public:
- enum DisconnectPolicy {
- RootAndDescendants,
- DescendantsOnly
- };
-
- explicit ChildFrameDisconnector(Node& root)
- : m_root(root)
- {
- }
-
- void disconnect(DisconnectPolicy = RootAndDescendants);
-
-private:
- void collectFrameOwners(Node& root);
- void collectFrameOwners(ElementShadow&);
- void disconnectCollectedFrameOwners();
-
- Vector<RefPtr<HTMLFrameOwnerElement>, 10> m_frameOwners;
- Node& m_root;
-};
-
-#ifndef NDEBUG
-unsigned assertConnectedSubrameCountIsConsistent(Node&);
-#endif
-
-inline void ChildFrameDisconnector::collectFrameOwners(Node& root)
-{
- if (!root.connectedSubframeCount())
- return;
-
- if (root.isHTMLElement() && root.isFrameOwnerElement())
- m_frameOwners.append(&toHTMLFrameOwnerElement(root));
-
- for (Node* child = root.firstChild(); child; child = child->nextSibling())
- collectFrameOwners(*child);
-
- ElementShadow* shadow = root.isElementNode() ? toElement(root).shadow() : 0;
- if (shadow)
- collectFrameOwners(*shadow);
-}
-
-inline void ChildFrameDisconnector::disconnectCollectedFrameOwners()
-{
- // Must disable frame loading in the subtree so an unload handler cannot
- // insert more frames and create loaded frames in detached subtrees.
- SubframeLoadingDisabler disabler(m_root);
-
- for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
- HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
- // Don't need to traverse up the tree for the first owner since no
- // script could have moved it.
- if (!i || m_root.containsIncludingShadowDOM(owner))
- owner->disconnectContentFrame();
- }
-}
-
-inline void ChildFrameDisconnector::disconnect(DisconnectPolicy policy)
-{
-#ifndef NDEBUG
- assertConnectedSubrameCountIsConsistent(m_root);
-#endif
-
- if (!m_root.connectedSubframeCount())
- return;
-
- if (policy == RootAndDescendants)
- collectFrameOwners(m_root);
- else {
- for (Node* child = m_root.firstChild(); child; child = child->nextSibling())
- collectFrameOwners(*child);
- }
-
- disconnectCollectedFrameOwners();
-}
-
} // namespace WebCore
#endif // ContainerNodeAlgorithms_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp
index 980dde13bfb..2e17b30dace 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp
@@ -27,16 +27,15 @@
#include "config.h"
#include "core/dom/ContextFeatures.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
#include "core/page/Page.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-ContextFeaturesClient* ContextFeaturesClient::empty()
+PassOwnPtr<ContextFeaturesClient> ContextFeaturesClient::empty()
{
- DEFINE_STATIC_LOCAL(ContextFeaturesClient, empty, ());
- return &empty;
+ return adoptPtr(new ContextFeaturesClient());
}
const char* ContextFeatures::supplementName()
@@ -46,7 +45,11 @@ const char* ContextFeatures::supplementName()
ContextFeatures* ContextFeatures::defaultSwitch()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<ContextFeatures>, instance, (ContextFeatures::create(ContextFeaturesClient::empty())));
+#else
DEFINE_STATIC_REF(ContextFeatures, instance, (ContextFeatures::create(ContextFeaturesClient::empty())));
+#endif
return instance;
}
@@ -54,21 +57,14 @@ bool ContextFeatures::dialogElementEnabled(Document* document)
{
if (!document)
return RuntimeEnabledFeatures::dialogElementEnabled();
- return document->contextFeatures()->isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
-}
-
-bool ContextFeatures::styleScopedEnabled(Document* document)
-{
- if (!document)
- return RuntimeEnabledFeatures::styleScopedEnabled();
- return document->contextFeatures()->isEnabled(document, StyleScoped, RuntimeEnabledFeatures::styleScopedEnabled());
+ return document->contextFeatures().isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
}
bool ContextFeatures::pagePopupEnabled(Document* document)
{
if (!document)
return false;
- return document->contextFeatures()->isEnabled(document, PagePopup, false);
+ return document->contextFeatures().isEnabled(document, PagePopup, false);
}
bool ContextFeatures::mutationEventsEnabled(Document* document)
@@ -76,25 +72,25 @@ bool ContextFeatures::mutationEventsEnabled(Document* document)
ASSERT(document);
if (!document)
return true;
- return document->contextFeatures()->isEnabled(document, MutationEvents, true);
+ return document->contextFeatures().isEnabled(document, MutationEvents, true);
}
bool ContextFeatures::pushStateEnabled(Document* document)
{
- return document->contextFeatures()->isEnabled(document, PushState, true);
+ return document->contextFeatures().isEnabled(document, PushState, true);
}
-void provideContextFeaturesTo(Page* page, ContextFeaturesClient* client)
+void provideContextFeaturesTo(Page& page, PassOwnPtr<ContextFeaturesClient> client)
{
- RefCountedSupplement<Page, ContextFeatures>::provideTo(page, ContextFeatures::supplementName(), ContextFeatures::create(client));
+ ContextFeatures::SupplementType::provideTo(page, ContextFeatures::supplementName(), ContextFeatures::create(client));
}
-void provideContextFeaturesToDocumentFrom(Document* document, Page* page)
+void provideContextFeaturesToDocumentFrom(Document& document, Page& page)
{
- ContextFeatures* provided = static_cast<ContextFeatures*>(RefCountedSupplement<Page, ContextFeatures>::from(page, ContextFeatures::supplementName()));
+ ContextFeatures* provided = static_cast<ContextFeatures*>(ContextFeatures::SupplementType::from(page, ContextFeatures::supplementName()));
if (!provided)
return;
- document->setContextFeatures(provided);
+ document.setContextFeatures(*provided);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h
index 109b781ff09..ab479ab90dd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h
@@ -35,11 +35,18 @@ class ContextFeaturesClient;
class Document;
class Page;
+#if ENABLE(OILPAN)
+class ContextFeatures FINAL : public GarbageCollectedFinalized<ContextFeatures>, public HeapSupplement<Page> {
+ USING_GARBAGE_COLLECTED_MIXIN(ContextFeatures);
+public:
+ typedef HeapSupplement<Page> SupplementType;
+#else
class ContextFeatures : public RefCountedSupplement<Page, ContextFeatures> {
public:
+ typedef RefCountedSupplement<Page, ContextFeatures> SupplementType;
+#endif
enum FeatureType {
DialogElement = 0,
- StyleScoped,
PagePopup,
MutationEvents,
PushState,
@@ -48,10 +55,9 @@ public:
static const char* supplementName();
static ContextFeatures* defaultSwitch();
- static PassRefPtr<ContextFeatures> create(ContextFeaturesClient*);
+ static PassRefPtrWillBeRawPtr<ContextFeatures> create(PassOwnPtr<ContextFeaturesClient>);
static bool dialogElementEnabled(Document*);
- static bool styleScopedEnabled(Document*);
static bool pagePopupEnabled(Document*);
static bool mutationEventsEnabled(Document*);
static bool pushStateEnabled(Document*);
@@ -59,38 +65,34 @@ public:
bool isEnabled(Document*, FeatureType, bool) const;
void urlDidChange(Document*);
+#if ENABLE(OILPAN)
+ virtual void trace(Visitor* visitor) OVERRIDE { HeapSupplement<Page>::trace(visitor); }
+#endif
+
private:
- explicit ContextFeatures(ContextFeaturesClient* client)
+ explicit ContextFeatures(PassOwnPtr<ContextFeaturesClient> client)
: m_client(client)
{ }
- virtual void hostDestroyed() OVERRIDE;
-
- ContextFeaturesClient* m_client;
+ OwnPtr<ContextFeaturesClient> m_client;
};
-inline void ContextFeatures::hostDestroyed()
-{
- m_client = 0;
-}
-
-
class ContextFeaturesClient {
WTF_MAKE_FAST_ALLOCATED;
public:
- static ContextFeaturesClient* empty();
+ static PassOwnPtr<ContextFeaturesClient> empty();
virtual ~ContextFeaturesClient() { }
virtual bool isEnabled(Document*, ContextFeatures::FeatureType, bool defaultValue) { return defaultValue; }
virtual void urlDidChange(Document*) { }
};
-void provideContextFeaturesTo(Page*, ContextFeaturesClient*);
-void provideContextFeaturesToDocumentFrom(Document*, Page*);
+void provideContextFeaturesTo(Page&, PassOwnPtr<ContextFeaturesClient>);
+void provideContextFeaturesToDocumentFrom(Document&, Page&);
-inline PassRefPtr<ContextFeatures> ContextFeatures::create(ContextFeaturesClient* client)
+inline PassRefPtrWillBeRawPtr<ContextFeatures> ContextFeatures::create(PassOwnPtr<ContextFeaturesClient> client)
{
- return adoptRef(new ContextFeatures(client));
+ return adoptRefWillBeNoop(new ContextFeatures(client));
}
inline bool ContextFeatures::isEnabled(Document* document, FeatureType type, bool defaultValue) const
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp b/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
index 048978c7354..af9f97ca291 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -59,7 +59,6 @@ void ContextLifecycleNotifier::removeObserver(ContextLifecycleNotifier::Observer
RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
if (observer->observerType() == Observer::ActiveDOMObjectType) {
- RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
m_activeDOMObjects.remove(static_cast<ActiveDOMObject*>(observer));
}
}
@@ -67,44 +66,61 @@ void ContextLifecycleNotifier::removeObserver(ContextLifecycleNotifier::Observer
void ContextLifecycleNotifier::notifyResumingActiveDOMObjects()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
- ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
- for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
- ASSERT((*iter)->executionContext() == context());
- ASSERT((*iter)->suspendIfNeededCalled());
- (*iter)->resume();
+ Vector<ActiveDOMObject*> snapshotOfActiveDOMObjects;
+ copyToVector(m_activeDOMObjects, snapshotOfActiveDOMObjects);
+ for (Vector<ActiveDOMObject*>::iterator iter = snapshotOfActiveDOMObjects.begin(); iter != snapshotOfActiveDOMObjects.end(); iter++) {
+ // FIXME: Oilpan: At the moment, it's possible that the ActiveDOMObject is destructed
+ // during the iteration. Once we move ActiveDOMObject to the heap and
+ // make m_activeDOMObjects a HeapHashSet<WeakMember<ActiveDOMObject>>,
+ // it's no longer possible that ActiveDOMObject is destructed during the iteration,
+ // so we can remove the hack (i.e., we can just iterate m_activeDOMObjects without
+ // taking a snapshot). For more details, see https://codereview.chromium.org/247253002/.
+ if (m_activeDOMObjects.contains(*iter)) {
+ ASSERT((*iter)->executionContext() == context());
+ ASSERT((*iter)->suspendIfNeededCalled());
+ (*iter)->resume();
+ }
}
}
void ContextLifecycleNotifier::notifySuspendingActiveDOMObjects()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
- ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
- for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
- ASSERT((*iter)->executionContext() == context());
- ASSERT((*iter)->suspendIfNeededCalled());
- (*iter)->suspend();
+ Vector<ActiveDOMObject*> snapshotOfActiveDOMObjects;
+ copyToVector(m_activeDOMObjects, snapshotOfActiveDOMObjects);
+ for (Vector<ActiveDOMObject*>::iterator iter = snapshotOfActiveDOMObjects.begin(); iter != snapshotOfActiveDOMObjects.end(); iter++) {
+ // It's possible that the ActiveDOMObject is already destructed.
+ // See a FIXME above.
+ if (m_activeDOMObjects.contains(*iter)) {
+ ASSERT((*iter)->executionContext() == context());
+ ASSERT((*iter)->suspendIfNeededCalled());
+ (*iter)->suspend();
+ }
}
}
void ContextLifecycleNotifier::notifyStoppingActiveDOMObjects()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
- ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
- for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
- ASSERT((*iter)->executionContext() == context());
- ASSERT((*iter)->suspendIfNeededCalled());
- (*iter)->stop();
+ Vector<ActiveDOMObject*> snapshotOfActiveDOMObjects;
+ copyToVector(m_activeDOMObjects, snapshotOfActiveDOMObjects);
+ for (Vector<ActiveDOMObject*>::iterator iter = snapshotOfActiveDOMObjects.begin(); iter != snapshotOfActiveDOMObjects.end(); iter++) {
+ // It's possible that the ActiveDOMObject is already destructed.
+ // See a FIXME above.
+ if (m_activeDOMObjects.contains(*iter)) {
+ ASSERT((*iter)->executionContext() == context());
+ ASSERT((*iter)->suspendIfNeededCalled());
+ (*iter)->stop();
+ }
}
}
bool ContextLifecycleNotifier::hasPendingActivity() const
{
- ActiveDOMObjectSet::const_iterator activeObjectsEnd = activeDOMObjects().end();
- for (ActiveDOMObjectSet::const_iterator iter = activeDOMObjects().begin(); iter != activeObjectsEnd; ++iter) {
+ for (ActiveDOMObjectSet::const_iterator iter = m_activeDOMObjects.begin(); iter != m_activeDOMObjects.end(); ++iter) {
if ((*iter)->hasPendingActivity())
return true;
}
-
return false;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h b/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h
index 9902ebdcefd..d341205b62b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h
@@ -57,8 +57,14 @@ template<typename T> struct CrossThreadTaskTraits<PassOwnPtr<T> > {
typedef PassOwnPtr<T> ParamType;
};
+// FIXME: Oilpan: Using a RawPtr is not safe.
+// We need to move ExecutionContextTask to the heap and make this a Member.
+template<typename T> struct CrossThreadTaskTraits<RawPtr<T> > {
+ typedef RawPtr<T> ParamType;
+};
+
template<typename P1, typename MP1>
-class CrossThreadTask1 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask1 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1);
typedef CrossThreadTask1<P1, MP1> CrossThreadTask;
@@ -87,7 +93,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2>
-class CrossThreadTask2 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask2 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2);
typedef CrossThreadTask2<P1, MP1, P2, MP2> CrossThreadTask;
@@ -119,7 +125,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
-class CrossThreadTask3 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask3 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3);
typedef CrossThreadTask3<P1, MP1, P2, MP2, P3, MP3> CrossThreadTask;
@@ -154,7 +160,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4>
-class CrossThreadTask4 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask4 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4);
typedef CrossThreadTask4<P1, MP1, P2, MP2, P3, MP3, P4, MP4> CrossThreadTask;
@@ -192,7 +198,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5>
-class CrossThreadTask5 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask5 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5);
typedef CrossThreadTask5<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5> CrossThreadTask;
@@ -233,7 +239,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
-class CrossThreadTask6 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask6 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6);
typedef CrossThreadTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> CrossThreadTask;
@@ -277,7 +283,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7>
-class CrossThreadTask7 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask7 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7);
typedef CrossThreadTask7<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7> CrossThreadTask;
@@ -324,7 +330,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7, typename P8, typename MP8>
-class CrossThreadTask8 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask8 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7, MP8);
typedef CrossThreadTask8<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7, P8, MP8> CrossThreadTask;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMError.h b/chromium/third_party/WebKit/Source/core/dom/DOMError.h
index a66d0e2175f..845c23063b0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMError.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMError.h
@@ -29,36 +29,39 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class DOMError : public RefCounted<DOMError>, public ScriptWrappable {
+class DOMError : public RefCountedWillBeGarbageCollectedFinalized<DOMError>, public ScriptWrappable {
public:
- static PassRefPtr<DOMError> create(const String& name)
+ static PassRefPtrWillBeRawPtr<DOMError> create(const String& name)
{
- return adoptRef(new DOMError(name));
+ return adoptRefWillBeNoop(new DOMError(name));
}
- static PassRefPtr<DOMError> create(const String& name, const String& message)
+ static PassRefPtrWillBeRawPtr<DOMError> create(const String& name, const String& message)
{
- return adoptRef(new DOMError(name, message));
+ return adoptRefWillBeNoop(new DOMError(name, message));
}
- static PassRefPtr<DOMError> create(ExceptionCode ec)
+ static PassRefPtrWillBeRawPtr<DOMError> create(ExceptionCode ec)
{
- return adoptRef(new DOMError(DOMException::getErrorName(ec), DOMException::getErrorMessage(ec)));
+ return adoptRefWillBeNoop(new DOMError(DOMException::getErrorName(ec), DOMException::getErrorMessage(ec)));
}
- static PassRefPtr<DOMError> create(ExceptionCode ec, const String& message)
+ static PassRefPtrWillBeRawPtr<DOMError> create(ExceptionCode ec, const String& message)
{
- return adoptRef(new DOMError(DOMException::getErrorName(ec), message));
+ return adoptRefWillBeNoop(new DOMError(DOMException::getErrorName(ec), message));
}
const String& name() const { return m_name; }
const String& message() const { return m_message; }
+ void trace(Visitor*) { }
+
protected:
explicit DOMError(const String& name);
DOMError(const String& name, const String& message);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMError.idl b/chromium/third_party/WebKit/Source/core/dom/DOMError.idl
index b2ea60f4821..aba4e7a6c51 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMError.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMError.idl
@@ -26,7 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
- NoInterfaceObject
+ Constructor(DOMString name, optional DOMString message = null),
+ WillBeGarbageCollected
] interface DOMError {
readonly attribute DOMString name;
readonly attribute DOMString message;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp
index ebb5b209f6c..06128d40a3d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "core/dom/DOMException.h"
-#include "ExceptionCode.h"
+#include "core/dom/ExceptionCode.h"
namespace WebCore {
@@ -76,6 +76,9 @@ static const struct CoreException {
// SQL
{ "DatabaseError", "The operation failed for some reason related to the database.", 0 },
+
+ // Web Crypto
+ { "OperationError", "The operation failed for an operation-specific reason", 0 },
};
static const CoreException* getErrorEntry(ExceptionCode ec)
@@ -96,11 +99,11 @@ DOMException::DOMException(unsigned short code, const String& name, const String
ScriptWrappable::init(this);
}
-PassRefPtr<DOMException> DOMException::create(ExceptionCode ec, const String& sanitizedMessage, const String& unsanitizedMessage)
+PassRefPtrWillBeRawPtr<DOMException> DOMException::create(ExceptionCode ec, const String& sanitizedMessage, const String& unsanitizedMessage)
{
const CoreException* entry = getErrorEntry(ec);
ASSERT(entry);
- return adoptRef(new DOMException(entry->code,
+ return adoptRefWillBeNoop(new DOMException(entry->code,
entry->name ? entry->name : "Error",
sanitizedMessage.isNull() ? String(entry->message) : sanitizedMessage,
unsanitizedMessage));
@@ -136,12 +139,4 @@ String DOMException::getErrorMessage(ExceptionCode ec)
return entry->message;
}
-unsigned short DOMException::getLegacyErrorCode(ExceptionCode ec)
-{
- const CoreException* entry = getErrorEntry(ec);
- ASSERT(entry);
-
- return (entry && entry->code) ? entry->code : 0;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMException.h b/chromium/third_party/WebKit/Source/core/dom/DOMException.h
index 825cf50338c..221a312337c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMException.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMException.h
@@ -30,6 +30,7 @@
#define DOMException_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -38,9 +39,9 @@ namespace WebCore {
typedef int ExceptionCode;
-class DOMException : public RefCounted<DOMException>, public ScriptWrappable {
+class DOMException FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMException>, public ScriptWrappable {
public:
- static PassRefPtr<DOMException> create(ExceptionCode, const String& sanitizedMessage = String(), const String& unsanitizedMessage = String());
+ static PassRefPtrWillBeRawPtr<DOMException> create(ExceptionCode, const String& sanitizedMessage = String(), const String& unsanitizedMessage = String());
unsigned short code() const { return m_code; }
String name() const { return m_name; }
@@ -55,7 +56,8 @@ public:
static String getErrorName(ExceptionCode);
static String getErrorMessage(ExceptionCode);
- static unsigned short getLegacyErrorCode(ExceptionCode);
+
+ void trace(Visitor*) { }
private:
DOMException(unsigned short m_code, const String& name, const String& sanitizedMessage, const String& unsanitizedMessage);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMException.idl b/chromium/third_party/WebKit/Source/core/dom/DOMException.idl
index 68d04bf4782..44423509cbc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMException.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMException.idl
@@ -27,7 +27,8 @@
*/
[
- DoNotCheckConstants
+ DoNotCheckConstants,
+ WillBeGarbageCollected,
] exception DOMException {
readonly attribute unsigned short code;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
index ff898a52dea..0a66b556589 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "core/dom/DOMImplementation.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
@@ -36,7 +36,10 @@
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/XMLDocument.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/HTMLViewSourceDocument.h"
@@ -45,9 +48,7 @@
#include "core/html/PluginDocument.h"
#include "core/html/TextDocument.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
-#include "core/svg/SVGDocument.h"
#include "platform/ContentType.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/graphics/Image.h"
@@ -132,7 +133,7 @@ static bool isSupportedSVG11Feature(const String& feature, const String& version
addString(svgFeatures, "GraphicsAttribute");
addString(svgFeatures, "BaseGraphicsAttribute");
addString(svgFeatures, "Marker");
-// addString(svgFeatures, "ColorProfile"); // requires color-profile, bug 6037
+// addString(svgFeatures, "ColorProfile");
addString(svgFeatures, "Gradient");
addString(svgFeatures, "Pattern");
addString(svgFeatures, "Clip");
@@ -146,7 +147,6 @@ static bool isSupportedSVG11Feature(const String& feature, const String& version
addString(svgFeatures, "Cursor");
addString(svgFeatures, "Hyperlinking");
addString(svgFeatures, "XlinkAttribute");
- addString(svgFeatures, "ExternalResourcesRequired");
addString(svgFeatures, "View");
addString(svgFeatures, "Script");
addString(svgFeatures, "Animation");
@@ -178,42 +178,46 @@ bool DOMImplementation::hasFeature(const String& feature, const String& version)
return true;
}
-PassRefPtr<DocumentType> DOMImplementation::createDocumentType(const AtomicString& qualifiedName,
+bool DOMImplementation::hasFeatureForBindings(const String& feature, const String& version)
+{
+ if (!hasFeature(feature, version)) {
+ UseCounter::count(m_document, UseCounter::DOMImplementationHasFeatureReturnFalse);
+ return false;
+ }
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<DocumentType> DOMImplementation::createDocumentType(const AtomicString& qualifiedName,
const String& publicId, const String& systemId, ExceptionState& exceptionState)
{
AtomicString prefix, localName;
if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
+ return nullptr;
- return DocumentType::create(&m_document, qualifiedName, publicId, systemId);
+ return DocumentType::create(m_document, qualifiedName, publicId, systemId);
}
-DOMImplementation* DOMImplementation::getInterface(const String& /*feature*/)
-{
- return 0;
-}
-
-PassRefPtr<Document> DOMImplementation::createDocument(const AtomicString& namespaceURI,
+PassRefPtrWillBeRawPtr<XMLDocument> DOMImplementation::createDocument(const AtomicString& namespaceURI,
const AtomicString& qualifiedName, DocumentType* doctype, ExceptionState& exceptionState)
{
- RefPtr<Document> doc;
- DocumentInit init = DocumentInit::fromContext(m_document.contextDocument());
+ RefPtrWillBeRawPtr<XMLDocument> doc = nullptr;
+ DocumentInit init = DocumentInit::fromContext(document().contextDocument());
if (namespaceURI == SVGNames::svgNamespaceURI) {
- doc = SVGDocument::create(init);
+ doc = XMLDocument::createSVG(init);
} else if (namespaceURI == HTMLNames::xhtmlNamespaceURI) {
- doc = Document::createXHTML(init.withRegistrationContext(m_document.registrationContext()));
+ doc = XMLDocument::createXHTML(init.withRegistrationContext(document().registrationContext()));
} else {
- doc = Document::create(init);
+ doc = XMLDocument::create(init);
}
- doc->setSecurityOrigin(m_document.securityOrigin()->isolatedCopy());
- doc->setContextFeatures(m_document.contextFeatures());
+ doc->setSecurityOrigin(document().securityOrigin()->isolatedCopy());
+ doc->setContextFeatures(document().contextFeatures());
- RefPtr<Node> documentElement;
+ RefPtrWillBeRawPtr<Node> documentElement = nullptr;
if (!qualifiedName.isEmpty()) {
documentElement = doc->createElementNS(namespaceURI, qualifiedName, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
}
if (doctype)
@@ -224,33 +228,21 @@ PassRefPtr<Document> DOMImplementation::createDocument(const AtomicString& names
return doc.release();
}
-PassRefPtr<CSSStyleSheet> DOMImplementation::createCSSStyleSheet(const String&, const String& media)
-{
- // FIXME: Title should be set.
- // FIXME: Media could have wrong syntax, in which case we should generate an exception.
- RefPtr<CSSStyleSheet> sheet = CSSStyleSheet::create(StyleSheetContents::create());
- sheet->setMediaQueries(MediaQuerySet::create(media));
- return sheet;
-}
-
bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
- if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
+ if (equalIgnoringCase(mimeType, "text/xml")
+ || equalIgnoringCase(mimeType, "application/xml")
+ || equalIgnoringCase(mimeType, "text/xsl"))
return true;
- // Per RFCs 3023 and 2045 a mime type is of the form:
+ // Per RFCs 3023 and 2045, an XML MIME type is of the form:
// ^[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+/[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+\+xml$
int length = mimeType.length();
if (length < 7)
return false;
- if (mimeType[0] == '/' ||
- mimeType[length - 5] == '/' ||
- mimeType[length - 4] != '+' ||
- mimeType[length - 3] != 'x' ||
- mimeType[length - 2] != 'm' ||
- mimeType[length - 1] != 'l')
+ if (mimeType[0] == '/' || mimeType[length - 5] == '/' || !mimeType.endsWith("+xml", false))
return false;
bool hasSlash = false;
@@ -294,37 +286,58 @@ bool DOMImplementation::isXMLMIMEType(const String& mimeType)
return true;
}
-bool DOMImplementation::isTextMIMEType(const String& mimeType)
+bool DOMImplementation::isJSONMIMEType(const String& mimeType)
{
- if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType)
- || mimeType == "application/json" // Render JSON as text/plain.
- || (mimeType.startsWith("text/") && mimeType != "text/html"
- && mimeType != "text/xml" && mimeType != "text/xsl"))
+ if (mimeType.startsWith("application/json", false))
return true;
-
+ if (mimeType.startsWith("application/", false)) {
+ size_t subtype = mimeType.find("+json", 12, false);
+ if (subtype != kNotFound) {
+ // Just check that a parameter wasn't matched.
+ size_t parameterMarker = mimeType.find(";");
+ if (parameterMarker == kNotFound) {
+ unsigned endSubtype = static_cast<unsigned>(subtype) + 5;
+ return endSubtype == mimeType.length() || isASCIISpace(mimeType[endSubtype]);
+ }
+ return parameterMarker > subtype;
+ }
+ }
return false;
}
-PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
+static bool isTextPlainType(const String& mimeType)
+{
+ return mimeType.startsWith("text/", false)
+ && !(equalIgnoringCase(mimeType, "text/html")
+ || equalIgnoringCase(mimeType, "text/xml")
+ || equalIgnoringCase(mimeType, "text/xsl"));
+}
+
+bool DOMImplementation::isTextMIMEType(const String& mimeType)
{
- DocumentInit init = DocumentInit::fromContext(m_document.contextDocument())
- .withRegistrationContext(m_document.registrationContext());
- RefPtr<HTMLDocument> d = HTMLDocument::create(init);
+ return MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || isJSONMIMEType(mimeType) || isTextPlainType(mimeType);
+}
+
+PassRefPtrWillBeRawPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
+{
+ DocumentInit init = DocumentInit::fromContext(document().contextDocument())
+ .withRegistrationContext(document().registrationContext());
+ RefPtrWillBeRawPtr<HTMLDocument> d = HTMLDocument::create(init);
d->open();
d->write("<!doctype html><html><body></body></html>");
if (!title.isNull())
d->setTitle(title);
- d->setSecurityOrigin(m_document.securityOrigin()->isolatedCopy());
- d->setContextFeatures(m_document.contextFeatures());
+ d->setSecurityOrigin(document().securityOrigin()->isolatedCopy());
+ d->setContextFeatures(document().contextFeatures());
return d.release();
}
-PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, const KURL& url, bool inViewSourceMode)
+PassRefPtrWillBeRawPtr<Document> DOMImplementation::createDocument(const String& type, LocalFrame* frame, const KURL& url, bool inViewSourceMode)
{
return createDocument(type, DocumentInit(url, frame), inViewSourceMode);
}
-PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const DocumentInit& init, bool inViewSourceMode)
+PassRefPtrWillBeRawPtr<Document> DOMImplementation::createDocument(const String& type, const DocumentInit& init, bool inViewSourceMode)
{
if (inViewSourceMode)
return HTMLViewSourceDocument::create(init, type);
@@ -333,7 +346,7 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const
if (type == "text/html")
return HTMLDocument::create(init);
if (type == "application/xhtml+xml")
- return Document::createXHTML(init);
+ return XMLDocument::createXHTML(init);
PluginData* pluginData = 0;
if (init.frame() && init.frame()->page() && init.frame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
@@ -358,11 +371,16 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const
if (isTextMIMEType(type))
return TextDocument::create(init);
if (type == "image/svg+xml")
- return SVGDocument::create(init);
+ return XMLDocument::createSVG(init);
if (isXMLMIMEType(type))
- return Document::create(init);
+ return XMLDocument::create(init);
return HTMLDocument::create(init);
}
+void DOMImplementation::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h
index b710d2ad22c..47a6c3212ad 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h
@@ -25,7 +25,6 @@
#define DOMImplementation_h
#include "core/dom/Document.h"
-#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -35,43 +34,48 @@ class Document;
class DocumentInit;
class DocumentType;
class ExceptionState;
-class Frame;
+class LocalFrame;
class HTMLDocument;
class KURL;
+class XMLDocument;
-class DOMImplementation : public ScriptWrappable {
- WTF_MAKE_FAST_ALLOCATED;
+class DOMImplementation FINAL : public NoBaseWillBeGarbageCollectedFinalized<DOMImplementation>, public ScriptWrappable {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<DOMImplementation> create(Document& document) { return adoptPtr(new DOMImplementation(document)); }
-
- void ref() { m_document.ref(); }
- void deref() { m_document.deref(); }
- Document* document() { return &m_document; }
+ static PassOwnPtrWillBeRawPtr<DOMImplementation> create(Document& document)
+ {
+ return adoptPtrWillBeNoop(new DOMImplementation(document));
+ }
+
+#if !ENABLE(OILPAN)
+ void ref() { m_document->ref(); }
+ void deref() { m_document->deref(); }
+#endif
+ Document& document() const { return *m_document; }
// DOM methods & attributes for DOMImplementation
static bool hasFeature(const String& feature, const String& version);
- PassRefPtr<DocumentType> createDocumentType(const AtomicString& qualifiedName, const String& publicId, const String& systemId, ExceptionState&);
- PassRefPtr<Document> createDocument(const AtomicString& namespaceURI, const AtomicString& qualifiedName, DocumentType*, ExceptionState&);
-
- DOMImplementation* getInterface(const String& feature);
-
- // From the DOMImplementationCSS interface
- static PassRefPtr<CSSStyleSheet> createCSSStyleSheet(const String& title, const String& media);
+ bool hasFeatureForBindings(const String& feature, const String& version);
+ PassRefPtrWillBeRawPtr<DocumentType> createDocumentType(const AtomicString& qualifiedName, const String& publicId, const String& systemId, ExceptionState&);
+ PassRefPtrWillBeRawPtr<XMLDocument> createDocument(const AtomicString& namespaceURI, const AtomicString& qualifiedName, DocumentType*, ExceptionState&);
// From the HTMLDOMImplementation interface
- PassRefPtr<HTMLDocument> createHTMLDocument(const String& title);
+ PassRefPtrWillBeRawPtr<HTMLDocument> createHTMLDocument(const String& title);
// Other methods (not part of DOM)
- static PassRefPtr<Document> createDocument(const String& MIMEType, Frame*, const KURL&, bool inViewSourceMode);
- static PassRefPtr<Document> createDocument(const String& type, const DocumentInit&, bool inViewSourceMode);
+ static PassRefPtrWillBeRawPtr<Document> createDocument(const String& mimeType, LocalFrame*, const KURL&, bool inViewSourceMode);
+ static PassRefPtrWillBeRawPtr<Document> createDocument(const String& mimeType, const DocumentInit&, bool inViewSourceMode);
+
+ static bool isXMLMIMEType(const String&);
+ static bool isTextMIMEType(const String&);
+ static bool isJSONMIMEType(const String&);
- static bool isXMLMIMEType(const String& MIMEType);
- static bool isTextMIMEType(const String& MIMEType);
+ void trace(Visitor*);
private:
explicit DOMImplementation(Document&);
- Document& m_document;
+ RawPtrWillBeMember<Document> m_document;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl
index 7630c5e5fbd..472d1b0998f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl
@@ -19,11 +19,13 @@
*/
[
- GenerateVisitDOMWrapper=document,
+ SetWrapperReferenceFrom=document,
+ WillBeGarbageCollected,
] interface DOMImplementation {
// DOM Level 1
+ [ImplementedAs=hasFeatureForBindings, MeasureAs=DOMImplementationHasFeature]
boolean hasFeature(DOMString feature, [TreatNullAs=NullString] DOMString version);
// DOM Level 2
@@ -31,17 +33,11 @@
[RaisesException] DocumentType createDocumentType(DOMString qualifiedName,
DOMString publicId,
DOMString systemId);
- [RaisesException] Document createDocument([TreatNullAs=NullString] DOMString namespaceURI,
- [TreatNullAs=NullString] DOMString qualifiedName,
- [Default=Undefined] optional DocumentType doctype);
-
- // DOMImplementationCSS interface from DOM Level 2 CSS
-
- [MeasureAs=DOMImplementationCreateCSSStyleSheet]
- CSSStyleSheet createCSSStyleSheet([Default=Undefined] optional DOMString title,
- [Default=Undefined] optional DOMString media);
+ [RaisesException] XMLDocument createDocument([TreatNullAs=NullString] DOMString namespaceURI,
+ [TreatNullAs=NullString] DOMString qualifiedName,
+ [Default=Undefined] optional DocumentType doctype);
// HTMLDOMImplementation interface from DOM Level 2 HTML
- HTMLDocument createHTMLDocument([Default=NullString] optional DOMString title);
+ HTMLDocument createHTMLDocument(optional DOMString title = null);
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp
new file mode 100644
index 00000000000..73b2f8d1dc0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/DOMImplementation.h"
+
+#include "wtf/text/WTFString.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(DOMImplementationTest, TextMIMEType)
+{
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("text/plain"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("text/javascript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("TEXT/JavaScript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/jSON"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json;foo=2"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json "));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/+json"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-javascript-like+json;a=2;c=4"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/javascript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("Application/Javascript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-custom+json;b=3"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-custom+json"));
+ // Outside of RFC-2045 grammar, but robustly accept/allow.
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-what+json;"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json;"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json "));
+
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom;a=a+json"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom;a=a+json ;"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom+jsonsoup"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom+jsonsoup "));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("text/html"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("text/xml"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("text/xsl"));
+}
+
+TEST(DOMImplementationTest, TextXMLType)
+{
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("text/xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("Text/xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("tEXt/XML"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/XML"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/x-tra+xML"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/xslt+xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/rdf+Xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("image/svg+xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("text/xsl"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("text/XSL"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/x+xml"));
+
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom;a=a+xml"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom;a=a+xml ;"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom+xml2"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom+xml2 "));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom+exml"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("text/html"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/xml;"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/xml "));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-what+xml;"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-tra+xML;a=2"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/+xML"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/+xml"));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp
deleted file mode 100644
index 9fbf981ff46..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include "config.h"
-#include "core/dom/DOMNamedFlowCollection.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/NamedFlow.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-DOMNamedFlowCollection::DOMNamedFlowCollection(const Vector<NamedFlow*>& namedFlows)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- ScriptWrappable::init(this);
- for (Vector<NamedFlow*>::const_iterator it = namedFlows.begin(); it != namedFlows.end(); ++it)
- m_namedFlows.add(*it);
-}
-
-unsigned long DOMNamedFlowCollection::length() const
-{
- return m_namedFlows.size();
-}
-
-PassRefPtr<NamedFlow> DOMNamedFlowCollection::item(unsigned long index) const
-{
- if (index >= static_cast<unsigned long>(m_namedFlows.size()))
- return 0;
- DOMNamedFlowSet::const_iterator it = m_namedFlows.begin();
- for (unsigned long i = 0; i < index; ++i)
- ++it;
- return *it;
-}
-
-PassRefPtr<NamedFlow> DOMNamedFlowCollection::namedItem(const AtomicString& name) const
-{
- DOMNamedFlowSet::const_iterator it = m_namedFlows.find<DOMNamedFlowHashTranslator, String>(name);
- if (it != m_namedFlows.end())
- return *it;
- return 0;
-}
-
-bool DOMNamedFlowCollection::hasNamedItem(const AtomicString& name) const
-{
- return namedItem(name);
-}
-
-// The HashFunctions object used by the HashSet to compare between RefPtr<NamedFlows>.
-// It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values.
-struct DOMNamedFlowCollection::DOMNamedFlowHashFunctions {
- static unsigned hash(PassRefPtr<NamedFlow> key) { return DefaultHash<String>::Hash::hash(key->name()); }
- static bool equal(PassRefPtr<NamedFlow> a, PassRefPtr<NamedFlow> b) { return a->name() == b->name(); }
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-// The HashTranslator is used to lookup a RefPtr<NamedFlow> in the set using a name.
-struct DOMNamedFlowCollection::DOMNamedFlowHashTranslator {
- static unsigned hash(const String& key) { return DefaultHash<String>::Hash::hash(key); }
- static bool equal(PassRefPtr<NamedFlow> a, const String& b) { return a->name() == b; }
-};
-} // namespace WebCore
-
-
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h b/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h
deleted file mode 100644
index c7e6a6c20af..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef DOMNamedFlowCollection_h
-#define DOMNamedFlowCollection_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/NamedFlowCollection.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Document;
-class NamedFlow;
-
-class DOMNamedFlowCollection : public ScriptWrappable, public RefCounted<DOMNamedFlowCollection> {
-public:
- static PassRefPtr<DOMNamedFlowCollection> create(const Vector<NamedFlow*>& namedFlows)
- {
- return adoptRef(new DOMNamedFlowCollection(namedFlows));
- }
-
- unsigned long length() const;
- PassRefPtr<NamedFlow> item(unsigned long index) const;
- PassRefPtr<NamedFlow> namedItem(const AtomicString& name) const;
-
- bool hasNamedItem(const AtomicString& name) const;
-
-private:
- struct DOMNamedFlowHashFunctions;
- struct DOMNamedFlowHashTranslator;
-
- typedef ListHashSet<RefPtr<NamedFlow>, 1, DOMNamedFlowHashFunctions> DOMNamedFlowSet;
- explicit DOMNamedFlowCollection(const Vector<NamedFlow*>&);
- DOMNamedFlowSet m_namedFlows;
-};
-
-} // namespace WebCore
-#endif
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp
index 2d69533d6b3..07098c9d5e3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp
@@ -58,9 +58,9 @@ void DOMSettableTokenList::add(const Vector<String>& tokens, ExceptionState& exc
for (size_t i = 0; i < tokens.size(); ++i) {
if (m_tokens.isNull())
- m_tokens.set(tokens[i], false);
+ m_tokens.set(AtomicString(tokens[i]), false);
else
- m_tokens.add(tokens[i]);
+ m_tokens.add(AtomicString(tokens[i]));
}
}
@@ -77,7 +77,7 @@ void DOMSettableTokenList::remove(const Vector<String>& tokens, ExceptionState&
{
DOMTokenList::remove(tokens, exceptionState);
for (size_t i = 0; i < tokens.size(); ++i)
- m_tokens.remove(tokens[i]);
+ m_tokens.remove(AtomicString(tokens[i]));
}
void DOMSettableTokenList::removeInternal(const AtomicString& token)
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h
index 234b505f785..bba9691d7a6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h
@@ -27,6 +27,7 @@
#include "core/dom/DOMTokenList.h"
#include "core/dom/SpaceSplitString.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/AtomicString.h"
@@ -34,17 +35,24 @@ namespace WebCore {
class ExceptionState;
-class DOMSettableTokenList : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
- WTF_MAKE_FAST_ALLOCATED;
+class DOMSettableTokenList FINAL
+ : public DOMTokenList
+#if !ENABLE(OILPAN)
+ , public RefCounted<DOMSettableTokenList>
+#endif
+ {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<DOMSettableTokenList> create()
+ static PassRefPtrWillBeRawPtr<DOMSettableTokenList> create()
{
- return adoptRef(new DOMSettableTokenList());
+ return adoptRefWillBeNoop(new DOMSettableTokenList());
}
virtual ~DOMSettableTokenList();
+#if !ENABLE(OILPAN)
virtual void ref() OVERRIDE { RefCounted<DOMSettableTokenList>::ref(); }
virtual void deref() OVERRIDE { RefCounted<DOMSettableTokenList>::deref(); }
+#endif
virtual unsigned length() const OVERRIDE { return m_tokens.size(); }
virtual const AtomicString item(unsigned index) const OVERRIDE;
@@ -52,7 +60,7 @@ public:
virtual void add(const Vector<String>&, ExceptionState&) OVERRIDE;
virtual void remove(const Vector<String>&, ExceptionState&) OVERRIDE;
- virtual AtomicString value() const OVERRIDE { return m_value; }
+ virtual const AtomicString& value() const OVERRIDE { return m_value; }
virtual void setValue(const AtomicString&) OVERRIDE;
const SpaceSplitString& tokens() const { return m_tokens; }
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl
index 18142d0e751..e02dd6950ac 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl
@@ -23,7 +23,7 @@
*/
interface DOMSettableTokenList : DOMTokenList {
- [TreatReturnedNullStringAs=Null, ImplementedAs=item] getter DOMString(unsigned long index);
+ [TreatReturnedNullStringAs=Null, ImplementedAs=item] getter DOMString (unsigned long index);
attribute DOMString value;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h
index 44de3447398..dd605cd3b56 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h
@@ -27,6 +27,7 @@
#define DOMStringList_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -36,11 +37,11 @@ namespace WebCore {
// FIXME: Some consumers of this class may benefit from lazily fetching items rather
// than creating the list statically as is currently the only option.
-class DOMStringList : public ScriptWrappable, public RefCounted<DOMStringList> {
+class DOMStringList FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMStringList>, public ScriptWrappable {
public:
- static PassRefPtr<DOMStringList> create()
+ static PassRefPtrWillBeRawPtr<DOMStringList> create()
{
- return adoptRef(new DOMStringList());
+ return adoptRefWillBeNoop(new DOMStringList());
}
bool isEmpty() const { return m_strings.isEmpty(); }
@@ -55,6 +56,8 @@ public:
operator const Vector<String>&() const { return m_strings; }
+ void trace(Visitor*) { }
+
private:
DOMStringList()
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl
index 1c75bcb8d7c..8a570878796 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl
@@ -24,9 +24,9 @@
*/
[
+ WillBeGarbageCollected,
] interface DOMStringList {
readonly attribute unsigned long length;
[TreatReturnedNullStringAs=Null] getter DOMString item([Default=Undefined] optional unsigned long index);
- boolean contains([Default=Undefined] optional DOMString string);
+ [MeasureAs=DOMStringListContains] boolean contains([Default=Undefined] optional DOMString string);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h
index 22ce97497f1..83095794734 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h
@@ -28,6 +28,8 @@
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptWrappable.h"
+#include "bindings/v8/V8Binding.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
@@ -36,36 +38,31 @@ namespace WebCore {
class Element;
-class DOMStringMap : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DOMStringMap); WTF_MAKE_FAST_ALLOCATED;
+class DOMStringMap : public NoBaseWillBeGarbageCollectedFinalized<DOMStringMap>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(DOMStringMap);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
virtual ~DOMStringMap();
+#if !ENABLE(OILPAN)
virtual void ref() = 0;
virtual void deref() = 0;
+#endif
virtual void getNames(Vector<String>&) = 0;
virtual String item(const String& name) = 0;
virtual bool contains(const String& name) = 0;
virtual void setItem(const String& name, const String& value, ExceptionState&) = 0;
- virtual void deleteItem(const String& name, ExceptionState&) = 0;
+ virtual bool deleteItem(const String& name) = 0;
bool anonymousNamedSetter(const String& name, const String& value, ExceptionState& exceptionState)
{
setItem(name, value, exceptionState);
return true;
}
- bool anonymousNamedDeleter(const AtomicString& name, ExceptionState&)
+ DeleteResult anonymousNamedDeleter(const AtomicString& name)
{
- // FIXME: Remove ExceptionState parameter.
-
- TrackExceptionState exceptionState;
- deleteItem(name, exceptionState);
- bool result = !exceptionState.hadException();
- // DOMStringMap deleter should ignore exception.
- // Behavior of Firefox and Opera are same.
- // delete document.body.dataset["-foo"] // false instead of DOM Exception 12
- // LayoutTests/fast/dom/HTMLSelectElement/select-selectedIndex-multiple.html
- return result;
+ bool knownProperty = deleteItem(name);
+ return knownProperty ? DeleteSuccess : DeleteUnknownProperty;
}
void namedPropertyEnumerator(Vector<String>& names, ExceptionState&)
{
@@ -81,13 +78,15 @@ public:
{
return anonymousNamedSetter(String::number(index), value, exceptionState);
}
- bool anonymousIndexedDeleter(uint32_t index, ExceptionState& exceptionState)
+ DeleteResult anonymousIndexedDeleter(uint32_t index)
{
- return anonymousNamedDeleter(AtomicString::number(index), exceptionState);
+ return anonymousNamedDeleter(AtomicString::number(index));
}
virtual Element* element() = 0;
+ virtual void trace(Visitor*) { }
+
protected:
DOMStringMap()
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl
index fcbbf899d42..c8c7d15fc17 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl
@@ -24,13 +24,15 @@
*/
[
- GenerateVisitDOMWrapper=element,
+ OverrideBuiltins,
+ SetWrapperReferenceFrom=element,
+ WillBeGarbageCollected,
] interface DOMStringMap {
- [ImplementedAs=anonymousIndexedGetter, NotEnumerable] getter DOMString (unsigned long index);
- [ImplementedAs=anonymousIndexedSetter, RaisesException, NotEnumerable] setter DOMString (unsigned long index, DOMString value);
- [ImplementedAs=anonymousIndexedDeleter, RaisesException, NotEnumerable] deleter boolean (unsigned long index);
- [ImplementedAs=item, OverrideBuiltins] getter DOMString (DOMString name);
- [ImplementedAs=anonymousNamedSetter, RaisesException, OverrideBuiltins] setter DOMString (DOMString name, DOMString value);
- [ImplementedAs=anonymousNamedDeleter, RaisesException] deleter boolean (DOMString name);
-};
+ [NotEnumerable] getter DOMString (unsigned long index);
+ [RaisesException] setter DOMString (unsigned long index, DOMString value);
+ deleter boolean (unsigned long index);
+ [ImplementedAs=item] getter DOMString (DOMString name);
+ [RaisesException] setter DOMString (DOMString name, DOMString value);
+ deleter boolean (DOMString name);
+};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
index 41255b2b170..d4aa1a50605 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-bool DOMTokenList::validateToken(const AtomicString& token, ExceptionState& exceptionState)
+bool DOMTokenList::validateToken(const String& token, ExceptionState& exceptionState)
{
if (token.isEmpty()) {
exceptionState.throwDOMException(SyntaxError, "The token provided must not be empty.");
@@ -74,6 +74,8 @@ void DOMTokenList::add(const AtomicString& token, ExceptionState& exceptionState
add(tokens, exceptionState);
}
+// Optimally, this should take a Vector<AtomicString> const ref in argument but the
+// bindings generator does not handle that.
void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionState)
{
Vector<String> filteredTokens;
@@ -81,7 +83,7 @@ void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionSt
for (size_t i = 0; i < tokens.size(); ++i) {
if (!validateToken(tokens[i], exceptionState))
return;
- if (containsInternal(tokens[i]))
+ if (containsInternal(AtomicString(tokens[i])))
continue;
if (filteredTokens.contains(tokens[i]))
continue;
@@ -101,6 +103,8 @@ void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionSt
remove(tokens, exceptionState);
}
+// Optimally, this should take a Vector<AtomicString> const ref in argument but the
+// bindings generator does not handle that.
void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptionState)
{
if (!validateTokens(tokens, exceptionState))
@@ -110,7 +114,7 @@ void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptio
// through the string character by character.
bool found = false;
for (size_t i = 0; i < tokens.size(); ++i) {
- if (containsInternal(tokens[i])) {
+ if (containsInternal(AtomicString(tokens[i]))) {
found = true;
break;
}
@@ -161,14 +165,16 @@ void DOMTokenList::removeInternal(const AtomicString& token)
setValue(removeToken(value(), token));
}
-String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
+AtomicString DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
{
Vector<String> tokens;
tokens.append(token.string());
return addTokens(input, tokens);
}
-String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens)
+// This returns an AtomicString because it is always passed as argument to setValue() and setValue()
+// takes an AtomicString in argument.
+AtomicString DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens)
{
bool needsSpace = false;
@@ -185,17 +191,19 @@ String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>&
needsSpace = true;
}
- return builder.toString();
+ return builder.toAtomicString();
}
-String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token)
+AtomicString DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token)
{
Vector<String> tokens;
tokens.append(token.string());
return removeTokens(input, tokens);
}
-String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens)
+// This returns an AtomicString because it is always passed as argument to setValue() and setValue()
+// takes an AtomicString in argument.
+AtomicString DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens)
{
// Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string
// New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string
@@ -238,7 +246,7 @@ String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String
}
}
- return output.toString();
+ return output.toAtomicString();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h
index d758214d09a..1ab1b7c2a5d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h
@@ -26,6 +26,7 @@
#define DOMTokenList_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicString.h"
@@ -34,17 +35,20 @@ namespace WebCore {
class Element;
class ExceptionState;
-class DOMTokenList : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DOMTokenList); WTF_MAKE_FAST_ALLOCATED;
+class DOMTokenList : public NoBaseWillBeGarbageCollectedFinalized<DOMTokenList>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(DOMTokenList);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
DOMTokenList()
{
ScriptWrappable::init(this);
}
- virtual ~DOMTokenList() { };
+ virtual ~DOMTokenList() { }
+#if !ENABLE(OILPAN)
virtual void ref() = 0;
virtual void deref() = 0;
+#endif
virtual unsigned length() const = 0;
virtual const AtomicString item(unsigned index) const = 0;
@@ -57,24 +61,26 @@ public:
bool toggle(const AtomicString&, ExceptionState&);
bool toggle(const AtomicString&, bool force, ExceptionState&);
- AtomicString toString() const { return value(); }
+ const AtomicString& toString() const { return value(); }
virtual Element* element() { return 0; }
+ virtual void trace(Visitor*) { }
+
protected:
- virtual AtomicString value() const = 0;
+ virtual const AtomicString& value() const = 0;
virtual void setValue(const AtomicString&) = 0;
virtual void addInternal(const AtomicString&);
virtual bool containsInternal(const AtomicString&) const = 0;
virtual void removeInternal(const AtomicString&);
- static bool validateToken(const AtomicString&, ExceptionState&);
+ static bool validateToken(const String&, ExceptionState&);
static bool validateTokens(const Vector<String>&, ExceptionState&);
- static String addToken(const AtomicString&, const AtomicString&);
- static String addTokens(const AtomicString&, const Vector<String>&);
- static String removeToken(const AtomicString&, const AtomicString&);
- static String removeTokens(const AtomicString&, const Vector<String>&);
+ static AtomicString addToken(const AtomicString&, const AtomicString&);
+ static AtomicString addTokens(const AtomicString&, const Vector<String>&);
+ static AtomicString removeToken(const AtomicString&, const AtomicString&);
+ static AtomicString removeTokens(const AtomicString&, const Vector<String>&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl
index 9830b7ec93d..98d51cff129 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl
@@ -23,7 +23,8 @@
*/
[
- GenerateVisitDOMWrapper=element,
+ SetWrapperReferenceFrom=element,
+ WillBeGarbageCollected,
] interface DOMTokenList {
readonly attribute unsigned long length;
[TreatReturnedNullStringAs=Null] getter DOMString item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp
index 8881223f724..feba9b94942 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp
@@ -63,20 +63,24 @@ void DOMURL::setInput(const String& value)
}
}
-String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob)
+String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob, ExceptionState& exceptionState)
{
if (!executionContext || !blob)
return String();
- return createPublicURL(executionContext, blob);
+ if (blob->hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed.");
+ return String();
+ }
+ return createPublicURL(executionContext, blob, blob->uuid());
}
-String DOMURL::createPublicURL(ExecutionContext* executionContext, URLRegistrable* registrable)
+String DOMURL::createPublicURL(ExecutionContext* executionContext, URLRegistrable* registrable, const String& uuid)
{
KURL publicURL = BlobURL::createPublicURL(executionContext->securityOrigin());
if (publicURL.isEmpty())
return String();
- executionContext->publicURLManager().registerURL(executionContext->securityOrigin(), publicURL, registrable);
+ executionContext->publicURLManager().registerURL(executionContext->securityOrigin(), publicURL, registrable, uuid);
return publicURL.string();
}
@@ -91,4 +95,12 @@ void DOMURL::revokeObjectURL(ExecutionContext* executionContext, const String& u
executionContext->publicURLManager().revoke(url);
}
+void DOMURL::revokeObjectUUID(ExecutionContext* executionContext, const String& uuid)
+{
+ if (!executionContext)
+ return;
+
+ executionContext->publicURLManager().revoke(uuid);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURL.h b/chromium/third_party/WebKit/Source/core/dom/DOMURL.h
index 2b112f7d966..534cae2d23e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURL.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURL.h
@@ -29,11 +29,9 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMURLUtils.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -42,27 +40,27 @@ class ExceptionState;
class ExecutionContext;
class URLRegistrable;
-class DOMURL FINAL : public ScriptWrappable, public DOMURLUtils, public RefCounted<DOMURL> {
-
+class DOMURL FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMURL>, public ScriptWrappable, public DOMURLUtils {
public:
- static PassRefPtr<DOMURL> create(const String& url, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, ExceptionState& exceptionState)
{
- return adoptRef(new DOMURL(url, blankURL(), exceptionState));
+ return adoptRefWillBeNoop(new DOMURL(url, blankURL(), exceptionState));
}
- static PassRefPtr<DOMURL> create(const String& url, const String& base, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, const String& base, ExceptionState& exceptionState)
{
- return adoptRef(new DOMURL(url, KURL(KURL(), base), exceptionState));
+ return adoptRefWillBeNoop(new DOMURL(url, KURL(KURL(), base), exceptionState));
}
- static PassRefPtr<DOMURL> create(const String& url, PassRefPtr<DOMURL> base, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, PassRefPtrWillBeRawPtr<DOMURL> base, ExceptionState& exceptionState)
{
ASSERT(base);
- return adoptRef(new DOMURL(url, base->m_url, exceptionState));
+ return adoptRefWillBeNoop(new DOMURL(url, base->m_url, exceptionState));
}
- static String createObjectURL(ExecutionContext*, Blob*);
+ static String createObjectURL(ExecutionContext*, Blob*, ExceptionState&);
static void revokeObjectURL(ExecutionContext*, const String&);
- static String createPublicURL(ExecutionContext*, URLRegistrable*);
+ static String createPublicURL(ExecutionContext*, URLRegistrable*, const String& uuid = String());
+ static void revokeObjectUUID(ExecutionContext*, const String&);
virtual KURL url() const OVERRIDE { return m_url; }
virtual void setURL(const KURL& url) OVERRIDE { m_url = url; }
@@ -70,6 +68,8 @@ public:
virtual String input() const OVERRIDE { return m_input; }
virtual void setInput(const String&) OVERRIDE;
+ void trace(Visitor*) { }
+
private:
DOMURL(const String& url, const KURL& base, ExceptionState&);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp
index 7e1fa195c5a..ead850c3511 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp
@@ -31,55 +31,55 @@
namespace WebCore {
-void DOMURLUtils::setHref(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHref(const String& value)
{
- impl->setInput(value);
+ setInput(value);
}
-void DOMURLUtils::setProtocol(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setProtocol(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
- url.setProtocol(value);
- impl->setURL(url);
+ kurl.setProtocol(value);
+ setURL(kurl);
}
-void DOMURLUtils::setUsername(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setUsername(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
- url.setUser(value);
- impl->setURL(url);
+ kurl.setUser(value);
+ setURL(kurl);
}
-void DOMURLUtils::setPassword(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPassword(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
- url.setPass(value);
- impl->setURL(url);
+ kurl.setPass(value);
+ setURL(kurl);
}
-void DOMURLUtils::setHost(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHost(const String& value)
{
if (value.isEmpty())
return;
- KURL url = impl->url();
- if (!url.canSetHostOrPort())
+ KURL kurl = url();
+ if (!kurl.canSetHostOrPort())
return;
- url.setHostAndPort(value);
- impl->setURL(url);
+ kurl.setHostAndPort(value);
+ setURL(kurl);
}
-void DOMURLUtils::setHostname(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHostname(const String& value)
{
- KURL url = impl->url();
- if (!url.canSetHostOrPort())
+ KURL kurl = url();
+ if (!kurl.canSetHostOrPort())
return;
// Before setting new value:
@@ -92,51 +92,51 @@ void DOMURLUtils::setHostname(DOMURLUtils* impl, const String& value)
if (i == hostLength)
return;
- url.setHost(value.substring(i));
+ kurl.setHost(value.substring(i));
- impl->setURL(url);
+ setURL(kurl);
}
-void DOMURLUtils::setPort(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPort(const String& value)
{
- KURL url = impl->url();
- if (!url.canSetHostOrPort())
+ KURL kurl = url();
+ if (!kurl.canSetHostOrPort())
return;
- url.setPort(value);
- impl->setURL(url);
+ kurl.setPort(value);
+ setURL(kurl);
}
-void DOMURLUtils::setPathname(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPathname(const String& value)
{
- KURL url = impl->url();
- if (!url.canSetPathname())
+ KURL kurl = url();
+ if (!kurl.canSetPathname())
return;
- url.setPath(value);
- impl->setURL(url);
+ kurl.setPath(value);
+ setURL(kurl);
}
-void DOMURLUtils::setSearch(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setSearch(const String& value)
{
- KURL url = impl->url();
- if (!url.isValid())
+ KURL kurl = url();
+ if (!kurl.isValid())
return;
- url.setQuery(value);
- impl->setURL(url);
+ kurl.setQuery(value);
+ setURL(kurl);
}
-void DOMURLUtils::setHash(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHash(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
if (value[0] == '#')
- url.setFragmentIdentifier(value.substring(1));
+ kurl.setFragmentIdentifier(value.substring(1));
else
- url.setFragmentIdentifier(value);
+ kurl.setFragmentIdentifier(value);
- impl->setURL(url);
+ setURL(kurl);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h
index 1987ecd7205..945a4bc4590 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h
@@ -29,7 +29,6 @@
#include "core/dom/DOMURLUtilsReadOnly.h"
#include "wtf/Forward.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -41,17 +40,17 @@ public:
virtual void setInput(const String&) = 0;
virtual ~DOMURLUtils() { };
- static void setHref(DOMURLUtils*, const String&);
-
- static void setProtocol(DOMURLUtils*, const String&);
- static void setUsername(DOMURLUtils*, const String&);
- static void setPassword(DOMURLUtils*, const String&);
- static void setHost(DOMURLUtils*, const String&);
- static void setHostname(DOMURLUtils*, const String&);
- static void setPort(DOMURLUtils*, const String&);
- static void setPathname(DOMURLUtils*, const String&);
- static void setSearch(DOMURLUtils*, const String&);
- static void setHash(DOMURLUtils*, const String&);
+ void setHref(const String&);
+
+ void setProtocol(const String&);
+ void setUsername(const String&);
+ void setPassword(const String&);
+ void setHost(const String&);
+ void setHostname(const String&);
+ void setPort(const String&);
+ void setPathname(const String&);
+ void setSearch(const String&);
+ void setHash(const String&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp
index 15b1268115a..368eae66207 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp
@@ -32,47 +32,47 @@
namespace WebCore {
-String DOMURLUtilsReadOnly::href(DOMURLUtilsReadOnly* impl)
+String DOMURLUtilsReadOnly::href()
{
- const KURL& url = impl->url();
- if (url.isNull())
- return impl->input();
- return url.string();
+ const KURL& kurl = url();
+ if (kurl.isNull())
+ return input();
+ return kurl.string();
}
-String DOMURLUtilsReadOnly::origin(const KURL& url)
+String DOMURLUtilsReadOnly::origin(const KURL& kurl)
{
- if (url.isNull())
+ if (kurl.isNull())
return "";
- return SecurityOrigin::create(url)->toString();
+ return SecurityOrigin::create(kurl)->toString();
}
-String DOMURLUtilsReadOnly::host(const KURL& url)
+String DOMURLUtilsReadOnly::host(const KURL& kurl)
{
- if (url.hostEnd() == url.pathStart())
- return url.host();
- if (isDefaultPortForProtocol(url.port(), url.protocol()))
- return url.host();
- return url.host() + ":" + String::number(url.port());
+ if (kurl.hostEnd() == kurl.pathStart())
+ return kurl.host();
+ if (isDefaultPortForProtocol(kurl.port(), kurl.protocol()))
+ return kurl.host();
+ return kurl.host() + ":" + String::number(kurl.port());
}
-String DOMURLUtilsReadOnly::port(const KURL& url)
+String DOMURLUtilsReadOnly::port(const KURL& kurl)
{
- if (url.hasPort())
- return String::number(url.port());
+ if (kurl.hasPort())
+ return String::number(kurl.port());
return emptyString();
}
-String DOMURLUtilsReadOnly::search(const KURL& url)
+String DOMURLUtilsReadOnly::search(const KURL& kurl)
{
- String query = url.query();
+ String query = kurl.query();
return query.isEmpty() ? emptyString() : "?" + query;
}
-String DOMURLUtilsReadOnly::hash(const KURL& url)
+String DOMURLUtilsReadOnly::hash(const KURL& kurl)
{
- String fragmentIdentifier = url.fragmentIdentifier();
+ String fragmentIdentifier = kurl.fragmentIdentifier();
if (fragmentIdentifier.isEmpty())
return emptyString();
return AtomicString(String("#" + fragmentIdentifier));
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h
index 36d60851e3e..33b92076c5a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h
@@ -29,7 +29,6 @@
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -39,37 +38,37 @@ public:
virtual String input() const = 0;
virtual ~DOMURLUtilsReadOnly() { };
- static String href(DOMURLUtilsReadOnly*);
+ String href();
static String origin(const KURL&);
- static String origin(DOMURLUtilsReadOnly* impl) { return origin(impl->url()); }
+ String origin() { return origin(url()); }
static String protocol(const KURL& url) { return url.protocol() + ":"; }
- static String protocol(DOMURLUtilsReadOnly* impl) { return protocol(impl->url()); }
+ String protocol() { return protocol(url()); }
static String username(const KURL& url) { return url.user(); }
- static String username(DOMURLUtilsReadOnly* impl) { return username(impl->url()); }
+ String username() { return username(url()); }
static String password(const KURL& url) { return url.pass(); }
- static String password(DOMURLUtilsReadOnly* impl) { return password(impl->url()); }
+ String password() { return password(url()); }
static String host(const KURL&);
- static String host(DOMURLUtilsReadOnly* impl) { return host(impl->url()); }
+ String host() { return host(url()); }
static String hostname(const KURL& url) { return url.host(); }
- static String hostname(DOMURLUtilsReadOnly* impl) { return hostname(impl->url()); }
+ String hostname() { return hostname(url()); }
static String port(const KURL&);
- static String port(DOMURLUtilsReadOnly* impl) { return port(impl->url()); }
+ String port() { return port(url()); }
static String pathname(const KURL& url) { return url.path(); }
- static String pathname(DOMURLUtilsReadOnly* impl) { return pathname(impl->url()); }
+ String pathname() { return pathname(url()); }
static String search(const KURL&);
- static String search(DOMURLUtilsReadOnly* impl) { return search(impl->url()); }
+ String search() { return search(url()); }
static String hash(const KURL&);
- static String hash(DOMURLUtilsReadOnly* impl) { return hash(impl->url()); }
+ String hash() { return hash(url()); }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp b/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp
deleted file mode 100644
index aef76486648..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/DataTransferItem.h"
-
-#include "bindings/v8/V8Binding.h"
-#include "core/dom/Clipboard.h"
-#include "core/dom/StringCallback.h"
-#include "core/platform/chromium/ChromiumDataObjectItem.h"
-#include "wtf/StdLibExtras.h"
-
-namespace WebCore {
-
-PassRefPtr<DataTransferItem> DataTransferItem::create(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObjectItem> item)
-{
- return adoptRef(new DataTransferItem(clipboard, item));
-}
-
-DataTransferItem::~DataTransferItem()
-{
-}
-
-String DataTransferItem::kind() const
-{
- DEFINE_STATIC_LOCAL(const String, kindString, ("string"));
- DEFINE_STATIC_LOCAL(const String, kindFile, ("file"));
- if (!m_clipboard->canReadTypes())
- return String();
- switch (m_item->kind()) {
- case ChromiumDataObjectItem::StringKind:
- return kindString;
- case ChromiumDataObjectItem::FileKind:
- return kindFile;
- }
- ASSERT_NOT_REACHED();
- return String();
-}
-
-String DataTransferItem::type() const
-{
- if (!m_clipboard->canReadTypes())
- return String();
- return m_item->type();
-}
-
-void DataTransferItem::getAsString(ExecutionContext* context, PassOwnPtr<StringCallback> callback) const
-{
- if (!m_clipboard->canReadData())
- return;
-
- m_item->getAsString(callback, context);
-}
-
-PassRefPtr<Blob> DataTransferItem::getAsFile() const
-{
- if (!m_clipboard->canReadData())
- return 0;
-
- return m_item->getAsFile();
-}
-
-DataTransferItem::DataTransferItem(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObjectItem> item)
- : m_clipboard(clipboard)
- , m_item(item)
-{
- ScriptWrappable::init(this);
-}
-
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl b/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl
deleted file mode 100644
index 849965218fc..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject
-] interface DataTransferItem {
- readonly attribute DOMString kind;
- readonly attribute DOMString type;
-
- [CallWith=ExecutionContext] void getAsString(StringCallback? callback);
- Blob getAsFile();
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp b/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp
deleted file mode 100644
index 8facacb9096..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/DataTransferItemList.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/Clipboard.h"
-#include "core/dom/DataTransferItem.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
-
-namespace WebCore {
-
-PassRefPtr<DataTransferItemList> DataTransferItemList::create(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObject> list)
-{
- return adoptRef(new DataTransferItemList(clipboard, list));
-}
-
-DataTransferItemList::~DataTransferItemList()
-{
-}
-
-size_t DataTransferItemList::length() const
-{
- if (!m_clipboard->canReadTypes())
- return 0;
- return m_dataObject->length();
-}
-
-PassRefPtr<DataTransferItem> DataTransferItemList::item(unsigned long index)
-{
- if (!m_clipboard->canReadTypes())
- return 0;
- RefPtr<ChromiumDataObjectItem> item = m_dataObject->item(index);
- if (!item)
- return 0;
-
- return DataTransferItem::create(m_clipboard, item);
-}
-
-void DataTransferItemList::deleteItem(unsigned long index, ExceptionState& exceptionState)
-{
- if (!m_clipboard->canWriteData()) {
- exceptionState.throwDOMException(InvalidStateError, "The list is not writable.");
- return;
- }
- m_dataObject->deleteItem(index);
-}
-
-void DataTransferItemList::clear()
-{
- if (!m_clipboard->canWriteData())
- return;
- m_dataObject->clearAll();
-}
-
-PassRefPtr<DataTransferItem> DataTransferItemList::add(const String& data, const String& type, ExceptionState& exceptionState)
-{
- if (!m_clipboard->canWriteData())
- return 0;
- RefPtr<ChromiumDataObjectItem> item = m_dataObject->add(data, type);
- if (!item) {
- exceptionState.throwDOMException(NotSupportedError, "An item already exists for type '" + type + "'.");
- return 0;
- }
- return DataTransferItem::create(m_clipboard, item);
-}
-
-PassRefPtr<DataTransferItem> DataTransferItemList::add(PassRefPtr<File> file)
-{
- if (!m_clipboard->canWriteData())
- return 0;
- RefPtr<ChromiumDataObjectItem> item = m_dataObject->add(file);
- if (!item)
- return 0;
- return DataTransferItem::create(m_clipboard, item);
-}
-
-DataTransferItemList::DataTransferItemList(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObject> dataObject)
- : m_clipboard(clipboard)
- , m_dataObject(dataObject)
-{
- ScriptWrappable::init(this);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h b/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h
deleted file mode 100644
index f296c7b001a..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DataTransferItemList_h
-#define DataTransferItemList_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class ChromiumDataObject;
-class Clipboard;
-class DataTransferItem;
-class File;
-
-class ExceptionState;
-
-class DataTransferItemList : public RefCounted<DataTransferItemList>, public ScriptWrappable {
-public:
- static PassRefPtr<DataTransferItemList> create(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObject>);
- ~DataTransferItemList();
-
- size_t length() const;
- PassRefPtr<DataTransferItem> item(unsigned long index);
- void deleteItem(unsigned long index, ExceptionState&);
- void clear();
- PassRefPtr<DataTransferItem> add(const String& data, const String& type, ExceptionState&);
- PassRefPtr<DataTransferItem> add(PassRefPtr<File>);
-
-private:
- DataTransferItemList(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObject>);
-
- RefPtr<Clipboard> m_clipboard;
- RefPtr<ChromiumDataObject> m_dataObject;
-};
-
-} // namespace WebCore
-
-#endif // DataTransferItemList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl b/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl
deleted file mode 100644
index 0babe031c24..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface DataTransferItemList {
- readonly attribute long length;
- [ImplementedAs=item] getter DataTransferItem (unsigned long index);
-
- [RaisesException, ImplementedAs=deleteItem] void remove(unsigned long index);
- void clear();
- DataTransferItem add(File? file);
- [RaisesException] DataTransferItem add(DOMString data, DOMString type);
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp
index 921531948ca..7db1bf2b2c4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/dom/DatasetDOMStringMap.h"
-#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/Attribute.h"
#include "core/dom/Element.h"
@@ -71,14 +70,9 @@ static String convertAttributeNameToPropertyName(const String& name)
return stringBuilder.toString();
}
-static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+template<typename CharType1, typename CharType2>
+static bool propertyNameMatchesAttributeName(const CharType1* propertyName, const CharType2* attributeName, unsigned propertyLength, unsigned attributeLength)
{
- if (!attributeName.startsWith("data-"))
- return false;
-
- unsigned propertyLength = propertyName.length();
- unsigned attributeLength = attributeName.length();
-
unsigned a = 5;
unsigned p = 0;
bool wordBoundary = false;
@@ -97,6 +91,25 @@ static bool propertyNameMatchesAttributeName(const String& propertyName, const S
return (a == attributeLength && p == propertyLength);
}
+static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+{
+ if (!attributeName.startsWith("data-"))
+ return false;
+
+ unsigned propertyLength = propertyName.length();
+ unsigned attributeLength = attributeName.length();
+
+ if (propertyName.is8Bit()) {
+ if (attributeName.is8Bit())
+ return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters8(), propertyLength, attributeLength);
+ return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters16(), propertyLength, attributeLength);
+ }
+
+ if (attributeName.is8Bit())
+ return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters8(), propertyLength, attributeLength);
+ return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters16(), propertyLength, attributeLength);
+}
+
static bool isValidPropertyName(const String& name)
{
unsigned length = name.length();
@@ -107,7 +120,9 @@ static bool isValidPropertyName(const String& name)
return true;
}
-static String convertPropertyNameToAttributeName(const String& name)
+// This returns an AtomicString because attribute names are always stored
+// as AtomicString types in Element (see setAttribute()).
+static AtomicString convertPropertyNameToAttributeName(const String& name)
{
StringBuilder builder;
builder.append("data-");
@@ -122,9 +137,10 @@ static String convertPropertyNameToAttributeName(const String& name)
builder.append(character);
}
- return builder.toString();
+ return builder.toAtomicString();
}
+#if !ENABLE(OILPAN)
void DatasetDOMStringMap::ref()
{
m_element->ref();
@@ -134,17 +150,18 @@ void DatasetDOMStringMap::deref()
{
m_element->deref();
}
+#endif
void DatasetDOMStringMap::getNames(Vector<String>& names)
{
if (!m_element->hasAttributes())
return;
- unsigned length = m_element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = m_element->attributeItem(i);
- if (isValidAttributeName(attribute->localName()))
- names.append(convertAttributeNameToPropertyName(attribute->localName()));
+ AttributeCollection attributes = m_element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (isValidAttributeName(it->localName()))
+ names.append(convertAttributeNameToPropertyName(it->localName()));
}
}
@@ -153,11 +170,11 @@ String DatasetDOMStringMap::item(const String& name)
if (!m_element->hasAttributes())
return String();
- unsigned length = m_element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = m_element->attributeItem(i);
- if (propertyNameMatchesAttributeName(name, attribute->localName()))
- return attribute->value();
+ AttributeCollection attributes = m_element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (propertyNameMatchesAttributeName(name, it->localName()))
+ return it->value();
}
return String();
@@ -168,34 +185,41 @@ bool DatasetDOMStringMap::contains(const String& name)
if (!m_element->hasAttributes())
return false;
- unsigned length = m_element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = m_element->attributeItem(i);
- if (propertyNameMatchesAttributeName(name, attribute->localName()))
+ AttributeCollection attributes = m_element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (propertyNameMatchesAttributeName(name, it->localName()))
return true;
}
-
return false;
}
void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionState& exceptionState)
{
if (!isValidPropertyName(name)) {
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet(name, "DOMStringMap", "'" + name + "' is not a valid property name."));
+ exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a valid property name.");
return;
}
- m_element->setAttribute(convertPropertyNameToAttributeName(name), value, exceptionState);
+ m_element->setAttribute(convertPropertyNameToAttributeName(name), AtomicString(value), exceptionState);
}
-void DatasetDOMStringMap::deleteItem(const String& name, ExceptionState& exceptionState)
+bool DatasetDOMStringMap::deleteItem(const String& name)
{
- if (!isValidPropertyName(name)) {
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToDelete(name, "DOMStringMap", "'" + name + "' is not a valid property name."));
- return;
+ if (isValidPropertyName(name)) {
+ AtomicString attributeName = convertPropertyNameToAttributeName(name);
+ if (m_element->hasAttribute(attributeName)) {
+ m_element->removeAttribute(attributeName);
+ return true;
+ }
}
+ return false;
+}
- m_element->removeAttribute(convertPropertyNameToAttributeName(name));
+void DatasetDOMStringMap::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ DOMStringMap::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h
index 9bbd1d09abc..dc31f536ce8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h
@@ -34,23 +34,27 @@ namespace WebCore {
class Element;
class ExceptionState;
-class DatasetDOMStringMap : public DOMStringMap {
+class DatasetDOMStringMap FINAL : public DOMStringMap {
public:
- static PassOwnPtr<DatasetDOMStringMap> create(Element* element)
+ static PassOwnPtrWillBeRawPtr<DatasetDOMStringMap> create(Element* element)
{
- return adoptPtr(new DatasetDOMStringMap(element));
+ return adoptPtrWillBeNoop(new DatasetDOMStringMap(element));
}
- virtual void ref();
- virtual void deref();
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE;
+ virtual void deref() OVERRIDE;
+#endif
- virtual void getNames(Vector<String>&);
- virtual String item(const String& name);
- virtual bool contains(const String& name);
- virtual void setItem(const String& name, const String& value, ExceptionState&);
- virtual void deleteItem(const String& name, ExceptionState&);
+ virtual void getNames(Vector<String>&) OVERRIDE;
+ virtual String item(const String& name) OVERRIDE;
+ virtual bool contains(const String& name) OVERRIDE;
+ virtual void setItem(const String& name, const String& value, ExceptionState&) OVERRIDE;
+ virtual bool deleteItem(const String& name) OVERRIDE;
- virtual Element* element() { return m_element; }
+ virtual Element* element() OVERRIDE { return m_element; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit DatasetDOMStringMap(Element* element)
@@ -58,7 +62,7 @@ private:
{
}
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp
index 7f3c01f23d8..06d32a47d17 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp
@@ -28,13 +28,13 @@
#include "core/dom/Document.h"
#include "core/dom/DocumentEncodingData.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
namespace WebCore {
-DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document)
- : DocumentParser(document)
- , m_hasAppendedData(false)
+DecodedDataDocumentParser::DecodedDataDocumentParser(Document& document)
+ : DocumentParser(&document)
+ , m_needsDecoder(true)
{
}
@@ -44,6 +44,10 @@ DecodedDataDocumentParser::~DecodedDataDocumentParser()
void DecodedDataDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
{
+ // If the decoder is explicitly unset rather than having ownership
+ // transferred away by takeDecoder(), we need to make sure it's recreated
+ // next time data is appended.
+ m_needsDecoder = !decoder;
m_decoder = decoder;
}
@@ -52,9 +56,9 @@ TextResourceDecoder* DecodedDataDocumentParser::decoder()
return m_decoder.get();
}
-void DecodedDataDocumentParser::setHasAppendedData()
+PassOwnPtr<TextResourceDecoder> DecodedDataDocumentParser::takeDecoder()
{
- m_hasAppendedData = true;
+ return m_decoder.release();
}
void DecodedDataDocumentParser::appendBytes(const char* data, size_t length)
@@ -91,22 +95,10 @@ void DecodedDataDocumentParser::flush()
void DecodedDataDocumentParser::updateDocument(String& decodedData)
{
- DocumentEncodingData encodingData;
- encodingData.encoding = m_decoder->encoding();
- encodingData.wasDetectedHeuristically = m_decoder->encodingWasDetectedHeuristically();
- encodingData.sawDecodingError = m_decoder->sawError();
- document()->setEncodingData(encodingData);
+ document()->setEncodingData(DocumentEncodingData(*m_decoder.get()));
- if (decodedData.isEmpty())
- return;
-
- append(decodedData.releaseImpl());
- // FIXME: Should be removed as part of https://code.google.com/p/chromium/issues/detail?id=319643
- if (!m_hasAppendedData) {
- m_hasAppendedData = true;
- if (m_decoder->encoding().usesVisualOrdering())
- document()->setVisuallyOrdered();
- }
+ if (!decodedData.isEmpty())
+ append(decodedData.releaseImpl());
}
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h
index 453147d0ecd..a557399fbd4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h
@@ -28,7 +28,6 @@
#include "core/dom/DocumentParser.h"
#include "wtf/OwnPtr.h"
-#include "wtf/RefPtr.h"
namespace WebCore {
class TextResourceDecoder;
@@ -42,13 +41,14 @@ public:
// The below functions are used by DocumentWriter (the loader).
virtual void appendBytes(const char* bytes, size_t length) OVERRIDE;
virtual void flush() OVERRIDE;
- virtual bool needsDecoder() const OVERRIDE { return !m_decoder; }
+ virtual bool needsDecoder() const OVERRIDE FINAL { return m_needsDecoder; }
virtual void setDecoder(PassOwnPtr<TextResourceDecoder>) OVERRIDE;
- virtual TextResourceDecoder* decoder() OVERRIDE;
- virtual void setHasAppendedData() OVERRIDE;
+ virtual TextResourceDecoder* decoder() OVERRIDE FINAL;
+
+ PassOwnPtr<TextResourceDecoder> takeDecoder();
protected:
- explicit DecodedDataDocumentParser(Document*);
+ explicit DecodedDataDocumentParser(Document&);
virtual ~DecodedDataDocumentParser();
private:
@@ -57,7 +57,7 @@ private:
void updateDocument(String& decodedData);
- bool m_hasAppendedData;
+ bool m_needsDecoder;
OwnPtr<TextResourceDecoder> m_decoder;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.cpp b/chromium/third_party/WebKit/Source/core/dom/Document.cpp
index d1b53da3212..fe9c3b06248 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Document.cpp
@@ -28,25 +28,21 @@
#include "config.h"
#include "core/dom/Document.h"
-#include "HTMLElementFactory.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGElementFactory.h"
-#include "SVGNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
#include "bindings/v8/CustomElementConstructorBuilder.h"
#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
+#include "core/HTMLElementFactory.h"
+#include "core/HTMLNames.h"
+#include "core/SVGElementFactory.h"
+#include "core/SVGNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
-#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/DocumentAnimations.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/animation/css/TransitionTimeline.h"
-#include "core/css/CSSDefaultStyleSheets.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSStyleDeclaration.h"
#include "core/css/CSSStyleSheet.h"
@@ -54,6 +50,8 @@
#include "core/css/StylePropertySet.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/StyleSheetList.h"
+#include "core/css/invalidation/StyleInvalidator.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/FontBuilder.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/css/resolver/StyleResolverStats.h"
@@ -63,19 +61,19 @@
#include "core/dom/Comment.h"
#include "core/dom/ContextFeatures.h"
#include "core/dom/DOMImplementation.h"
-#include "core/dom/DOMNamedFlowCollection.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentLifecycleNotifier.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/DocumentMarkerController.h"
-#include "core/dom/DocumentSharedObjectPool.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
+#include "core/dom/ElementDataCache.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/dom/MainThreadTaskRunner.h"
-#include "core/dom/NamedFlowCollection.h"
+#include "core/dom/MutationObserver.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeChildRemovalTracker.h"
#include "core/dom/NodeFilter.h"
#include "core/dom/NodeIterator.h"
@@ -84,9 +82,9 @@
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/NodeWithIndex.h"
-#include "core/dom/PostAttachCallbacks.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/RequestAnimationFrameCallback.h"
+#include "core/dom/ScriptForbiddenScope.h"
#include "core/dom/ScriptRunner.h"
#include "core/dom/ScriptedAnimationController.h"
#include "core/dom/SelectorQuery.h"
@@ -95,6 +93,7 @@
#include "core/dom/TransformSource.h"
#include "core/dom/TreeWalker.h"
#include "core/dom/VisitedLinkState.h"
+#include "core/dom/XMLDocument.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
@@ -108,18 +107,19 @@
#include "core/events/HashChangeEvent.h"
#include "core/events/PageTransitionEvent.h"
#include "core/events/ScopedEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/History.h"
-#include "core/frame/animation/AnimationController.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/DocumentNameCollection.h"
#include "core/html/HTMLAllCollection.h"
#include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLBaseElement.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDialogElement.h"
@@ -128,20 +128,28 @@
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLLinkElement.h"
-#include "core/html/HTMLNameCollection.h"
+#include "core/html/HTMLMetaElement.h"
#include "core/html/HTMLScriptElement.h"
#include "core/html/HTMLStyleElement.h"
+#include "core/html/HTMLTemplateElement.h"
#include "core/html/HTMLTitleElement.h"
#include "core/html/PluginDocument.h"
+#include "core/html/WindowNameCollection.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/html/canvas/CanvasRenderingContext2D.h"
+#include "core/html/canvas/WebGLRenderingContext.h"
#include "core/html/forms/FormController.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportsController.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/NestingLevelIncrementer.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorCounters.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/loader/CookieJar.h"
#include "core/loader/DocumentLoader.h"
@@ -152,26 +160,28 @@
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/EventHandler.h"
+#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
#include "core/page/MouseEventWithHitTestResults.h"
#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
#include "core/page/PointerLockController.h"
-#include "core/frame/Settings.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidget.h"
#include "core/rendering/TextAutosizer.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGFontFaceElement.h"
-#include "core/svg/SVGStyleElement.h"
+#include "core/svg/SVGUseElement.h"
+#include "core/workers/SharedWorkerRepositoryClient.h"
#include "core/xml/XSLTProcessor.h"
#include "core/xml/parser/XMLDocumentParser.h"
#include "platform/DateComponents.h"
#include "platform/Language.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
#include "platform/network/HTTPParsers.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "platform/text/PlatformLocale.h"
@@ -179,6 +189,7 @@
#include "platform/weborigin/OriginAccessEntry.h"
#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/Platform.h"
#include "wtf/CurrentTime.h"
#include "wtf/HashFunctions.h"
#include "wtf/MainThread.h"
@@ -187,7 +198,6 @@
#include "wtf/text/StringBuffer.h"
#include "wtf/text/TextEncodingRegistry.h"
-using namespace std;
using namespace WTF;
using namespace Unicode;
@@ -285,7 +295,7 @@ static bool shouldInheritSecurityOriginFromOwner(const KURL& url)
// Note: We generalize this to all "blank" URLs and invalid URLs because we
// treat all of these URLs as about:blank.
//
- return url.isEmpty() || url.isBlankURL();
+ return url.isEmpty() || url.protocolIsAbout();
}
static Widget* widgetForElement(const Element& focusedElement)
@@ -303,7 +313,7 @@ static bool acceptsEditingFocus(const Element& element)
return element.document().frame() && element.rootEditableElement();
}
-static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame* targetFrame)
+static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const Frame* targetFrame)
{
// targetFrame can be 0 when we're trying to navigate a top-level frame
// that has a 0 opener.
@@ -311,8 +321,13 @@ static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame*
return false;
const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
- for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
- Document* ancestorDocument = ancestorFrame->document();
+ for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
+ // FIXME: SecurityOrigins need to be refactored to work with out-of-process iframes.
+ // For now we prevent navigation between cross-process frames.
+ if (!ancestorFrame->isLocalFrame())
+ return false;
+
+ Document* ancestorDocument = toLocalFrame(ancestorFrame)->document();
// FIXME: Should be an ASSERT? Frames should alway have documents.
if (!ancestorDocument)
return true;
@@ -331,7 +346,7 @@ static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame*
return false;
}
-static void printNavigationErrorMessage(const Frame& frame, const KURL& activeURL, const char* reason)
+static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& activeURL, const char* reason)
{
String message = "Unsafe JavaScript attempt to initiate navigation for frame with URL '" + frame.document()->url().string() + "' from frame with URL '" + activeURL.string() + "'. " + reason + "\n";
@@ -341,46 +356,76 @@ static void printNavigationErrorMessage(const Frame& frame, const KURL& activeUR
uint64_t Document::s_globalTreeVersion = 0;
-// This class should be passed only to Document::postTask.
-class CheckFocusedElementTask FINAL : public ExecutionContextTask {
+// This class doesn't work with non-Document ExecutionContext.
+class AutofocusTask FINAL : public ExecutionContextTask {
public:
- static PassOwnPtr<CheckFocusedElementTask> create()
+ static PassOwnPtr<AutofocusTask> create()
{
- return adoptPtr(new CheckFocusedElementTask());
+ return adoptPtr(new AutofocusTask());
}
- virtual ~CheckFocusedElementTask() { }
+ virtual ~AutofocusTask() { }
private:
- CheckFocusedElementTask() { }
+ AutofocusTask() { }
virtual void performTask(ExecutionContext* context) OVERRIDE
{
- ASSERT(context->isDocument());
Document* document = toDocument(context);
- document->didRunCheckFocusedElementTask();
- Element* element = document->focusedElement();
- if (!element)
- return;
- if (document->childNeedsStyleRecalc()) {
- document->setNeedsFocusedElementCheck();
- return;
+ if (RefPtrWillBeRawPtr<Element> element = document->autofocusElement()) {
+ document->setAutofocusElement(0);
+ element->focus();
}
- if (element->renderer() && element->renderer()->needsLayout())
- return;
- if (!element->isFocusable())
- document->setFocusedElement(0);
}
};
+DocumentVisibilityObserver::DocumentVisibilityObserver(Document& document)
+ : m_document(nullptr)
+{
+ registerObserver(document);
+}
+
+DocumentVisibilityObserver::~DocumentVisibilityObserver()
+{
+#if !ENABLE(OILPAN)
+ unregisterObserver();
+#endif
+}
+
+void DocumentVisibilityObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+}
+
+void DocumentVisibilityObserver::unregisterObserver()
+{
+ if (m_document) {
+ m_document->unregisterVisibilityObserver(this);
+ m_document = nullptr;
+ }
+}
+
+void DocumentVisibilityObserver::registerObserver(Document& document)
+{
+ ASSERT(!m_document);
+ m_document = &document;
+ if (m_document)
+ m_document->registerVisibilityObserver(this);
+}
+
+void DocumentVisibilityObserver::setObservedDocument(Document& document)
+{
+ unregisterObserver();
+ registerObserver(document);
+}
+
Document::Document(const DocumentInit& initializer, DocumentClassFlags documentClasses)
: ContainerNode(0, CreateDocument)
- , TreeScope(this)
+ , TreeScope(*this)
, m_hasNodesWithPlaceholderStyle(false)
- , m_needsNotifyRemoveAllPendingStylesheet(false)
, m_evaluateMediaQueriesOnStyleRecalc(false)
, m_pendingSheetLayout(NoLayoutWithPendingSheets)
, m_frame(initializer.frame())
, m_domWindow(m_frame ? m_frame->domWindow() : 0)
- , m_import(initializer.import())
+ , m_importsController(initializer.importsController())
, m_activeParserCount(0)
, m_contextFeatures(ContextFeatures::defaultSwitch())
, m_wellFormed(false)
@@ -388,28 +433,27 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
, m_paginatedForScreen(false)
, m_compatibilityMode(NoQuirksMode)
, m_compatibilityModeLocked(false)
- , m_didPostCheckFocusedElementTask(false)
+ , m_executeScriptsWaitingForResourcesTimer(this, &Document::executeScriptsWaitingForResourcesTimerFired)
+ , m_hasAutofocused(false)
+ , m_clearFocusedElementTimer(this, &Document::clearFocusedElementTimerFired)
, m_domTreeVersion(++s_globalTreeVersion)
, m_listenerTypes(0)
, m_mutationObserverTypes(0)
, m_visitedLinkState(VisitedLinkState::create(*this))
, m_visuallyOrdered(false)
, m_readyState(Complete)
- , m_bParsing(false)
- , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
- , m_inStyleRecalc(false)
+ , m_isParsing(false)
, m_gotoAnchorNeededAfterStylesheetsLoad(false)
, m_containsValidityStyleRules(false)
, m_updateFocusAppearanceRestoresSelection(false)
, m_containsPlugins(false)
, m_ignoreDestructiveWriteCount(0)
, m_titleSetExplicitly(false)
- , m_markers(adoptPtr(new DocumentMarkerController))
+ , m_markers(adoptPtrWillBeNoop(new DocumentMarkerController))
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
- , m_cssTarget(0)
+ , m_cssTarget(nullptr)
, m_loadEventProgress(LoadEventNotRun)
, m_startTime(currentTime())
- , m_overMinimumLayoutThreshold(false)
, m_scriptRunner(ScriptRunner::create(this))
, m_xmlVersion("1.0")
, m_xmlStandalone(StandaloneUnspecified)
@@ -423,39 +467,42 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
, m_sawElementsInKnownNamespaces(false)
, m_isSrcdocDocument(false)
, m_isMobileDocument(false)
- , m_mayDisplaySeamlesslyWithParent(false)
+ , m_isTransitionDocument(false)
, m_renderView(0)
+#if !ENABLE(OILPAN)
, m_weakFactory(this)
+#endif
, m_contextDocument(initializer.contextDocument())
- , m_idAttributeName(idAttr)
, m_hasFullscreenElementStack(false)
, m_loadEventDelayCount(0)
, m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
+ , m_pluginLoadingTimer(this, &Document::pluginLoadingTimerFired)
+ , m_didSetReferrerPolicy(false)
, m_referrerPolicy(ReferrerPolicyDefault)
, m_directionSetOnDocumentElement(false)
, m_writingModeSetOnDocumentElement(false)
, m_writeRecursionIsTooDeep(false)
, m_writeRecursionDepth(0)
- , m_lastHandledUserGestureTimestamp(0)
, m_taskRunner(MainThreadTaskRunner::create(this))
, m_registrationContext(initializer.registrationContext(this))
- , m_sharedObjectPoolClearTimer(this, &Document::sharedObjectPoolClearTimerFired)
+ , m_elementDataCacheClearTimer(this, &Document::elementDataCacheClearTimerFired)
#ifndef NDEBUG
, m_didDispatchViewportPropertiesChanged(false)
#endif
- , m_animationClock(AnimationClock::create())
- , m_timeline(DocumentTimeline::create(this))
- , m_transitionTimeline(TransitionTimeline::create(this))
- , m_templateDocumentHost(0)
+ , m_timeline(AnimationTimeline::create(this))
+ , m_templateDocumentHost(nullptr)
, m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
+ , m_hasViewportUnits(false)
+ , m_styleRecalcElementCounter(0)
{
setClient(this);
ScriptWrappable::init(this);
if (m_frame) {
- provideContextFeaturesToDocumentFrom(this, m_frame->page());
+ ASSERT(m_frame->page());
+ provideContextFeaturesToDocumentFrom(*this, *m_frame->page());
- m_fetcher = m_frame->loader().activeDocumentLoader()->fetcher();
+ m_fetcher = m_frame->loader().documentLoader()->fetcher();
}
if (!m_fetcher)
@@ -473,12 +520,14 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
initSecurityContext(initializer);
initDNSPrefetch();
- for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
+#if !ENABLE(OILPAN)
+ for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
m_nodeListCounts[i] = 0;
+#endif
InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
- m_lifecyle.advanceTo(DocumentLifecycle::Inactive);
+ m_lifecycle.advanceTo(DocumentLifecycle::Inactive);
// Since CSSFontSelector requires Document::m_fetcher and StyleEngine owns
// CSSFontSelector, need to initialize m_styleEngine after initializing
@@ -489,19 +538,26 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
Document::~Document()
{
ASSERT(!renderView());
+ ASSERT(!parentTreeScope());
+#if !ENABLE(OILPAN)
ASSERT(m_ranges.isEmpty());
- ASSERT(!m_parentTreeScope);
ASSERT(!hasGuardRefCount());
+ // With Oilpan, either the document outlives the visibility observers
+ // or the visibility observers and the document die in the same GC round.
+ // When they die in the same GC round, the list of visibility observers
+ // will not be empty on Document destruction.
+ ASSERT(m_visibilityObservers.isEmpty());
if (m_templateDocument)
- m_templateDocument->setTemplateDocumentHost(0); // balanced in templateDocument().
-
- if (Document* ownerDocument = this->ownerDocument())
- ownerDocument->didRemoveEventTargetNode(this);
+ m_templateDocument->m_templateDocumentHost = nullptr; // balanced in ensureTemplateDocument().
m_scriptRunner.clear();
- removeAllEventListeners();
+ // FIXME: Oilpan: Not removing event listeners here also means that we do
+ // not notify the inspector instrumentation that the event listeners are
+ // gone. The Document and all the nodes in the document are gone, so maybe
+ // that is OK?
+ removeAllEventListenersRecursively();
// Currently we believe that Document can never outlive the parser.
// Although the Document may be replaced synchronously, DocumentParsers
@@ -511,19 +567,25 @@ Document::~Document()
// if the DocumentParser outlives the Document it won't cause badness.
ASSERT(!m_parser || m_parser->refCount() == 1);
detachParser();
+#endif
if (this == topDocument())
clearAXObjectCache();
+#if !ENABLE(OILPAN)
if (m_styleSheetList)
m_styleSheetList->detachFromDocument();
- if (m_import) {
- m_import->wasDetachedFromDocument();
- m_import = 0;
+ if (m_importsController) {
+ m_importsController->wasDetachedFrom(*this);
+ m_importsController = nullptr;
}
- m_styleEngine.clear(); // We need to destory CSSFontSelector before destroying m_fetcher.
+ m_timeline->detachFromDocument();
+
+ // We need to destroy CSSFontSelector before destroying m_fetcher.
+ if (m_styleEngine)
+ m_styleEngine->detachFromDocument();
if (m_elemSheet)
m_elemSheet->clearOwnerNode();
@@ -531,7 +593,7 @@ Document::~Document()
// It's possible for multiple Documents to end up referencing the same ResourceFetcher (e.g., SVGImages
// load the initial empty document and the SVGDocument with the same DocumentLoader).
if (m_fetcher->document() == this)
- m_fetcher->setDocument(0);
+ m_fetcher->setDocument(nullptr);
m_fetcher.clear();
// We must call clearRareData() here since a Document class inherits TreeScope
@@ -539,28 +601,30 @@ Document::~Document()
if (hasRareData())
clearRareData();
- ASSERT(!m_listsInvalidatedAtDocument.size());
+ ASSERT(m_listsInvalidatedAtDocument.isEmpty());
- for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
+ for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
ASSERT(!m_nodeListCounts[i]);
+#endif
- clearDocumentScope();
setClient(0);
InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
}
+#if !ENABLE(OILPAN)
void Document::dispose()
{
ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
+
// We must make sure not to be retaining any of our children through
// these extra pointers or we will create a reference cycle.
- m_docType = 0;
- m_focusedElement = 0;
- m_hoverNode = 0;
- m_activeElement = 0;
- m_titleElement = 0;
- m_documentElement = 0;
+ m_docType = nullptr;
+ m_focusedElement = nullptr;
+ m_hoverNode = nullptr;
+ m_activeHoverElement = nullptr;
+ m_titleElement = nullptr;
+ m_documentElement = nullptr;
m_contextFeatures = ContextFeatures::defaultSwitch();
m_userActionElements.documentDidRemoveLastRef();
m_associatedFormControls.clear();
@@ -569,15 +633,17 @@ void Document::dispose()
m_registrationContext.clear();
- if (m_import) {
- m_import->wasDetachedFromDocument();
- m_import = 0;
+ if (m_importsController) {
+ m_importsController->wasDetachedFrom(*this);
+ m_importsController = nullptr;
}
// removeDetachedChildren() doesn't always unregister IDs,
// so tear down scope information upfront to avoid having stale references in the map.
destroyTreeScopeData();
+
removeDetachedChildren();
+
// removeDetachedChildren() can access FormController.
m_formController.clear();
@@ -591,11 +657,12 @@ void Document::dispose()
m_scriptedAnimationController.clear();
if (svgExtensions())
- accessSVGExtensions()->pauseAnimations();
+ accessSVGExtensions().pauseAnimations();
- m_lifecyle.advanceTo(DocumentLifecycle::Disposed);
+ m_lifecycle.advanceTo(DocumentLifecycle::Disposed);
lifecycleNotifier().notifyDocumentWasDisposed();
}
+#endif
SelectorQueryCache& Document::selectorQueryCache()
{
@@ -613,6 +680,7 @@ MediaQueryMatcher& Document::mediaQueryMatcher()
void Document::mediaQueryAffectingValueChanged()
{
+ m_evaluateMediaQueriesOnStyleRecalc = true;
styleEngine()->clearMediaQueryRuleSetStyleSheets();
}
@@ -634,7 +702,7 @@ String Document::compatMode() const
return inQuirksMode() ? "BackCompat" : "CSS1Compat";
}
-void Document::setDoctype(PassRefPtr<DocumentType> docType)
+void Document::setDoctype(PassRefPtrWillBeRawPtr<DocumentType> docType)
{
// This should never be called more than once.
ASSERT(!m_docType || !docType);
@@ -648,16 +716,16 @@ void Document::setDoctype(PassRefPtr<DocumentType> docType)
clearStyleResolver();
}
-DOMImplementation* Document::implementation()
+DOMImplementation& Document::implementation()
{
if (!m_implementation)
m_implementation = DOMImplementation::create(*this);
- return m_implementation.get();
+ return *m_implementation;
}
-bool Document::hasManifest() const
+bool Document::hasAppCacheManifest() const
{
- return documentElement() && isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
+ return isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
}
Location* Document::location() const
@@ -665,280 +733,319 @@ Location* Document::location() const
if (!frame())
return 0;
- return domWindow()->location();
+ return &domWindow()->location();
}
void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-
- Element* newDocumentElement = ElementTraversal::firstWithin(*this);
- if (newDocumentElement == m_documentElement)
- return;
- m_documentElement = newDocumentElement;
- // The root style used for media query matching depends on the document element.
- clearStyleResolver();
+ m_documentElement = ElementTraversal::firstWithin(*this);
}
-PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
{
if (!isValidName(name)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
- return 0;
+ exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + name + "') is not a valid name.");
+ return nullptr;
}
if (isXHTMLDocument() || isHTMLDocument())
- return HTMLElementFactory::createHTMLElement(isHTMLDocument() ? name.lower() : name, document(), 0, false);
+ return HTMLElementFactory::createHTMLElement(isHTMLDocument() ? name.lower() : name, *this, 0, false);
- return createElement(QualifiedName(nullAtom, name, nullAtom), false);
+ return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
}
-PassRefPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState& exceptionState)
{
if (!isValidName(localName)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
- return 0;
+ exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + localName + "') is not a valid name.");
+ return nullptr;
}
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element;
- if (RuntimeEnabledFeatures::customElementsEnabled() && CustomElement::isValidName(localName) && registrationContext())
+ if (CustomElement::isValidName(localName) && registrationContext()) {
element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
- else
+ } else {
element = createElement(localName, exceptionState);
+ if (exceptionState.hadException())
+ return nullptr;
+ }
- if (RuntimeEnabledFeatures::customElementsEnabled() && !typeExtension.isNull() && !typeExtension.isEmpty())
+ if (!typeExtension.isEmpty())
CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);
- return element;
+ return element.release();
}
-PassRefPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState& exceptionState)
+static inline QualifiedName createQualifiedName(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
{
AtomicString prefix, localName;
- if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
+ if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
+ return QualifiedName::null();
QualifiedName qName(prefix, localName, namespaceURI);
- if (!hasValidNamespaceForElements(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
+ if (!Document::hasValidNamespaceForElements(qName)) {
+ exceptionState.throwDOMException(NamespaceError, "The namespace URI provided ('" + namespaceURI + "') is not valid for the qualified name provided ('" + qualifiedName + "').");
+ return QualifiedName::null();
}
- RefPtr<Element> element;
+ return qName;
+}
+
+PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
+{
+ QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
+ if (qName == QualifiedName::null())
+ return nullptr;
+
+ return createElement(qName, false);
+}
+
+PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState& exceptionState)
+{
+ QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
+ if (qName == QualifiedName::null())
+ return nullptr;
+
+ RefPtrWillBeRawPtr<Element> element;
if (CustomElement::isValidName(qName.localName()) && registrationContext())
element = registrationContext()->createCustomTagElement(*this, qName);
else
- element = createElementNS(namespaceURI, qualifiedName, exceptionState);
+ element = createElement(qName, false);
- if (!typeExtension.isNull() && !typeExtension.isEmpty())
+ if (!typeExtension.isEmpty())
CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);
- return element;
+ return element.release();
}
-ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, ExceptionState& exceptionState)
+ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, ExceptionState& exceptionState)
{
- return registerElement(state, name, Dictionary(), exceptionState);
+ return registerElement(scriptState, name, Dictionary(), exceptionState);
}
-ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
+ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
{
if (!registrationContext()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No element registration context is available.");
return ScriptValue();
}
- CustomElementConstructorBuilder constructorBuilder(state, &options);
+ CustomElementConstructorBuilder constructorBuilder(scriptState, &options);
registrationContext()->registerElement(this, &constructorBuilder, name, validNames, exceptionState);
return constructorBuilder.bindingsReturnValue();
}
-void Document::setImport(HTMLImport* import)
+void Document::setImportsController(HTMLImportsController* controller)
{
- ASSERT(!m_import || !import);
- m_import = import;
+ ASSERT(!m_importsController || !controller);
+ m_importsController = controller;
}
-void Document::didLoadAllImports()
+HTMLImportLoader* Document::importLoader() const
{
- executeScriptsWaitingForResourcesIfNeeded();
+ if (!m_importsController)
+ return 0;
+ return m_importsController->loaderFor(*this);
}
bool Document::haveImportsLoaded() const
{
- return !m_import || !m_import->isBlocked();
+ if (!m_importsController)
+ return true;
+ return !m_importsController->shouldBlockScriptExecution(*this);
+}
+
+LocalDOMWindow* Document::executingWindow()
+{
+ if (LocalDOMWindow* owningWindow = domWindow())
+ return owningWindow;
+ if (HTMLImportsController* import = this->importsController())
+ return import->master()->domWindow();
+ return 0;
+}
+
+LocalFrame* Document::executingFrame()
+{
+ LocalDOMWindow* window = executingWindow();
+ if (!window)
+ return 0;
+ return window->frame();
}
-PassRefPtr<DocumentFragment> Document::createDocumentFragment()
+PassRefPtrWillBeRawPtr<DocumentFragment> Document::createDocumentFragment()
{
- return DocumentFragment::create(document());
+ return DocumentFragment::create(*this);
}
-PassRefPtr<Text> Document::createTextNode(const String& data)
+PassRefPtrWillBeRawPtr<Text> Document::createTextNode(const String& data)
{
return Text::create(*this, data);
}
-PassRefPtr<Comment> Document::createComment(const String& data)
+PassRefPtrWillBeRawPtr<Comment> Document::createComment(const String& data)
{
return Comment::create(*this, data);
}
-PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& exceptionState)
{
if (isHTMLDocument()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, "This operation is not supported for HTML documents.");
+ return nullptr;
}
if (data.contains("]]>")) {
exceptionState.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
- return 0;
+ return nullptr;
}
return CDATASection::create(*this, data);
}
-PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& exceptionState)
{
if (!isValidName(target)) {
exceptionState.throwDOMException(InvalidCharacterError, "The target provided ('" + target + "') is not a valid name.");
- return 0;
+ return nullptr;
}
if (data.contains("?>")) {
exceptionState.throwDOMException(InvalidCharacterError, "The data provided ('" + data + "') contains '?>'.");
- return 0;
+ return nullptr;
}
return ProcessingInstruction::create(*this, target, data);
}
-PassRefPtr<Text> Document::createEditingTextNode(const String& text)
+PassRefPtrWillBeRawPtr<Text> Document::createEditingTextNode(const String& text)
{
return Text::createEditingText(*this, text);
}
-PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
+bool Document::importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtrWillBeRawPtr<ContainerNode> newContainerNode, ExceptionState& exceptionState)
+{
+ for (Node* oldChild = oldContainerNode->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
+ RefPtrWillBeRawPtr<Node> newChild = importNode(oldChild, true, exceptionState);
+ if (exceptionState.hadException())
+ return false;
+ newContainerNode->appendChild(newChild.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+ }
+
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, ExceptionState& ec)
{
- return MutableStylePropertySet::create()->ensureCSSStyleDeclaration();
+ UseCounter::countDeprecation(this, UseCounter::DocumentImportNodeOptionalArgument);
+ return importNode(importedNode, true, ec);
}
-PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
{
if (!importedNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
switch (importedNode->nodeType()) {
case TEXT_NODE:
return createTextNode(importedNode->nodeValue());
case CDATA_SECTION_NODE:
- return createCDATASection(importedNode->nodeValue(), exceptionState);
+ return CDATASection::create(*this, importedNode->nodeValue());
case PROCESSING_INSTRUCTION_NODE:
return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), exceptionState);
case COMMENT_NODE:
return createComment(importedNode->nodeValue());
+ case DOCUMENT_TYPE_NODE: {
+ DocumentType* doctype = toDocumentType(importedNode);
+ return DocumentType::create(this, doctype->name(), doctype->publicId(), doctype->systemId());
+ }
case ELEMENT_NODE: {
Element* oldElement = toElement(importedNode);
// FIXME: The following check might be unnecessary. Is it possible that
// oldElement has mismatched prefix/namespace?
if (!hasValidNamespaceForElements(oldElement->tagQName())) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
+ exceptionState.throwDOMException(NamespaceError, "The imported node has an invalid namespace.");
+ return nullptr;
}
- RefPtr<Element> newElement = createElement(oldElement->tagQName(), false);
+ RefPtrWillBeRawPtr<Element> newElement = createElement(oldElement->tagQName(), false);
newElement->cloneDataFromElement(*oldElement);
if (deep) {
- for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
- RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
- if (exceptionState.hadException())
- return 0;
- newElement->appendChild(newChild.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
- }
+ if (!importContainerNodeChildren(oldElement, newElement, exceptionState))
+ return nullptr;
+ if (isHTMLTemplateElement(*oldElement)
+ && !importContainerNodeChildren(toHTMLTemplateElement(oldElement)->content(), toHTMLTemplateElement(newElement)->content(), exceptionState))
+ return nullptr;
}
return newElement.release();
}
case ATTRIBUTE_NODE:
- return Attr::create(*this, QualifiedName(nullAtom, toAttr(importedNode)->name(), nullAtom), toAttr(importedNode)->value());
+ return Attr::create(*this, QualifiedName(nullAtom, AtomicString(toAttr(importedNode)->name()), nullAtom), toAttr(importedNode)->value());
case DOCUMENT_FRAGMENT_NODE: {
if (importedNode->isShadowRoot()) {
// ShadowRoot nodes should not be explicitly importable.
// Either they are imported along with their host node, or created implicitly.
- break;
+ exceptionState.throwDOMException(NotSupportedError, "The node provided is a shadow root, which may not be imported.");
+ return nullptr;
}
DocumentFragment* oldFragment = toDocumentFragment(importedNode);
- RefPtr<DocumentFragment> newFragment = createDocumentFragment();
- if (deep) {
- for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
- RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
- if (exceptionState.hadException())
- return 0;
- newFragment->appendChild(newChild.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
- }
- }
+ RefPtrWillBeRawPtr<DocumentFragment> newFragment = createDocumentFragment();
+ if (deep && !importContainerNodeChildren(oldFragment, newFragment, exceptionState))
+ return nullptr;
return newFragment.release();
}
- case ENTITY_NODE:
- case NOTATION_NODE:
- // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that.
- // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
case DOCUMENT_NODE:
- case DOCUMENT_TYPE_NODE:
- case XPATH_NAMESPACE_NODE:
- break;
+ exceptionState.throwDOMException(NotSupportedError, "The node provided is a document, which may not be imported.");
+ return nullptr;
}
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
}
-PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState)
{
if (!source) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
EventQueueScope scope;
switch (source->nodeType()) {
- case ENTITY_NODE:
- case NOTATION_NODE:
case DOCUMENT_NODE:
case DOCUMENT_TYPE_NODE:
- case XPATH_NAMESPACE_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, "The node provided is of type '" + source->nodeName() + "', which may not be adopted.");
+ return nullptr;
case ATTRIBUTE_NODE: {
Attr* attr = toAttr(source.get());
- if (attr->ownerElement())
- attr->ownerElement()->removeAttributeNode(attr, exceptionState);
+ if (RefPtrWillBeRawPtr<Element> ownerElement = attr->ownerElement())
+ ownerElement->removeAttributeNode(attr, exceptionState);
break;
}
default:
if (source->isShadowRoot()) {
// ShadowRoot cannot disconnect itself from the host node.
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a shadow root, which may not be adopted.");
+ return nullptr;
}
if (source->isFrameOwnerElement()) {
HTMLFrameOwnerElement* frameOwnerElement = toHTMLFrameOwnerElement(source.get());
- if (frame() && frame()->tree().isDescendantOf(frameOwnerElement->contentFrame())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ // FIXME(kenrb): the downcast can be removed when the FrameTree supports RemoteFrames.
+ if (frame() && frame()->tree().isDescendantOf(toLocalFrameTemporary(frameOwnerElement->contentFrame()))) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a frame which contains this document.");
+ return nullptr;
}
}
if (source->parentNode()) {
source->parentNode()->removeChild(source.get(), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
}
}
@@ -958,39 +1065,32 @@ bool Document::hasValidNamespaceForElements(const QualifiedName& qName)
// Required by DOM Level 3 Core and unspecified by DOM Level 2 Core:
// http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
- // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar")
- if ((qName.prefix() == xmlnsAtom && qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI) || (qName.prefix() != xmlnsAtom && qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI))
- return false;
-
- return true;
+ // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar"), createElementNS(null, "xmlns")
+ if (qName.prefix() == xmlnsAtom || (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom))
+ return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
+ return qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI;
}
bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName)
{
- // Spec: DOM Level 2 Core: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-ElSetAttrNS
- if (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom) {
- // Note: The case of an "xmlns" qualified name with a namespace of
- // xmlnsNamespaceURI is specifically allowed (See <http://www.w3.org/2000/xmlns/>).
- return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
- }
return hasValidNamespaceForElements(qName);
}
// FIXME: This should really be in a possible ElementFactory class
-PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
+PassRefPtrWillBeRawPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
{
- RefPtr<Element> e;
+ RefPtrWillBeRawPtr<Element> e = nullptr;
// FIXME: Use registered namespaces and look up in a hash to find the right factory.
if (qName.namespaceURI() == xhtmlNamespaceURI)
- e = HTMLElementFactory::createHTMLElement(qName.localName(), document(), 0, createdByParser);
+ e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, createdByParser);
else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
- e = SVGElementFactory::createSVGElement(qName.localName(), document(), createdByParser);
+ e = SVGElementFactory::createSVGElement(qName.localName(), *this, createdByParser);
if (e)
m_sawElementsInKnownNamespaces = true;
else
- e = Element::create(qName, &document());
+ e = Element::create(qName, this);
if (e->prefix() != qName.prefix())
e->setTagNameForCreateElementNS(qName);
@@ -1005,39 +1105,6 @@ bool Document::regionBasedColumnsEnabled() const
return settings() && settings()->regionBasedColumnsEnabled();
}
-PassRefPtr<DOMNamedFlowCollection> Document::webkitGetNamedFlows()
-{
- if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderView())
- return 0;
-
- updateStyleIfNeeded();
-
- return namedFlows()->createCSSOMSnapshot();
-}
-
-NamedFlowCollection* Document::namedFlows()
-{
- if (!m_namedFlows)
- m_namedFlows = NamedFlowCollection::create(this);
-
- return m_namedFlows.get();
-}
-
-PassRefPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
-{
- AtomicString prefix, localName;
- if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
-
- QualifiedName qName(prefix, localName, namespaceURI);
- if (!hasValidNamespaceForElements(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
- }
-
- return createElement(qName, false);
-}
-
String Document::readyState() const
{
DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
@@ -1066,8 +1133,6 @@ void Document::setReadyState(ReadyState readyState)
case Loading:
if (!m_documentTiming.domLoading) {
m_documentTiming.domLoading = monotonicallyIncreasingTime();
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- m_timeline->setZeroTime(m_documentTiming.domLoading);
}
break;
case Interactive:
@@ -1106,6 +1171,7 @@ String Document::defaultCharset() const
void Document::setCharset(const String& charset)
{
+ UseCounter::count(*this, UseCounter::DocumentSetCharset);
if (DocumentLoader* documentLoader = loader())
documentLoader->setUserChosenEncoding(charset);
WTF::TextEncoding encoding(charset);
@@ -1113,7 +1179,7 @@ void Document::setCharset(const String& charset)
if (!encoding.isValid())
return;
DocumentEncodingData newEncodingData = m_encodingData;
- newEncodingData.encoding = encoding;
+ newEncodingData.setEncoding(encoding);
setEncodingData(newEncodingData);
}
@@ -1124,18 +1190,13 @@ void Document::setContentLanguage(const AtomicString& language)
m_contentLanguage = language;
// Document's style depends on the content language.
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void Document::setXMLVersion(const String& version, ExceptionState& exceptionState)
{
- if (!implementation()->hasFeature("XML", String())) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
if (!XMLDocumentParser::supportsXMLVersion(version)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "This document does not support the XML version '" + version + "'.");
return;
}
@@ -1144,11 +1205,6 @@ void Document::setXMLVersion(const String& version, ExceptionState& exceptionSta
void Document::setXMLStandalone(bool standalone, ExceptionState& exceptionState)
{
- if (!implementation()->hasFeature("XML", String())) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
m_xmlStandalone = standalone ? Standalone : NotStandalone;
}
@@ -1171,10 +1227,13 @@ void Document::setContent(const String& content)
String Document::suggestedMIMEType() const
{
- if (isXHTMLDocument())
- return "application/xhtml+xml";
- if (isSVGDocument())
- return "image/svg+xml";
+ if (isXMLDocument()) {
+ if (isXHTMLDocument())
+ return "application/xhtml+xml";
+ if (isSVGDocument())
+ return "image/svg+xml";
+ return "application/xml";
+ }
if (xmlStandalone())
return "text/xml";
if (isHTMLDocument())
@@ -1185,6 +1244,26 @@ String Document::suggestedMIMEType() const
return String();
}
+void Document::setMimeType(const AtomicString& mimeType)
+{
+ m_mimeType = mimeType;
+}
+
+AtomicString Document::contentType() const
+{
+ if (!m_mimeType.isEmpty())
+ return m_mimeType;
+
+ if (DocumentLoader* documentLoader = loader())
+ return documentLoader->mimeType();
+
+ String mimeType = suggestedMIMEType();
+ if (!mimeType.isEmpty())
+ return AtomicString(mimeType);
+
+ return AtomicString("application/xml");
+}
+
Element* Document::elementFromPoint(int x, int y) const
{
if (!renderView())
@@ -1193,14 +1272,14 @@ Element* Document::elementFromPoint(int x, int y) const
return TreeScope::elementFromPoint(x, y);
}
-PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
+PassRefPtrWillBeRawPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
if (!renderView())
- return 0;
- LayoutPoint localPoint;
- RenderObject* renderer = rendererFromPoint(this, x, y, &localPoint);
+ return nullptr;
+ HitTestResult result = hitTestInDocument(this, x, y);
+ RenderObject* renderer = result.renderer();
if (!renderer)
- return 0;
+ return nullptr;
Node* node = renderer->node();
Node* shadowAncestorNode = ancestorInThisScope(node);
@@ -1210,9 +1289,9 @@ PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
return Range::create(*this, container, offset, container, offset);
}
- PositionWithAffinity positionWithAffinity = renderer->positionForPoint(localPoint);
+ PositionWithAffinity positionWithAffinity = renderer->positionForPoint(result.localPoint());
if (positionWithAffinity.position().isNull())
- return 0;
+ return nullptr;
Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
return Range::create(*this, rangeCompliantPosition, rangeCompliantPosition);
@@ -1299,18 +1378,18 @@ void Document::setTitle(const String& title)
// Title set by JavaScript -- overrides any title elements.
m_titleSetExplicitly = true;
if (!isHTMLDocument() && !isXHTMLDocument())
- m_titleElement = 0;
+ m_titleElement = nullptr;
else if (!m_titleElement) {
if (HTMLElement* headElement = head()) {
- m_titleElement = createElement(titleTag, false);
- headElement->appendChild(m_titleElement);
+ m_titleElement = HTMLTitleElement::create(*this);
+ headElement->appendChild(m_titleElement.get());
}
}
- updateTitle(title);
-
- if (m_titleElement && isHTMLTitleElement(m_titleElement.get()))
+ if (isHTMLTitleElement(m_titleElement))
toHTMLTitleElement(m_titleElement)->setText(title);
+ else
+ updateTitle(title);
}
void Document::setTitleElement(const String& title, Element* titleElement)
@@ -1330,25 +1409,35 @@ void Document::removeTitle(Element* titleElement)
if (m_titleElement != titleElement)
return;
- m_titleElement = 0;
+ m_titleElement = nullptr;
m_titleSetExplicitly = false;
// FIXME: This is broken for SVG.
// Update title based on first title element in the head, if one exists.
if (HTMLElement* headElement = head()) {
- for (Element* element = headElement->firstElementChild(); element; element = element->nextElementSibling()) {
- if (!isHTMLTitleElement(element))
- continue;
- HTMLTitleElement* title = toHTMLTitleElement(element);
+ if (HTMLTitleElement* title = Traversal<HTMLTitleElement>::firstChild(*headElement))
setTitleElement(title->text(), title);
- break;
- }
}
if (!m_titleElement)
updateTitle(String());
}
+const AtomicString& Document::dir()
+{
+ Element* rootElement = documentElement();
+ if (isHTMLHtmlElement(rootElement))
+ return toHTMLHtmlElement(rootElement)->dir();
+ return nullAtom;
+}
+
+void Document::setDir(const AtomicString& value)
+{
+ Element* rootElement = documentElement();
+ if (isHTMLHtmlElement(rootElement))
+ toHTMLHtmlElement(rootElement)->setDir(value);
+}
+
PageVisibilityState Document::pageVisibilityState() const
{
// The visibility of the document is inherited from the visibility of the
@@ -1370,18 +1459,28 @@ bool Document::hidden() const
return pageVisibilityState() != PageVisibilityStateVisible;
}
-void Document::dispatchVisibilityStateChangeEvent()
+void Document::didChangeVisibilityState()
{
dispatchEvent(Event::create(EventTypeNames::visibilitychange));
// Also send out the deprecated version until it can be removed.
dispatchEvent(Event::create(EventTypeNames::webkitvisibilitychange));
+
+ PageVisibilityState state = pageVisibilityState();
+ DocumentVisibilityObserverSet::const_iterator observerEnd = m_visibilityObservers.end();
+ for (DocumentVisibilityObserverSet::const_iterator it = m_visibilityObservers.begin(); it != observerEnd; ++it)
+ (*it)->didChangeVisibilityState(state);
+}
+
+void Document::registerVisibilityObserver(DocumentVisibilityObserver* observer)
+{
+ ASSERT(!m_visibilityObservers.contains(observer));
+ m_visibilityObservers.add(observer);
}
-DOMSecurityPolicy* Document::securityPolicy()
+void Document::unregisterVisibilityObserver(DocumentVisibilityObserver* observer)
{
- if (!m_domSecurityPolicy)
- m_domSecurityPolicy = DOMSecurityPolicy::create(this);
- return m_domSecurityPolicy.get();
+ ASSERT(m_visibilityObservers.contains(observer));
+ m_visibilityObservers.remove(observer);
}
String Document::nodeName() const
@@ -1394,17 +1493,20 @@ Node::NodeType Document::nodeType() const
return DOCUMENT_NODE;
}
-FormController* Document::formController()
+FormController& Document::formController()
{
- if (!m_formController)
+ if (!m_formController) {
m_formController = FormController::create();
- return m_formController.get();
+ if (m_frame && m_frame->loader().currentItem() && m_frame->loader().currentItem()->isCurrentDocument(this))
+ m_frame->loader().currentItem()->setDocumentState(m_formController->formElementsState());
+ }
+ return *m_formController;
}
-Vector<String> Document::formElementsState() const
+DocumentState* Document::formElementsState() const
{
if (!m_formController)
- return Vector<String>();
+ return 0;
return m_formController->formElementsState();
}
@@ -1412,7 +1514,7 @@ void Document::setStateForNewFormElements(const Vector<String>& stateVector)
{
if (!stateVector.size() && !m_formController)
return;
- formController()->setStateForNewFormElements(stateVector);
+ formController().setStateForNewFormElements(stateVector);
}
FrameView* Document::view() const
@@ -1425,124 +1527,174 @@ Page* Document::page() const
return m_frame ? m_frame->page() : 0;
}
+FrameHost* Document::frameHost() const
+{
+ return m_frame ? m_frame->host() : 0;
+}
+
Settings* Document::settings() const
{
return m_frame ? m_frame->settings() : 0;
}
-PassRefPtr<Range> Document::createRange()
+PassRefPtrWillBeRawPtr<Range> Document::createRange()
{
return Range::create(*this);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& exceptionState)
{
// FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
- return NodeIterator::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
+ return NodeIterator::create(root, NodeFilter::SHOW_ALL, nullptr);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
// FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
// NodeFilter.
- return NodeIterator::create(root, whatToShow, PassRefPtr<NodeFilter>());
+ return NodeIterator::create(root, whatToShow, nullptr);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
// FIXME: Ditto.
return NodeIterator::create(root, whatToShow, filter);
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
- return TreeWalker::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
+ return TreeWalker::create(root, NodeFilter::SHOW_ALL, nullptr);
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
- return TreeWalker::create(root, whatToShow, PassRefPtr<NodeFilter>());
+ return TreeWalker::create(root, whatToShow, nullptr);
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
return TreeWalker::create(root, whatToShow, filter);
}
-void Document::scheduleStyleRecalc()
+bool Document::needsRenderTreeUpdate() const
{
- if (shouldDisplaySeamlesslyWithParent()) {
- // When we're seamless, our parent document manages our style recalcs.
- ownerElement()->setNeedsStyleRecalc();
- ownerElement()->document().scheduleStyleRecalc();
- return;
- }
-
- if (m_styleRecalcTimer.isActive())
- return;
-
- ASSERT(needsStyleRecalc() || childNeedsStyleRecalc() || childNeedsDistributionRecalc());
-
- m_styleRecalcTimer.startOneShot(0);
-
- InspectorInstrumentation::didScheduleStyleRecalculation(this);
+ if (!isActive() || !view())
+ return false;
+ if (needsFullRenderTreeUpdate())
+ return true;
+ if (childNeedsStyleRecalc())
+ return true;
+ if (childNeedsStyleInvalidation())
+ return true;
+ return false;
}
-void Document::unscheduleStyleRecalc()
+bool Document::needsFullRenderTreeUpdate() const
{
- ASSERT(!isActive() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
- m_styleRecalcTimer.stop();
+ if (!isActive() || !view())
+ return false;
+ if (!m_useElementsNeedingUpdate.isEmpty())
+ return true;
+ if (!m_layerUpdateSVGFilterElements.isEmpty())
+ return true;
+ if (needsStyleRecalc())
+ return true;
+ if (needsStyleInvalidation())
+ return true;
+ // FIXME: The childNeedsDistributionRecalc bit means either self or children, we should fix that.
+ if (childNeedsDistributionRecalc())
+ return true;
+ if (DocumentAnimations::needsOutdatedAnimationPlayerUpdate(*this))
+ return true;
+ return false;
}
-bool Document::hasPendingStyleRecalc() const
+bool Document::shouldScheduleRenderTreeUpdate() const
{
- return m_styleRecalcTimer.isActive() && !m_inStyleRecalc;
+ if (!isActive())
+ return false;
+ if (inStyleRecalc())
+ return false;
+ // InPreLayout will recalc style itself. There's no reason to schedule another recalc.
+ if (m_lifecycle.state() == DocumentLifecycle::InPreLayout)
+ return false;
+ if (!shouldScheduleLayout())
+ return false;
+ return true;
}
-bool Document::hasPendingForcedStyleRecalc() const
+void Document::scheduleRenderTreeUpdate()
{
- return hasPendingStyleRecalc() && styleChangeType() >= SubtreeStyleChange;
+ ASSERT(!hasPendingStyleRecalc());
+ ASSERT(shouldScheduleRenderTreeUpdate());
+ ASSERT(needsRenderTreeUpdate());
+
+ page()->animator().scheduleVisualUpdate();
+ m_lifecycle.ensureStateAtMost(DocumentLifecycle::VisualUpdatePending);
+
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScheduleStyleRecalculation", "frame", frame());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didScheduleStyleRecalculation(this);
}
-void Document::styleRecalcTimerFired(Timer<Document>*)
+bool Document::hasPendingForcedStyleRecalc() const
{
- updateStyleIfNeeded();
+ return hasPendingStyleRecalc() && !inStyleRecalc() && styleChangeType() >= SubtreeStyleChange;
}
void Document::updateDistributionIfNeeded()
{
+ ScriptForbiddenScope forbidScript;
+
if (!childNeedsDistributionRecalc())
return;
- TRACE_EVENT0("webkit", "Document::recalcDistribution");
+ TRACE_EVENT0("webkit", "Document::updateDistributionIfNeeded");
recalcDistribution();
}
+void Document::updateStyleInvalidationIfNeeded()
+{
+ ScriptForbiddenScope forbidScript;
+
+ if (!isActive())
+ return;
+ if (!childNeedsStyleInvalidation())
+ return;
+ TRACE_EVENT0("webkit", "Document::updateStyleInvalidationIfNeeded");
+ ASSERT(styleResolver());
+
+ styleResolver()->ruleFeatureSet().styleInvalidator().invalidate(*this);
+}
+
void Document::updateDistributionForNodeIfNeeded(Node* node)
{
+ ScriptForbiddenScope forbidScript;
+
if (node->inDocument()) {
updateDistributionIfNeeded();
return;
@@ -1556,23 +1708,11 @@ void Document::updateDistributionForNodeIfNeeded(Node* node)
root->recalcDistribution();
}
-void Document::setStyleDependentState(RenderStyle* documentStyle)
+void Document::setupFontBuilder(RenderStyle* documentStyle)
{
- const Pagination& pagination = view()->pagination();
- if (pagination.mode != Pagination::Unpaginated) {
- Pagination::setStylesForPaginationMode(pagination.mode, documentStyle);
- documentStyle->setColumnGap(pagination.gap);
- if (renderView()->hasColumns())
- renderView()->updateColumnInfoFromStyle(documentStyle);
- }
-
- // Seamless iframes want to inherit their font from their parent iframe, so early return before setting the font.
- if (shouldDisplaySeamlesslyWithParent())
- return;
-
FontBuilder fontBuilder;
- fontBuilder.initForStyleResolve(*this, documentStyle, isSVGDocument());
- RefPtr<CSSFontSelector> selector = m_styleEngine->fontSelector();
+ fontBuilder.initForStyleResolve(*this, documentStyle);
+ RefPtrWillBeRawPtr<CSSFontSelector> selector = m_styleEngine->fontSelector();
fontBuilder.createFontForDocument(selector, documentStyle);
}
@@ -1587,10 +1727,11 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change)
WritingMode rootWritingMode = documentElementStyle->writingMode();
TextDirection rootDirection = documentElementStyle->direction();
- HTMLElement* body = this->body();
+ HTMLElement* body = this->body();
+ RefPtr<RenderStyle> bodyStyle;
if (body) {
- RefPtr<RenderStyle> bodyStyle = body->renderStyle();
+ bodyStyle = body->renderStyle();
if (!bodyStyle || body->needsStyleRecalc() || documentElement()->needsStyleRecalc() || change == Force)
bodyStyle = ensureStyleResolver().styleForElement(body, documentElementStyle.get());
if (!writingModeSetOnDocumentElement())
@@ -1599,157 +1740,217 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change)
rootDirection = bodyStyle->direction();
}
+ RefPtr<RenderStyle> overflowStyle;
+ if (Element* element = viewportDefiningElement(documentElementStyle.get())) {
+ if (element == body) {
+ overflowStyle = bodyStyle;
+ } else {
+ ASSERT(element == documentElement());
+ overflowStyle = documentElementStyle;
+ }
+ }
+
+ // Resolved rem units are stored in the matched properties cache so we need to make sure to
+ // invalidate the cache if the documentElement needed to reattach or the font size changed
+ // and then trigger a full document recalc. We also need to clear it here since the
+ // call to styleForElement on the body above can cache bad values for rem units if the
+ // documentElement's style was dirty. We could keep track of which elements depend on
+ // rem units like we do for viewport styles, but we assume root font size changes are
+ // rare and just invalidate the cache for now.
+ if (styleEngine()->usesRemUnits() && (documentElement()->needsAttach() || documentElement()->computedStyle()->fontSize() != documentElementStyle->fontSize())) {
+ ensureStyleResolver().invalidateMatchedPropertiesCache();
+ documentElement()->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ EOverflow overflowX = OAUTO;
+ EOverflow overflowY = OAUTO;
+ float columnGap = 0;
+ if (overflowStyle) {
+ overflowX = overflowStyle->overflowX();
+ overflowY = overflowStyle->overflowY();
+ // Visible overflow on the viewport is meaningless, and the spec says to treat it as 'auto':
+ if (overflowX == OVISIBLE)
+ overflowX = OAUTO;
+ if (overflowY == OVISIBLE)
+ overflowY = OAUTO;
+ // Column-gap is (ab)used by the current paged overflow implementation (in lack of other
+ // ways to specify gaps between pages), so we have to propagate it too.
+ columnGap = overflowStyle->columnGap();
+ }
+
RefPtr<RenderStyle> documentStyle = renderView()->style();
- if (documentStyle->writingMode() != rootWritingMode || documentStyle->direction() != rootDirection) {
+ if (documentStyle->writingMode() != rootWritingMode
+ || documentStyle->direction() != rootDirection
+ || documentStyle->overflowX() != overflowX
+ || documentStyle->overflowY() != overflowY
+ || documentStyle->columnGap() != columnGap) {
RefPtr<RenderStyle> newStyle = RenderStyle::clone(documentStyle.get());
newStyle->setWritingMode(rootWritingMode);
newStyle->setDirection(rootDirection);
+ newStyle->setColumnGap(columnGap);
+ newStyle->setOverflowX(overflowX);
+ newStyle->setOverflowY(overflowY);
renderView()->setStyle(newStyle);
- setStyleDependentState(newStyle.get());
+ setupFontBuilder(newStyle.get());
}
if (body) {
if (RenderStyle* style = body->renderStyle()) {
if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
- body->setNeedsStyleRecalc();
+ body->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
if (RenderStyle* style = documentElement()->renderStyle()) {
if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
- documentElement()->setNeedsStyleRecalc();
+ documentElement()->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
-void Document::recalcStyle(StyleRecalcChange change)
+void Document::updateRenderTree(StyleRecalcChange change)
{
- // we should not enter style recalc while painting
- RELEASE_ASSERT(!view() || !view()->isPainting());
+ ASSERT(isMainThread());
- // FIXME: We should never enter here without a FrameView or with an inactive document.
- if (!isActive() || !view())
+ if (change != Force && !needsRenderTreeUpdate())
return;
- if (m_inStyleRecalc)
+ if (inStyleRecalc())
return;
- TRACE_EVENT0("webkit", "Document::recalcStyle");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle");
+ // Entering here from inside layout or paint would be catastrophic since recalcStyle can
+ // tear down the render tree or (unfortunately) run script. Kill the whole renderer if
+ // someone managed to get into here from inside layout or paint.
+ RELEASE_ASSERT(!view()->isInPerformLayout());
+ RELEASE_ASSERT(!view()->isPainting());
- updateDistributionIfNeeded();
+ // Script can run below in WidgetUpdates, so protect the LocalFrame.
+ RefPtr<LocalFrame> protect(m_frame);
+
+ TRACE_EVENT0("webkit", "Document::updateRenderTree");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "UpdateRenderTree");
+ m_styleRecalcElementCounter = 0;
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "frame", frame());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
- if (m_evaluateMediaQueriesOnStyleRecalc) {
- m_evaluateMediaQueriesOnStyleRecalc = false;
- evaluateMediaQueryList();
- }
+ DocumentAnimations::updateOutdatedAnimationPlayersIfNeeded(*this);
+
+ // FIXME: This executes media query listeners which runs script, instead the script
+ // should run at raf timing in ScriptedAnimationController just like resize events.
+ evaluateMediaQueryListIfNeeded();
+
+ updateUseShadowTreesIfNeeded();
+ updateDistributionIfNeeded();
+ updateStyleInvalidationIfNeeded();
- // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
- // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
- // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
+ // FIXME: We should update style on our ancestor chain before proceeding
+ // however doing so currently causes several tests to crash, as LocalFrame::setDocument calls Document::attach
+ // before setting the LocalDOMWindow on the LocalFrame, or the SecurityOrigin on the document. The attach, in turn
// resolves style (here) and then when we resolve style on the parent chain, we may end up
// re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
// hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
- if (m_styleEngine->needsUpdateActiveStylesheetsOnStyleRecalc())
- m_styleEngine->updateActiveStyleSheets(FullStyleUpdate);
-
if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
m_styleEngine->setUsesRemUnit(true);
- {
- PostAttachCallbacks::SuspendScope suspendPostAttachCallbacks;
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
- FrameView::DeferredRepaintScope deferRepaints(*view());
- TemporaryChange<bool> changeInStyleRecalc(m_inStyleRecalc, true);
-
- if (styleChangeType() >= SubtreeStyleChange)
- change = Force;
-
- // FIXME: Cannot access the ensureStyleResolver() before calling styleForDocument below because
- // apparently the StyleResolver's constructor has side effects. We should fix it.
- // See printing/setPrinting.html, printing/width-overflow.html though they only fail on
- // mac when accessing the resolver by what appears to be a viewport size difference.
-
- if (change == Force || (change >= Inherit && shouldDisplaySeamlesslyWithParent())) {
- m_hasNodesWithPlaceholderStyle = false;
- RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this, m_styleEngine->fontSelector());
- StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderView()->style());
- if (localChange != NoChange)
- renderView()->setStyle(documentStyle.release());
- }
+ updateStyle(change);
- clearNeedsStyleRecalc();
+ // As a result of the style recalculation, the currently hovered element might have been
+ // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
+ // to check if any other elements ended up under the mouse pointer due to re-layout.
+ if (hoverNode() && !hoverNode()->renderer() && frame())
+ frame()->eventHandler().dispatchFakeMouseMoveEventSoon();
- // Uncomment to enable printing of statistics about style sharing and the matched property cache.
- // Optionally pass StyleResolver::ReportSlowStats to print numbers that require crawling the
- // entire DOM (where collecting them is very slow).
- // FIXME: Expose this as a runtime flag.
- // ensureStyleResolver().enableStats(/*StyleResolver::ReportSlowStats*/);
+ if (m_focusedElement && !m_focusedElement->isFocusable())
+ clearFocusedElementSoon();
- if (StyleResolverStats* stats = ensureStyleResolver().stats())
- stats->reset();
+#if ENABLE(SVG_FONTS)
+ if (svgExtensions())
+ accessSVGExtensions().removePendingSVGFontFaceElementsForRemoval();
+#endif
- if (Element* documentElement = this->documentElement()) {
- inheritHtmlAndBodyElementStyles(change);
- if (shouldRecalcStyle(change, documentElement))
- documentElement->recalcStyle(change);
- }
+ ASSERT(!m_timeline->hasOutdatedAnimationPlayer());
- ensureStyleResolver().printStats();
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "elementCount", m_styleRecalcElementCounter);
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didRecalculateStyle(cookie, m_styleRecalcElementCounter);
+}
- view()->updateCompositingLayersAfterStyleChange();
+void Document::updateStyle(StyleRecalcChange change)
+{
+ TRACE_EVENT0("webkit", "Document::updateStyle");
- clearChildNeedsStyleRecalc();
- unscheduleStyleRecalc();
+ ScriptForbiddenScope forbidScript;
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+ m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc);
- // FIXME: SVG <use> element can schedule a recalc in the middle of an already running one.
- // See StyleEngine::updateActiveStyleSheets.
- if (m_styleEngine->needsUpdateActiveStylesheetsOnStyleRecalc())
- setNeedsStyleRecalc();
+ if (styleChangeType() >= SubtreeStyleChange)
+ change = Force;
- if (m_styleEngine->hasResolver()) {
- // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
- StyleResolver& resolver = m_styleEngine->ensureResolver();
- m_styleEngine->resetCSSFeatureFlags(resolver.ensureRuleFeatureSet());
- resolver.clearStyleSharingList();
- }
+ // FIXME: Cannot access the ensureStyleResolver() before calling styleForDocument below because
+ // apparently the StyleResolver's constructor has side effects. We should fix it.
+ // See printing/setPrinting.html, printing/width-overflow.html though they only fail on
+ // mac when accessing the resolver by what appears to be a viewport size difference.
+
+ if (change == Force) {
+ m_hasNodesWithPlaceholderStyle = false;
+ RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this);
+ StyleRecalcChange localChange = RenderStyle::stylePropagationDiff(documentStyle.get(), renderView()->style());
+ if (localChange != NoChange)
+ renderView()->setStyle(documentStyle.release());
}
- InspectorInstrumentation::didRecalculateStyle(cookie);
+ clearNeedsStyleRecalc();
- // As a result of the style recalculation, the currently hovered element might have been
- // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
- // to check if any other elements ended up under the mouse pointer due to re-layout.
- if (hoverNode() && !hoverNode()->renderer() && frame())
- frame()->eventHandler().dispatchFakeMouseMoveEventSoon();
-}
+ // Uncomment to enable printing of statistics about style sharing and the matched property cache.
+ // Optionally pass StyleResolver::ReportSlowStats to print numbers that require crawling the
+ // entire DOM (where collecting them is very slow).
+ // FIXME: Expose this as a runtime flag.
+ // ensureStyleResolver().enableStats(/*StyleResolver::ReportSlowStats*/);
-void Document::updateStyleIfNeeded()
-{
- ASSERT(isMainThread());
- ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
+ if (StyleResolverStats* stats = ensureStyleResolver().stats())
+ stats->reset();
- if (!needsStyleRecalc() && !childNeedsStyleRecalc() && !childNeedsDistributionRecalc())
- return;
+ if (Element* documentElement = this->documentElement()) {
+ inheritHtmlAndBodyElementStyles(change);
+ dirtyElementsForLayerUpdate();
+ if (documentElement->shouldCallRecalcStyle(change))
+ documentElement->recalcStyle(change);
+ while (dirtyElementsForLayerUpdate())
+ documentElement->recalcStyle(NoChange);
+ }
+
+ ensureStyleResolver().printStats();
+
+ view()->recalcOverflowAfterStyleChange();
+ renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+
+ clearChildNeedsStyleRecalc();
+
+ if (m_styleEngine->hasResolver()) {
+ // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
+ StyleResolver& resolver = m_styleEngine->ensureResolver();
+ m_styleEngine->resetCSSFeatureFlags(resolver.ensureUpdatedRuleFeatureSet());
+ resolver.clearStyleSharingList();
+ }
- RefPtr<Frame> holder(m_frame);
- AnimationUpdateBlock animationUpdateBlock(m_frame ? &m_frame->animation() : 0);
- recalcStyle(NoChange);
- DocumentAnimations::serviceAfterStyleRecalc(*this);
+ ASSERT(!needsStyleRecalc());
+ ASSERT(!childNeedsStyleRecalc());
+ ASSERT(inStyleRecalc());
+ m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
}
-void Document::updateStyleForNodeIfNeeded(Node* node)
+void Document::updateRenderTreeForNodeIfNeeded(Node* node)
{
- if (!hasPendingForcedStyleRecalc() && !childNeedsStyleRecalc() && !needsStyleRecalc())
- return;
+ bool needsRecalc = needsFullRenderTreeUpdate();
- bool needsStyleRecalc = hasPendingForcedStyleRecalc();
- for (Node* ancestor = node; ancestor && !needsStyleRecalc; ancestor = ancestor->parentOrShadowHostNode())
- needsStyleRecalc = ancestor->needsStyleRecalc();
- if (needsStyleRecalc)
- updateStyleIfNeeded();
+ for (const Node* ancestor = node; ancestor && !needsRecalc; ancestor = NodeRenderingTraversal::parent(ancestor))
+ needsRecalc = ancestor->needsStyleRecalc() || ancestor->needsStyleInvalidation();
+
+ if (needsRecalc)
+ updateRenderTreeIfNeeded();
}
void Document::updateLayout()
@@ -1757,7 +1958,7 @@ void Document::updateLayout()
ASSERT(isMainThread());
RefPtr<FrameView> frameView = view();
- if (frameView && frameView->isInLayout()) {
+ if (frameView && frameView->isInPerformLayout()) {
// View layout should not be re-entrant.
ASSERT_NOT_REACHED();
return;
@@ -1766,51 +1967,36 @@ void Document::updateLayout()
if (Element* oe = ownerElement())
oe->document().updateLayout();
- updateStyleIfNeeded();
+ updateRenderTreeIfNeeded();
- // Only do a layout if changes have occurred that make it necessary.
- if (isActive() && frameView && renderView() && (frameView->layoutPending() || renderView()->needsLayout()))
- frameView->layout();
+ if (!isActive())
+ return;
- if (isActive() && frameView)
- frameView->partialLayout().reset();
+ if (frameView->needsLayout())
+ frameView->layout();
- setNeedsFocusedElementCheck();
+ if (lifecycle().state() < DocumentLifecycle::LayoutClean)
+ lifecycle().advanceTo(DocumentLifecycle::LayoutClean);
}
void Document::setNeedsFocusedElementCheck()
{
- // FIXME: Using a Task doesn't look a good idea.
- if (!m_focusedElement || m_didPostCheckFocusedElementTask)
- return;
- m_taskRunner->postTask(CheckFocusedElementTask::create());
- m_didPostCheckFocusedElementTask = true;
+ setNeedsStyleRecalc(LocalStyleChange);
}
-void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
+void Document::clearFocusedElementSoon()
{
- ASSERT(m_styleEngine->ignoringPendingStylesheets());
+ if (!m_clearFocusedElementTimer.isActive())
+ m_clearFocusedElementTimer.startOneShot(0, FROM_HERE);
+}
- if (!m_styleEngine->hasPendingSheets())
- return;
+void Document::clearFocusedElementTimerFired(Timer<Document>*)
+{
+ updateRenderTreeIfNeeded();
+ m_clearFocusedElementTimer.stop();
- // FIXME: We are willing to attempt to suppress painting with outdated style info only once.
- // Our assumption is that it would be dangerous to try to stop it a second time, after page
- // content has already been loaded and displayed with accurate style information. (Our
- // suppression involves blanking the whole page at the moment. If it were more refined, we
- // might be able to do something better.) It's worth noting though that this entire method
- // is a hack, since what we really want to do is suspend JS instead of doing a layout with
- // inaccurate information.
- HTMLElement* bodyElement = body();
- if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
- m_pendingSheetLayout = DidLayoutWithPendingSheets;
- styleResolverChanged(RecalcStyleImmediately);
- } else if (m_hasNodesWithPlaceholderStyle) {
- // If new nodes have been added or style recalc has been done with style sheets still
- // pending, some nodes may not have had their real style calculated yet. Normally this
- // gets cleaned when style sheets arrive but here we need up-to-date style immediately.
- recalcStyle(Force);
- }
+ if (m_focusedElement && !m_focusedElement->isFocusable())
+ m_focusedElement->blur();
}
// FIXME: This is a bad idea and needs to be removed eventually.
@@ -1822,42 +2008,31 @@ void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)
{
StyleEngine::IgnoringPendingStylesheet ignoring(m_styleEngine.get());
- recalcStyleForLayoutIgnoringPendingStylesheets();
- updateLayout();
- if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view())
- view()->flushAnyPendingPostLayoutTasks();
-}
-
-void Document::partialUpdateLayoutIgnorePendingStylesheets(Node* stopLayoutAtNode)
-{
- // Non-overlay scrollbars can cause a second layout that is dependent
- // on a first layout. This is disabled for partial layout for now.
- if (!RuntimeEnabledFeatures::partialLayoutEnabled() || !ScrollbarTheme::theme()->usesOverlayScrollbars()) {
- updateLayoutIgnorePendingStylesheets();
- return;
- }
- StyleEngine::IgnoringPendingStylesheet ignoring(m_styleEngine.get());
- recalcStyleForLayoutIgnoringPendingStylesheets();
-
- if (stopLayoutAtNode) {
- RenderObject* renderer = stopLayoutAtNode->renderer();
- bool canPartialLayout = renderer;
- while (renderer) {
- if (!renderer->supportsPartialLayout()) {
- canPartialLayout = false;
- break;
- }
- renderer = renderer->parent();
+ if (m_styleEngine->hasPendingSheets()) {
+ // FIXME: We are willing to attempt to suppress painting with outdated style info only once.
+ // Our assumption is that it would be dangerous to try to stop it a second time, after page
+ // content has already been loaded and displayed with accurate style information. (Our
+ // suppression involves blanking the whole page at the moment. If it were more refined, we
+ // might be able to do something better.) It's worth noting though that this entire method
+ // is a hack, since what we really want to do is suspend JS instead of doing a layout with
+ // inaccurate information.
+ HTMLElement* bodyElement = body();
+ if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
+ m_pendingSheetLayout = DidLayoutWithPendingSheets;
+ styleResolverChanged();
+ } else if (m_hasNodesWithPlaceholderStyle) {
+ // If new nodes have been added or style recalc has been done with style sheets still
+ // pending, some nodes may not have had their real style calculated yet. Normally this
+ // gets cleaned when style sheets arrive but here we need up-to-date style immediately.
+ updateRenderTree(Force);
}
- if (canPartialLayout && view())
- view()->partialLayout().setStopAtRenderer(stopLayoutAtNode->renderer());
}
updateLayout();
- if (view())
- view()->partialLayout().reset();
+ if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view())
+ view()->flushAnyPendingPostLayoutTasks();
}
PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
@@ -1880,7 +2055,6 @@ bool Document::isPageBoxVisible(int pageIndex)
void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
{
RefPtr<RenderStyle> style = styleForPage(pageIndex);
- RenderView* view = renderView();
int width = pageSize.width();
int height = pageSize.height();
@@ -1899,8 +2073,8 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
LengthSize size = style->pageSize();
ASSERT(size.width().isFixed());
ASSERT(size.height().isFixed());
- width = valueForLength(size.width(), 0, view);
- height = valueForLength(size.height(), 0, view);
+ width = valueForLength(size.width(), 0);
+ height = valueForLength(size.height(), 0);
break;
}
default:
@@ -1910,10 +2084,10 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
// The percentage is calculated with respect to the width even for margin top and bottom.
// http://www.w3.org/TR/CSS2/box.html#margin-properties
- marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width, view);
- marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width, view);
- marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width, view);
- marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width, view);
+ marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width);
+ marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width);
+ marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width);
+ marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width);
}
void Document::setIsViewSource(bool isViewSource)
@@ -1926,6 +2100,58 @@ void Document::setIsViewSource(bool isViewSource)
didUpdateSecurityOrigin();
}
+bool Document::dirtyElementsForLayerUpdate()
+{
+ if (m_layerUpdateSVGFilterElements.isEmpty())
+ return false;
+
+ for (WillBeHeapHashSet<RawPtrWillBeMember<Element> >::iterator it = m_layerUpdateSVGFilterElements.begin(), end = m_layerUpdateSVGFilterElements.end(); it != end; ++it)
+ (*it)->setNeedsStyleRecalc(LocalStyleChange);
+ m_layerUpdateSVGFilterElements.clear();
+ return true;
+}
+
+void Document::scheduleSVGFilterLayerUpdateHack(Element& element)
+{
+ if (element.styleChangeType() == NeedsReattachStyleChange)
+ return;
+ element.setSVGFilterNeedsLayerUpdate();
+ m_layerUpdateSVGFilterElements.add(&element);
+ scheduleRenderTreeUpdateIfNeeded();
+}
+
+void Document::unscheduleSVGFilterLayerUpdateHack(Element& element)
+{
+ element.clearSVGFilterNeedsLayerUpdate();
+ m_layerUpdateSVGFilterElements.remove(&element);
+}
+
+void Document::scheduleUseShadowTreeUpdate(SVGUseElement& element)
+{
+ m_useElementsNeedingUpdate.add(&element);
+ scheduleRenderTreeUpdateIfNeeded();
+}
+
+void Document::unscheduleUseShadowTreeUpdate(SVGUseElement& element)
+{
+ m_useElementsNeedingUpdate.remove(&element);
+}
+
+void Document::updateUseShadowTreesIfNeeded()
+{
+ ScriptForbiddenScope forbidScript;
+
+ if (m_useElementsNeedingUpdate.isEmpty())
+ return;
+
+ WillBeHeapVector<RawPtrWillBeMember<SVGUseElement> > elements;
+ copyToVector(m_useElementsNeedingUpdate, elements);
+ m_useElementsNeedingUpdate.clear();
+
+ for (WillBeHeapVector<RawPtrWillBeMember<SVGUseElement> >::iterator it = elements.begin(), end = elements.end(); it != end; ++it)
+ (*it)->buildPendingResource();
+}
+
StyleResolver* Document::styleResolver() const
{
return m_styleEngine->resolver();
@@ -1943,7 +2169,7 @@ void Document::clearStyleResolver()
void Document::attach(const AttachContext& context)
{
- ASSERT(m_lifecyle.state() == DocumentLifecycle::Inactive);
+ ASSERT(m_lifecycle.state() == DocumentLifecycle::Inactive);
ASSERT(!m_axObjectCache || this != topDocument());
m_renderView = new RenderView(this);
@@ -1951,22 +2177,28 @@ void Document::attach(const AttachContext& context)
m_renderView->setIsInWindow(true);
m_renderView->setStyle(StyleResolver::styleForDocument(*this));
- view()->updateCompositingLayersAfterStyleChange();
-
- m_styleEngine->didAttach();
+ m_renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
ContainerNode::attach(context);
- m_lifecyle.advanceTo(DocumentLifecycle::Active);
+ // FastTextAutosizer can't update render view info while the Document is detached, so update now in case anything changed.
+ if (FastTextAutosizer* textAutosizer = fastTextAutosizer())
+ textAutosizer->updatePageInfo();
+
+ m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
}
void Document::detach(const AttachContext& context)
{
ASSERT(isActive());
- m_lifecyle.advanceTo(DocumentLifecycle::Stopping);
+ m_lifecycle.advanceTo(DocumentLifecycle::Stopping);
if (page())
page()->documentDetached(this);
+ InspectorInstrumentation::documentDetached(this);
+
+ if (m_frame->loader().client()->sharedWorkerRepositoryClient())
+ m_frame->loader().client()->sharedWorkerRepositoryClient()->documentDetached(this);
if (this == topDocument())
clearAXObjectCache();
@@ -1979,16 +2211,14 @@ void Document::detach(const AttachContext& context)
m_scriptedAnimationController.clear();
if (svgExtensions())
- accessSVGExtensions()->pauseAnimations();
+ accessSVGExtensions().pauseAnimations();
- // FIXME: This shouldn't be needed once DOMWindow becomes ExecutionContext.
+ // FIXME: This shouldn't be needed once LocalDOMWindow becomes ExecutionContext.
if (m_domWindow)
m_domWindow->clearEventQueue();
- RenderView* renderView = m_renderView;
-
- if (renderView)
- renderView->setIsInWindow(false);
+ if (m_renderView)
+ m_renderView->setIsInWindow(false);
if (m_frame) {
FrameView* view = m_frame->view();
@@ -1996,28 +2226,20 @@ void Document::detach(const AttachContext& context)
view->detachCustomScrollbars();
}
- // Indicate destruction mode by setting the renderer to null.
- // FIXME: Don't do this and use m_lifecycle.state() == Stopping instead.
- setRenderer(0);
- m_renderView = 0;
-
- m_hoverNode = 0;
- m_focusedElement = 0;
- m_activeElement = 0;
+ m_hoverNode = nullptr;
+ m_focusedElement = nullptr;
+ m_activeHoverElement = nullptr;
+ m_autofocusElement = nullptr;
+ m_renderView = 0;
ContainerNode::detach(context);
- unscheduleStyleRecalc();
-
m_styleEngine->didDetach();
- if (renderView)
- renderView->destroy();
-
- if (m_touchEventTargets && m_touchEventTargets->size() && parentDocument())
- parentDocument()->didRemoveEventTargetNode(this);
+ if (Document* parentDoc = parentDocument())
+ parentDoc->didClearTouchEventHandlers(this);
- // This is required, as our Frame might delete itself as soon as it detaches
+ // This is required, as our LocalFrame might delete itself as soon as it detaches
// us. However, this violates Node::detach() semantics, as it's never
// possible to re-attach. Eventually Document::detach() should be renamed,
// or this setting of the frame to 0 could be made explicit in each of the
@@ -2028,7 +2250,18 @@ void Document::detach(const AttachContext& context)
m_mediaQueryMatcher->documentDestroyed();
lifecycleNotifier().notifyDocumentWasDetached();
- m_lifecyle.advanceTo(DocumentLifecycle::Stopped);
+ m_lifecycle.advanceTo(DocumentLifecycle::Stopped);
+#if ENABLE(OILPAN)
+ // This mirrors the clearing of the document object's touch
+ // handlers that happens when the LocalDOMWindow is destructed in a
+ // non-Oilpan setting (LocalDOMWindow::removeAllEventListeners()),
+ // except that it is now done during detach instead.
+ didClearTouchEventHandlers(this);
+
+ // Done with the window, explicitly clear to hasten its
+ // destruction.
+ clearDOMWindow();
+#endif
}
void Document::prepareForDestruction()
@@ -2040,19 +2273,17 @@ void Document::prepareForDestruction()
if (!isActive())
return;
- if (DOMWindow* window = this->domWindow())
+ if (LocalDOMWindow* window = this->domWindow())
window->willDetachDocumentFromFrame();
detach();
}
void Document::removeAllEventListeners()
{
- EventTarget::removeAllEventListeners();
+ ContainerNode::removeAllEventListeners();
- if (DOMWindow* domWindow = this->domWindow())
+ if (LocalDOMWindow* domWindow = this->domWindow())
domWindow->removeAllEventListeners();
- for (Node* node = firstChild(); node; node = NodeTraversal::next(*node))
- node->removeAllEventListeners();
}
void Document::clearAXObjectCache()
@@ -2070,10 +2301,10 @@ AXObjectCache* Document::existingAXObjectCache() const
// If the renderer is gone then we are in the process of destruction.
// This method will be called before m_frame = 0.
- if (!topDocument()->renderView())
+ if (!topDocument().renderView())
return 0;
- return topDocument()->m_axObjectCache.get();
+ return topDocument().m_axObjectCache.get();
}
AXObjectCache* Document::axObjectCache() const
@@ -2085,43 +2316,33 @@ AXObjectCache* Document::axObjectCache() const
// document. This is because we need to be able to get from any WebCoreAXObject
// to any other WebCoreAXObject on the same page. Using a single cache allows
// lookups across nested webareas (i.e. multiple documents).
- Document* topDocument = this->topDocument();
+ Document& topDocument = this->topDocument();
// If the document has already been detached, do not make a new axObjectCache.
- if (!topDocument->renderView())
+ if (!topDocument.renderView())
return 0;
ASSERT(topDocument == this || !m_axObjectCache);
- if (!topDocument->m_axObjectCache)
- topDocument->m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
- return topDocument->m_axObjectCache.get();
+ if (!topDocument.m_axObjectCache)
+ topDocument.m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
+ return topDocument.m_axObjectCache.get();
}
-void Document::setVisuallyOrdered()
-{
- m_visuallyOrdered = true;
- // FIXME: How is possible to not have a renderer here?
- if (renderView())
- renderView()->style()->setRTLOrdering(VisualOrder);
- setNeedsStyleRecalc();
-}
-
-PassRefPtr<DocumentParser> Document::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> Document::createParser()
{
if (isHTMLDocument()) {
- bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(this->page());
- return HTMLDocumentParser::create(toHTMLDocument(this), reportErrors);
+ bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(page());
+ return HTMLDocumentParser::create(toHTMLDocument(*this), reportErrors);
}
// FIXME: this should probably pass the frame instead
- return XMLDocumentParser::create(this, view());
+ return XMLDocumentParser::create(*this, view());
}
bool Document::isFrameSet() const
{
if (!isHTMLDocument())
return false;
- HTMLElement* bodyElement = body();
- return bodyElement && bodyElement->hasTagName(framesetTag);
+ return isHTMLFrameSetElement(body());
}
ScriptableDocumentParser* Document::scriptableDocumentParser() const
@@ -2129,8 +2350,13 @@ ScriptableDocumentParser* Document::scriptableDocumentParser() const
return parser() ? parser()->asScriptableDocumentParser() : 0;
}
-void Document::open(Document* ownerDocument)
+void Document::open(Document* ownerDocument, ExceptionState& exceptionState)
{
+ if (importLoader()) {
+ exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support open().");
+ return;
+ }
+
if (ownerDocument) {
setURL(ownerDocument->url());
m_cookieURL = ownerDocument->cookieURL();
@@ -2153,7 +2379,7 @@ void Document::open(Document* ownerDocument)
m_frame->loader().stopAllLoaders();
}
- removeAllEventListeners();
+ removeAllEventListenersRecursively();
implicitOpen();
if (ScriptableDocumentParser* parser = scriptableDocumentParser())
parser->setWasCreatedByScript(true);
@@ -2185,7 +2411,7 @@ void Document::cancelParsing()
explicitClose();
}
-PassRefPtr<DocumentParser> Document::implicitOpen()
+PassRefPtrWillBeRawPtr<DocumentParser> Document::implicitOpen()
{
cancelParsing();
@@ -2194,12 +2420,6 @@ PassRefPtr<DocumentParser> Document::implicitOpen()
setCompatibilityMode(NoQuirksMode);
- // Documents rendered seamlessly should start out requiring a stylesheet
- // collection update in order to ensure they inherit all the relevant data
- // from their parent.
- if (shouldDisplaySeamlesslyWithParent())
- styleResolverChanged(RecalcStyleDeferred);
-
m_parser = createParser();
setParsing(true);
setReadyState(Loading);
@@ -2212,25 +2432,29 @@ HTMLElement* Document::body() const
if (!documentElement())
return 0;
- for (Node* child = documentElement()->firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(framesetTag) || child->hasTagName(bodyTag))
- return toHTMLElement(child);
+ for (HTMLElement* child = Traversal<HTMLElement>::firstWithin(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (isHTMLFrameSetElement(*child) || isHTMLBodyElement(*child))
+ return child;
}
return 0;
}
-void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionState& exceptionState)
+void Document::setBody(PassRefPtrWillBeRawPtr<HTMLElement> prpNewBody, ExceptionState& exceptionState)
{
- RefPtr<HTMLElement> newBody = prpNewBody;
+ RefPtrWillBeRawPtr<HTMLElement> newBody = prpNewBody;
- if (!newBody || !documentElement()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (!newBody) {
+ exceptionState.throwDOMException(HierarchyRequestError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLElement"));
+ return;
+ }
+ if (!documentElement()) {
+ exceptionState.throwDOMException(HierarchyRequestError, "No document element exists.");
return;
}
- if (!newBody->hasTagName(bodyTag) && !newBody->hasTagName(framesetTag)) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (!isHTMLBodyElement(*newBody) && !isHTMLFrameSetElement(*newBody)) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The new body element is of type '" + newBody->tagName() + "'. It must be either a 'BODY' or 'FRAMESET' element.");
return;
}
@@ -2244,24 +2468,47 @@ void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionState& excep
documentElement()->appendChild(newBody.release(), exceptionState);
}
-HTMLHeadElement* Document::head()
+HTMLHeadElement* Document::head() const
{
Node* de = documentElement();
if (!de)
return 0;
- for (Node* node = de->firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(headTag))
- return toHTMLHeadElement(node);
+ return Traversal<HTMLHeadElement>::firstChild(*de);
+}
+
+Element* Document::viewportDefiningElement(RenderStyle* rootStyle) const
+{
+ // If a BODY element sets non-visible overflow, it is to be propagated to the viewport, as long
+ // as the following conditions are all met:
+ // (1) The root element is HTML.
+ // (2) It is the primary BODY element (we only assert for this, expecting callers to behave).
+ // (3) The root element has visible overflow.
+ // Otherwise it's the root element's properties that are to be propagated.
+ Element* rootElement = documentElement();
+ Element* bodyElement = body();
+ if (!rootElement)
+ return 0;
+ if (!rootStyle) {
+ rootStyle = rootElement->renderStyle();
+ if (!rootStyle)
+ return 0;
}
- return 0;
+ if (bodyElement && rootStyle->isOverflowVisible() && isHTMLHtmlElement(*rootElement))
+ return bodyElement;
+ return rootElement;
}
-void Document::close()
+void Document::close(ExceptionState& exceptionState)
{
// FIXME: We should follow the specification more closely:
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-close
+ if (importLoader()) {
+ exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support close().");
+ return;
+ }
+
if (!scriptableDocumentParser() || !scriptableDocumentParser()->wasCreatedByScript() || !scriptableDocumentParser()->isParsing())
return;
@@ -2270,7 +2517,7 @@ void Document::close()
void Document::explicitClose()
{
- if (RefPtr<DocumentParser> parser = m_parser)
+ if (RefPtrWillBeRawPtr<DocumentParser> parser = m_parser)
parser->finish();
if (!m_frame) {
@@ -2298,9 +2545,9 @@ void Document::implicitClose()
if (!doload)
return;
- // The call to dispatchWindowLoadEvent can detach the DOMWindow and cause it (and its
+ // The call to dispatchWindowLoadEvent can detach the LocalDOMWindow and cause it (and its
// attached Document) to be destroyed.
- RefPtr<DOMWindow> protectedWindow(this->domWindow());
+ RefPtrWillBeRawPtr<LocalDOMWindow> protectedWindow(this->domWindow());
m_loadEventProgress = LoadEventInProgress;
@@ -2312,7 +2559,6 @@ void Document::implicitClose()
detachParser();
if (frame() && frame()->script().canExecuteScripts(NotAboutToExecuteScript)) {
- ImageLoader::dispatchPendingBeforeLoadEvents();
ImageLoader::dispatchPendingLoadEvents();
ImageLoader::dispatchPendingErrorEvents();
@@ -2324,10 +2570,9 @@ void Document::implicitClose()
// those two functions repeatedly and don't save them on the stack.
// To align the HTML load event and the SVGLoad event for the outermost <svg> element, fire it from
- // here, instead of doing it from SVGElement::finishedParsingChildren (if externalResourcesRequired="false",
- // which is the default, for ='true' its fired at a later time, once all external resources finished loading).
+ // here, instead of doing it from SVGElement::finishedParsingChildren.
if (svgExtensions())
- accessSVGExtensions()->dispatchSVGLoadEventToOutermostSVGElements();
+ accessSVGExtensions().dispatchSVGLoadEventToOutermostSVGElements();
if (protectedWindow)
protectedWindow->documentWasClosed();
@@ -2350,16 +2595,14 @@ void Document::implicitClose()
// Just bail out. Before or during the onload we were shifted to another page.
// The old i-Bench suite does this. When this happens don't bother painting or laying out.
m_loadEventProgress = LoadEventCompleted;
- view()->unscheduleRelayout();
return;
}
// We used to force a synchronous display and flush here. This really isn't
// necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
// (if your platform is syncing flushes and limiting them to 60fps).
- m_overMinimumLayoutThreshold = true;
if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
- updateStyleIfNeeded();
+ updateRenderTreeIfNeeded();
// Always do a layout after loading if needed.
if (view() && renderView() && (!renderView()->firstChild() || renderView()->needsLayout()))
@@ -2386,7 +2629,7 @@ void Document::implicitClose()
}
if (svgExtensions())
- accessSVGExtensions()->startAnimations();
+ accessSVGExtensions().startAnimations();
}
bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigation)
@@ -2397,9 +2640,9 @@ bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigatio
if (!body())
return true;
- RefPtr<Document> protect(this);
+ RefPtrWillBeRawPtr<Document> protect(this);
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
+ RefPtrWillBeRawPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
m_loadEventProgress = BeforeUnloadEventInProgress;
m_domWindow->dispatchEvent(beforeUnloadEvent.get(), this);
m_loadEventProgress = BeforeUnloadEventCompleted;
@@ -2423,17 +2666,17 @@ bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigatio
void Document::dispatchUnloadEvents()
{
- RefPtr<Document> protect(this);
+ RefPtrWillBeRawPtr<Document> protect(this);
if (m_parser)
m_parser->stopParsing();
if (m_loadEventProgress >= LoadEventTried && m_loadEventProgress <= UnloadEventInProgress) {
Element* currentFocusedElement = focusedElement();
- if (currentFocusedElement && currentFocusedElement->hasTagName(inputTag))
- toHTMLInputElement(currentFocusedElement)->endEditing();
+ if (isHTMLInputElement(currentFocusedElement))
+ toHTMLInputElement(*currentFocusedElement).endEditing();
if (m_loadEventProgress < PageHideInProgress) {
m_loadEventProgress = PageHideInProgress;
- if (DOMWindow* window = domWindow())
+ if (LocalDOMWindow* window = domWindow())
window->dispatchEvent(PageTransitionEvent::create(EventTypeNames::pagehide, false), this);
if (!m_frame)
return;
@@ -2443,7 +2686,7 @@ void Document::dispatchUnloadEvents()
// time into freed memory.
RefPtr<DocumentLoader> documentLoader = m_frame->loader().provisionalDocumentLoader();
m_loadEventProgress = UnloadEventInProgress;
- RefPtr<Event> unloadEvent(Event::create(EventTypeNames::unload));
+ RefPtrWillBeRawPtr<Event> unloadEvent(Event::create(EventTypeNames::unload));
if (documentLoader && !documentLoader->timing()->unloadEventStart() && !documentLoader->timing()->unloadEventEnd()) {
DocumentLoadTiming* timing = documentLoader->timing();
ASSERT(timing->navigationStart());
@@ -2464,7 +2707,7 @@ void Document::dispatchUnloadEvents()
bool keepEventListeners = m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->loader().provisionalDocumentLoader()
&& isSecureTransitionTo(m_frame->loader().provisionalDocumentLoader()->url());
if (!keepEventListeners)
- removeAllEventListeners();
+ removeAllEventListenersRecursively();
}
Document::PageDismissalType Document::pageDismissalEventBeingDispatched() const
@@ -2480,42 +2723,29 @@ Document::PageDismissalType Document::pageDismissalEventBeingDispatched() const
void Document::setParsing(bool b)
{
- m_bParsing = b;
-
- if (m_bParsing && !m_sharedObjectPool)
- m_sharedObjectPool = DocumentSharedObjectPool::create();
+ m_isParsing = b;
- if (!m_bParsing && view())
- view()->scheduleRelayout();
+ if (m_isParsing && !m_elementDataCache)
+ m_elementDataCache = ElementDataCache::create();
}
-bool Document::shouldScheduleLayout()
+bool Document::shouldScheduleLayout() const
{
// This function will only be called when FrameView thinks a layout is needed.
// This enforces a couple extra rules.
//
// (a) Only schedule a layout once the stylesheets are loaded.
// (b) Only schedule layout once we have a body element.
+ if (!isActive())
+ return false;
- return (haveStylesheetsLoaded() && body())
- || (documentElement() && !isHTMLHtmlElement(documentElement()));
-}
-
-bool Document::shouldParserYieldAgressivelyBeforeScriptExecution()
-{
- return view() && view()->layoutPending() && !minimumLayoutDelay();
-}
-
-int Document::minimumLayoutDelay()
-{
- if (m_overMinimumLayoutThreshold)
- return 0;
+ if (isRenderingReady() && body())
+ return true;
- int elapsed = elapsedTime();
- m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
+ if (documentElement() && !isHTMLHtmlElement(*documentElement()))
+ return true;
- // We'll want to schedule the timer to fire at the minimum layout threshold.
- return max(0, cLayoutScheduleThreshold - elapsed);
+ return false;
}
int Document::elapsedTime() const
@@ -2523,8 +2753,13 @@ int Document::elapsedTime() const
return static_cast<int>((currentTime() - m_startTime) * 1000);
}
-void Document::write(const SegmentedString& text, Document* ownerDocument)
+void Document::write(const SegmentedString& text, Document* ownerDocument, ExceptionState& exceptionState)
{
+ if (importLoader()) {
+ exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support write().");
+ return;
+ }
+
NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);
m_writeRecursionIsTooDeep = (m_writeRecursionDepth > 1) && m_writeRecursionIsTooDeep;
@@ -2534,8 +2769,11 @@ void Document::write(const SegmentedString& text, Document* ownerDocument)
return;
bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
- if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)
+
+ if (!hasInsertionPoint && m_ignoreDestructiveWriteCount) {
+ addConsoleMessage(JSMessageSource, WarningMessageLevel, ExceptionMessages::failedToExecute("write", "Document", "It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened."));
return;
+ }
if (!hasInsertionPoint)
open(ownerDocument);
@@ -2544,14 +2782,16 @@ void Document::write(const SegmentedString& text, Document* ownerDocument)
m_parser->insert(text);
}
-void Document::write(const String& text, Document* ownerDocument)
+void Document::write(const String& text, Document* ownerDocument, ExceptionState& exceptionState)
{
- write(SegmentedString(text), ownerDocument);
+ write(SegmentedString(text), ownerDocument, exceptionState);
}
-void Document::writeln(const String& text, Document* ownerDocument)
+void Document::writeln(const String& text, Document* ownerDocument, ExceptionState& exceptionState)
{
- write(text, ownerDocument);
+ write(text, ownerDocument, exceptionState);
+ if (exceptionState.hadException())
+ return;
write("\n", ownerDocument);
}
@@ -2578,7 +2818,7 @@ EventTarget* Document::errorEventTarget()
return domWindow();
}
-void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
{
internalAddMessage(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack, 0);
}
@@ -2590,9 +2830,8 @@ void Document::setURL(const KURL& url)
return;
m_url = newURL;
- m_documentURI = m_url.string();
updateBaseURL();
- contextFeatures()->urlDidChange(this);
+ contextFeatures().urlDidChange(this);
}
void Document::updateBaseURL()
@@ -2600,18 +2839,14 @@ void Document::updateBaseURL()
KURL oldBaseURL = m_baseURL;
// DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML], the base URI is computed using
// first the value of the href attribute of the HTML BASE element if any, and the value of the documentURI attribute
- // from the Document interface otherwise.
+ // from the Document interface otherwise (which we store, preparsed, in m_url).
if (!m_baseElementURL.isEmpty())
m_baseURL = m_baseElementURL;
else if (!m_baseURLOverride.isEmpty())
m_baseURL = m_baseURLOverride;
- else {
- // The documentURI attribute is read-only from JavaScript, but writable from Objective C, so we need to retain
- // this fallback behavior. We use a null base URL, since the documentURI attribute is an arbitrary string
- // and DOM 3 Core does not specify how it should be resolved.
- // FIXME: Now that we don't support Objective-C this can probably be removed.
- m_baseURL = KURL(ParsedURLString, documentURI());
- }
+ else
+ m_baseURL = m_url;
+
selectorQueryCache().invalidate();
if (!m_baseURL.isValid())
@@ -2629,10 +2864,8 @@ void Document::updateBaseURL()
if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) {
// Base URL change changes any relative visited links.
// FIXME: There are other URLs in the tree that would need to be re-evaluated on dynamic base URL change. Style should be invalidated too.
- for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element)) {
- if (isHTMLAnchorElement(element))
- toHTMLAnchorElement(element)->invalidateCachedVisitedLinkHash();
- }
+ for (HTMLAnchorElement* anchor = Traversal<HTMLAnchorElement>::firstWithin(*this); anchor; anchor = Traversal<HTMLAnchorElement>::next(*anchor))
+ anchor->invalidateCachedVisitedLinkHash();
}
}
@@ -2647,21 +2880,19 @@ void Document::processBaseElement()
// Find the first href attribute in a base element and the first target attribute in a base element.
const AtomicString* href = 0;
const AtomicString* target = 0;
- for (Element* element = ElementTraversal::firstWithin(*this); element && (!href || !target); element = ElementTraversal::next(*element)) {
- if (element->hasTagName(baseTag)) {
- if (!href) {
- const AtomicString& value = element->fastGetAttribute(hrefAttr);
- if (!value.isNull())
- href = &value;
- }
- if (!target) {
- const AtomicString& value = element->fastGetAttribute(targetAttr);
- if (!value.isNull())
- target = &value;
- }
- if (contentSecurityPolicy()->isActive())
- UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
+ for (HTMLBaseElement* base = Traversal<HTMLBaseElement>::firstWithin(*this); base && (!href || !target); base = Traversal<HTMLBaseElement>::next(*base)) {
+ if (!href) {
+ const AtomicString& value = base->fastGetAttribute(hrefAttr);
+ if (!value.isNull())
+ href = &value;
+ }
+ if (!target) {
+ const AtomicString& value = base->fastGetAttribute(targetAttr);
+ if (!value.isNull())
+ target = &value;
}
+ if (contentSecurityPolicy()->isActive())
+ UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
}
// FIXME: Since this doesn't share code with completeURL it may not handle encodings correctly.
@@ -2692,30 +2923,24 @@ void Document::disableEval(const String& errorMessage)
frame()->script().disableEval(errorMessage);
}
-bool Document::canNavigate(Frame* targetFrame)
+bool Document::canNavigate(const Frame& targetFrame)
{
if (!m_frame)
return false;
- // FIXME: We shouldn't call this function without a target frame, but
- // fast/forms/submit-to-blank-multiple-times.html depends on this function
- // returning true when supplied with a 0 targetFrame.
- if (!targetFrame)
- return true;
-
// Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
return true;
if (isSandboxed(SandboxNavigation)) {
- if (targetFrame->tree().isDescendantOf(m_frame))
+ if (targetFrame.tree().isDescendantOf(m_frame))
return true;
const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
- printNavigationErrorMessage(*targetFrame, url(), reason);
+ printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), reason);
return false;
}
@@ -2729,7 +2954,7 @@ bool Document::canNavigate(Frame* targetFrame)
//
// See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
// historical information about this security check.
- if (canAccessAncestor(origin, targetFrame))
+ if (canAccessAncestor(origin, &targetFrame))
return true;
// Top-level frames are easier to navigate than other frames because they
@@ -2743,100 +2968,112 @@ bool Document::canNavigate(Frame* targetFrame)
// some way related to the frame being navigate (e.g., by the "opener"
// and/or "parent" relation). Requiring some sort of relation prevents a
// document from navigating arbitrary, unrelated top-level frames.
- if (!targetFrame->tree().parent()) {
+ if (!targetFrame.tree().parent()) {
if (targetFrame == m_frame->loader().opener())
return true;
- if (canAccessAncestor(origin, targetFrame->loader().opener()))
+ // FIXME: We don't have access to RemoteFrame's opener yet.
+ if (targetFrame.isLocalFrame() && canAccessAncestor(origin, toLocalFrame(targetFrame).loader().opener()))
return true;
}
- printNavigationErrorMessage(*targetFrame, url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
+ printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
return false;
}
-Frame* Document::findUnsafeParentScrollPropagationBoundary()
+LocalFrame* Document::findUnsafeParentScrollPropagationBoundary()
{
- Frame* currentFrame = m_frame;
+ LocalFrame* currentFrame = m_frame;
Frame* ancestorFrame = currentFrame->tree().parent();
while (ancestorFrame) {
- if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrigin()))
+ // FIXME: We don't yet have access to a RemoteFrame's security origin.
+ if (!ancestorFrame->isLocalFrame())
return currentFrame;
- currentFrame = ancestorFrame;
+ if (!toLocalFrame(ancestorFrame)->document()->securityOrigin()->canAccess(securityOrigin()))
+ return currentFrame;
+ currentFrame = toLocalFrame(ancestorFrame);
ancestorFrame = ancestorFrame->tree().parent();
}
return 0;
}
-
-void Document::seamlessParentUpdatedStylesheets()
+void Document::didLoadAllImports()
{
- m_styleEngine->didModifySeamlessParentStyleSheet();
- styleResolverChanged(RecalcStyleImmediately);
+ if (!haveStylesheetsLoaded())
+ return;
+ if (!importLoader())
+ styleResolverMayHaveChanged();
+ didLoadAllScriptBlockingResources();
}
void Document::didRemoveAllPendingStylesheet()
{
- m_needsNotifyRemoveAllPendingStylesheet = false;
+ styleResolverMayHaveChanged();
+
+ // Only imports on master documents can trigger rendering.
+ if (HTMLImportLoader* import = importLoader())
+ import->didRemoveAllPendingStylesheet();
+ if (!haveImportsLoaded())
+ return;
+ didLoadAllScriptBlockingResources();
+}
- styleResolverChanged(RecalcStyleDeferred, AnalyzedStyleUpdate);
- executeScriptsWaitingForResourcesIfNeeded();
+void Document::didLoadAllScriptBlockingResources()
+{
+ m_executeScriptsWaitingForResourcesTimer.startOneShot(0, FROM_HERE);
if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
view()->scrollToFragment(m_url);
}
-void Document::executeScriptsWaitingForResourcesIfNeeded()
+void Document::executeScriptsWaitingForResourcesTimerFired(Timer<Document>*)
{
- if (!haveStylesheetsAndImportsLoaded())
+ if (!isRenderingReady())
return;
if (ScriptableDocumentParser* parser = scriptableDocumentParser())
parser->executeScriptsWaitingForResources();
}
-
-CSSStyleSheet* Document::elementSheet()
+CSSStyleSheet& Document::elementSheet()
{
if (!m_elemSheet)
m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
- return m_elemSheet.get();
+ return *m_elemSheet;
}
-void Document::processHttpEquiv(const AtomicString& equiv, const AtomicString& content)
+void Document::processHttpEquiv(const AtomicString& equiv, const AtomicString& content, bool inDocumentHeadElement)
{
ASSERT(!equiv.isNull() && !content.isNull());
- if (equalIgnoringCase(equiv, "default-style"))
+ if (equalIgnoringCase(equiv, "default-style")) {
processHttpEquivDefaultStyle(content);
- else if (equalIgnoringCase(equiv, "refresh"))
+ } else if (equalIgnoringCase(equiv, "refresh")) {
processHttpEquivRefresh(content);
- else if (equalIgnoringCase(equiv, "set-cookie"))
+ } else if (equalIgnoringCase(equiv, "set-cookie")) {
processHttpEquivSetCookie(content);
- else if (equalIgnoringCase(equiv, "content-language"))
+ } else if (equalIgnoringCase(equiv, "content-language")) {
setContentLanguage(content);
- else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
+ } else if (equalIgnoringCase(equiv, "x-dns-prefetch-control")) {
parseDNSPrefetchControlHeader(content);
- else if (equalIgnoringCase(equiv, "x-frame-options"))
+ } else if (equalIgnoringCase(equiv, "x-frame-options")) {
processHttpEquivXFrameOptions(content);
- else if (equalIgnoringCase(equiv, "content-security-policy")
- || equalIgnoringCase(equiv, "content-security-policy-report-only")
- || equalIgnoringCase(equiv, "x-webkit-csp")
- || equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
- processHttpEquivContentSecurityPolicy(equiv, content);
+ } else if (equalIgnoringCase(equiv, "content-security-policy") || equalIgnoringCase(equiv, "content-security-policy-report-only")) {
+ if (inDocumentHeadElement)
+ processHttpEquivContentSecurityPolicy(equiv, content);
+ else
+ contentSecurityPolicy()->reportMetaOutsideHead(content);
+ }
}
void Document::processHttpEquivContentSecurityPolicy(const AtomicString& equiv, const AtomicString& content)
{
+ if (importLoader())
+ return;
if (equalIgnoringCase(equiv, "content-security-policy"))
- contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce);
+ contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceMeta);
else if (equalIgnoringCase(equiv, "content-security-policy-report-only"))
- contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report);
- // FIXME: Remove deprecation messages after the next release branch.
- else if (equalIgnoringCase(equiv, "x-webkit-csp"))
- UseCounter::countDeprecation(this, UseCounter::PrefixedContentSecurityPolicy);
- else if (equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
- UseCounter::countDeprecation(this, UseCounter::PrefixedContentSecurityPolicyReportOnly);
+ contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceMeta);
else
ASSERT_NOT_REACHED();
}
@@ -2851,7 +3088,7 @@ void Document::processHttpEquivDefaultStyle(const AtomicString& content)
// -dwh
m_styleEngine->setSelectedStylesheetSetName(content);
m_styleEngine->setPreferredStylesheetSetName(content);
- styleResolverChanged(RecalcStyleDeferred);
+ styleResolverChanged();
}
void Document::processHttpEquivRefresh(const AtomicString& content)
@@ -2899,7 +3136,7 @@ void Document::processHttpEquivSetCookie(const AtomicString& content)
void Document::processHttpEquivXFrameOptions(const AtomicString& content)
{
- Frame* frame = this->frame();
+ LocalFrame* frame = this->frame();
if (!frame)
return;
@@ -2911,7 +3148,7 @@ void Document::processHttpEquivXFrameOptions(const AtomicString& content)
// Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
// intent, we must navigate away from the possibly partially-rendered document to a location that
// doesn't inherit the parent's SecurityOrigin.
- frame->navigationScheduler().scheduleLocationChange(this, SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+ frame->navigationScheduler().scheduleLocationChange(this, SecurityOrigin::urlWithUniqueSecurityOrigin(), Referrer());
addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
}
}
@@ -2923,6 +3160,10 @@ bool Document::shouldMergeWithLegacyDescription(ViewportDescription::Type origin
void Document::setViewportDescription(const ViewportDescription& viewportDescription)
{
+ // The UA-defined min-width is used by the processing of legacy meta tags.
+ if (!viewportDescription.isSpecifiedByAuthor())
+ m_viewportDefaultMinWidth = viewportDescription.minWidth;
+
if (viewportDescription.isLegacyViewportType()) {
if (settings() && !settings()->viewportMetaEnabled())
return;
@@ -2952,7 +3193,7 @@ void Document::updateViewportDescription()
#ifndef NDEBUG
m_didDispatchViewportPropertiesChanged = true;
#endif
- page()->chrome().dispatchViewportPropertiesDidChange(m_viewportDescription);
+ frameHost()->chrome().dispatchViewportPropertiesDidChange(m_viewportDescription);
}
}
@@ -2960,14 +3201,28 @@ void Document::processReferrerPolicy(const String& policy)
{
ASSERT(!policy.isNull());
- m_referrerPolicy = ReferrerPolicyDefault;
+ if (equalIgnoringCase(policy, "never")) {
+ setReferrerPolicy(ReferrerPolicyNever);
+ } else if (equalIgnoringCase(policy, "always")) {
+ setReferrerPolicy(ReferrerPolicyAlways);
+ } else if (equalIgnoringCase(policy, "origin")) {
+ setReferrerPolicy(ReferrerPolicyOrigin);
+ } else if (equalIgnoringCase(policy, "default")) {
+ setReferrerPolicy(ReferrerPolicyDefault);
+ } else {
+ addConsoleMessage(RenderingMessageSource, ErrorMessageLevel, "Failed to set referrer policy: The value '" + policy + "' is not one of 'always', 'default', 'never', or 'origin'. Defaulting to 'never'.");
+ setReferrerPolicy(ReferrerPolicyNever);
+ }
+}
+
+void Document::setReferrerPolicy(ReferrerPolicy referrerPolicy)
+{
+ // FIXME: Can we adopt the CSP referrer policy merge algorithm? Or does the web rely on being able to modify the referrer policy in-flight?
+ if (m_didSetReferrerPolicy)
+ UseCounter::count(this, UseCounter::ResetReferrerPolicy);
+ m_didSetReferrerPolicy = true;
- if (equalIgnoringCase(policy, "never"))
- m_referrerPolicy = ReferrerPolicyNever;
- else if (equalIgnoringCase(policy, "always"))
- m_referrerPolicy = ReferrerPolicyAlways;
- else if (equalIgnoringCase(policy, "origin"))
- m_referrerPolicy = ReferrerPolicyOrigin;
+ m_referrerPolicy = referrerPolicy;
}
String Document::outgoingReferrer()
@@ -2975,9 +3230,10 @@ String Document::outgoingReferrer()
// See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
// for why we walk the parent chain for srcdoc documents.
Document* referrerDocument = this;
- if (Frame* frame = m_frame) {
+ if (LocalFrame* frame = m_frame) {
while (frame->document()->isSrcdocDocument()) {
- frame = frame->tree().parent();
+ // Srcdoc documents must be local within the containing frame.
+ frame = toLocalFrame(frame->tree().parent());
// Srcdoc documents cannot be top-level documents, by definition,
// because they need to be contained in iframes with the srcdoc.
ASSERT(frame);
@@ -3022,10 +3278,7 @@ bool Document::childTypeAllowed(NodeType type) const
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_NODE:
- case ENTITY_NODE:
- case NOTATION_NODE:
case TEXT_NODE:
- case XPATH_NAMESPACE_NODE:
return false;
case COMMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
@@ -3069,17 +3322,14 @@ bool Document::canReplaceChild(const Node& newChild, const Node& oldChild) const
}
// Then, see how many doctypes and elements might be added by the new child.
- if (newChild.nodeType() == DOCUMENT_FRAGMENT_NODE) {
- for (Node* c = newChild.firstChild(); c; c = c->nextSibling()) {
+ if (newChild.isDocumentFragment()) {
+ for (Node* c = toDocumentFragment(newChild).firstChild(); c; c = c->nextSibling()) {
switch (c->nodeType()) {
case ATTRIBUTE_NODE:
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_NODE:
- case ENTITY_NODE:
- case NOTATION_NODE:
case TEXT_NODE:
- case XPATH_NAMESPACE_NODE:
return false;
case COMMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
@@ -3098,10 +3348,7 @@ bool Document::canReplaceChild(const Node& newChild, const Node& oldChild) const
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_NODE:
- case ENTITY_NODE:
- case NOTATION_NODE:
case TEXT_NODE:
- case XPATH_NAMESPACE_NODE:
return false;
case COMMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
@@ -3121,20 +3368,23 @@ bool Document::canReplaceChild(const Node& newChild, const Node& oldChild) const
return true;
}
-PassRefPtr<Node> Document::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> Document::cloneNode(bool deep)
{
- RefPtr<Document> clone = cloneDocumentWithoutChildren();
+ RefPtrWillBeRawPtr<Document> clone = cloneDocumentWithoutChildren();
clone->cloneDataFromDocument(*this);
if (deep)
cloneChildNodes(clone.get());
return clone.release();
}
-PassRefPtr<Document> Document::cloneDocumentWithoutChildren()
+PassRefPtrWillBeRawPtr<Document> Document::cloneDocumentWithoutChildren()
{
DocumentInit init(url());
- if (isXHTMLDocument())
- return createXHTML(init.withRegistrationContext(registrationContext()));
+ if (isXMLDocument()) {
+ if (isXHTMLDocument())
+ return XMLDocument::createXHTML(init.withRegistrationContext(registrationContext()));
+ return XMLDocument::create(init);
+ }
return create(init);
}
@@ -3144,6 +3394,7 @@ void Document::cloneDataFromDocument(const Document& other)
setEncodingData(other.m_encodingData);
setContextFeatures(other.contextFeatures());
setSecurityOrigin(other.securityOrigin()->isolatedCopy());
+ setMimeType(other.contentType());
}
StyleSheetList* Document::styleSheets()
@@ -3166,7 +3417,15 @@ String Document::selectedStylesheetSet() const
void Document::setSelectedStylesheetSet(const String& aString)
{
m_styleEngine->setSelectedStylesheetSetName(aString);
- styleResolverChanged(RecalcStyleDeferred);
+ styleResolverChanged();
+}
+
+void Document::evaluateMediaQueryListIfNeeded()
+{
+ if (!m_evaluateMediaQueriesOnStyleRecalc)
+ return;
+ evaluateMediaQueryList();
+ m_evaluateMediaQueriesOnStyleRecalc = false;
}
void Document::evaluateMediaQueryList()
@@ -3175,60 +3434,49 @@ void Document::evaluateMediaQueryList()
m_mediaQueryMatcher->styleResolverChanged();
}
-void Document::styleResolverChanged(RecalcStyleTime updateTime, StyleResolverUpdateMode updateMode)
+void Document::notifyResizeForViewportUnits()
+{
+ if (!hasViewportUnits())
+ return;
+ ensureStyleResolver().notifyResizeForViewportUnits();
+ setNeedsStyleRecalcForViewportUnits();
+}
+
+void Document::styleResolverChanged(StyleResolverUpdateMode updateMode)
{
// styleResolverChanged() can be invoked during Document destruction.
// We just skip that case.
if (!m_styleEngine)
return;
- StyleResolverChange change = m_styleEngine->resolverChanged(updateTime, updateMode);
- if (change.needsRepaint()) {
+ m_styleEngine->resolverChanged(updateMode);
+
+ if (didLayoutWithPendingStylesheets() && !m_styleEngine->hasPendingSheets()) {
// We need to manually repaint because we avoid doing all repaints in layout or style
// recalc while sheets are still loading to avoid FOUC.
m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
renderView()->repaintViewAndCompositedLayers();
}
-
- if (!change.needsStyleRecalc())
- return;
-
- m_evaluateMediaQueriesOnStyleRecalc = true;
- setNeedsStyleRecalc();
-
- if (updateTime == RecalcStyleImmediately)
- updateStyleIfNeeded();
}
-void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
+void Document::styleResolverMayHaveChanged()
{
- // If we're not in a frame yet any potential child documents won't have a StyleResolver to update.
- if (!frame())
- return;
-
- // Seamless child frames are expected to notify their seamless children recursively, so we only do direct children.
- for (Frame* child = frame()->tree().firstChild(); child; child = child->tree().nextSibling()) {
- Document* childDocument = child->document();
- if (childDocument->shouldDisplaySeamlesslyWithParent()) {
- ASSERT(childDocument->seamlessParentIFrame()->document() == this);
- childDocument->seamlessParentUpdatedStylesheets();
- }
- }
+ styleResolverChanged(hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate);
}
-void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
+void Document::setHoverNode(PassRefPtrWillBeRawPtr<Node> newHoverNode)
{
m_hoverNode = newHoverNode;
}
-void Document::setActiveElement(PassRefPtr<Element> newActiveElement)
+void Document::setActiveHoverElement(PassRefPtrWillBeRawPtr<Element> newActiveElement)
{
if (!newActiveElement) {
- m_activeElement.clear();
+ m_activeHoverElement.clear();
return;
}
- m_activeElement = newActiveElement;
+ m_activeHoverElement = newActiveElement;
}
void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
@@ -3241,7 +3489,7 @@ void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
return;
bool contains = node->containsIncludingShadowDOM(m_focusedElement.get());
if (contains && (m_focusedElement != node || !amongChildrenOnly))
- setFocusedElement(0);
+ setFocusedElement(nullptr);
}
void Document::hoveredNodeDetached(Node* node)
@@ -3268,17 +3516,17 @@ void Document::hoveredNodeDetached(Node* node)
void Document::activeChainNodeDetached(Node* node)
{
- if (!m_activeElement)
+ if (!m_activeHoverElement)
return;
- if (node != m_activeElement && (!m_activeElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeElement.get())))
+ if (node != m_activeHoverElement && (!m_activeHoverElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeHoverElement.get())))
return;
Node* activeNode = NodeRenderingTraversal::parent(node);
while (activeNode && activeNode->isElementNode() && !activeNode->renderer())
activeNode = NodeRenderingTraversal::parent(activeNode);
- m_activeElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
+ m_activeHoverElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
}
const Vector<AnnotatedRegionValue>& Document::annotatedRegions() const
@@ -3292,9 +3540,11 @@ void Document::setAnnotatedRegions(const Vector<AnnotatedRegionValue>& regions)
setAnnotatedRegionsDirty(false);
}
-bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, FocusDirection direction)
+bool Document::setFocusedElement(PassRefPtrWillBeRawPtr<Element> prpNewFocusedElement, FocusType type)
{
- RefPtr<Element> newFocusedElement = prpNewFocusedElement;
+ m_clearFocusedElementTimer.stop();
+
+ RefPtrWillBeRawPtr<Element> newFocusedElement = prpNewFocusedElement;
// Make sure newFocusedNode is actually in this document
if (newFocusedElement && (newFocusedElement->document() != this))
@@ -3307,8 +3557,8 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
return true;
bool focusChangeBlocked = false;
- RefPtr<Element> oldFocusedElement = m_focusedElement;
- m_focusedElement = 0;
+ RefPtrWillBeRawPtr<Element> oldFocusedElement = m_focusedElement;
+ m_focusedElement = nullptr;
// Remove focus from the existing focus node (if any)
if (oldFocusedElement) {
@@ -3319,28 +3569,27 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
oldFocusedElement->setFocus(false);
- // Dispatch a change event for text fields or textareas that have been edited
- if (oldFocusedElement->wasChangedSinceLastFormControlChangeEvent())
- oldFocusedElement->dispatchFormControlChangeEvent();
-
// Dispatch the blur event and let the node do any other blur related activities (important for text fields)
- oldFocusedElement->dispatchBlurEvent(newFocusedElement.get());
-
- if (m_focusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- newFocusedElement = 0;
- }
+ // If page lost focus, blur event will have already been dispatched
+ if (page() && (page()->focusController().isFocused())) {
+ oldFocusedElement->dispatchBlurEvent(newFocusedElement.get());
+
+ if (m_focusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ newFocusedElement = nullptr;
+ }
- oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, newFocusedElement.get()); // DOM level 3 name for the bubbling blur event.
- // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
- // on it, probably when <rdar://problem/8503958> is resolved.
- oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, newFocusedElement.get()); // DOM level 2 name for compatibility.
+ oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, newFocusedElement.get()); // DOM level 3 name for the bubbling blur event.
+ // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
+ // on it, probably when <rdar://problem/8503958> is resolved.
+ oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, newFocusedElement.get()); // DOM level 2 name for compatibility.
- if (m_focusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- newFocusedElement = 0;
+ if (m_focusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ newFocusedElement = nullptr;
+ }
}
if (view()) {
@@ -3362,31 +3611,36 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
m_focusedElement = newFocusedElement;
// Dispatch the focus event and let the node do any other focus related activities (important for text fields)
- m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), direction);
+ // If page lost focus, event will be dispatched on page focus, don't duplicate
+ if (page() && (page()->focusController().isFocused())) {
+ m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), type);
- if (m_focusedElement != newFocusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- goto SetFocusedElementDone;
- }
- m_focusedElement->dispatchFocusInEvent(EventTypeNames::focusin, oldFocusedElement.get()); // DOM level 3 bubbling focus event.
+ if (m_focusedElement != newFocusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ goto SetFocusedElementDone;
+ }
- if (m_focusedElement != newFocusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- goto SetFocusedElementDone;
- }
+ m_focusedElement->dispatchFocusInEvent(EventTypeNames::focusin, oldFocusedElement.get()); // DOM level 3 bubbling focus event.
- // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
- // on it, probably when <rdar://problem/8503958> is m.
- m_focusedElement->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, oldFocusedElement.get()); // DOM level 2 for compatibility.
+ if (m_focusedElement != newFocusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ goto SetFocusedElementDone;
+ }
- if (m_focusedElement != newFocusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- goto SetFocusedElementDone;
+ // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
+ // on it, probably when <rdar://problem/8503958> is m.
+ m_focusedElement->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, oldFocusedElement.get()); // DOM level 2 for compatibility.
+
+ if (m_focusedElement != newFocusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ goto SetFocusedElementDone;
+ }
}
+
m_focusedElement->setFocus(true);
if (m_focusedElement->isRootEditableElement())
@@ -3417,45 +3671,70 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFocusedElement.get());
}
- if (!focusChangeBlocked && page())
- page()->chrome().focusedNodeChanged(m_focusedElement.get());
+ if (!focusChangeBlocked && frameHost())
+ frameHost()->chrome().focusedNodeChanged(m_focusedElement.get());
SetFocusedElementDone:
- updateStyleIfNeeded();
- if (Frame* frame = this->frame())
+ updateRenderTreeIfNeeded();
+ if (LocalFrame* frame = this->frame())
frame->selection().didChangeFocus();
return !focusChangeBlocked;
}
-void Document::setCSSTarget(Element* n)
+void Document::setCSSTarget(Element* newTarget)
{
if (m_cssTarget)
m_cssTarget->didAffectSelector(AffectedSelectorTarget);
- m_cssTarget = n;
- if (n)
- n->didAffectSelector(AffectedSelectorTarget);
+ m_cssTarget = newTarget;
+ if (m_cssTarget)
+ m_cssTarget->didAffectSelector(AffectedSelectorTarget);
}
-void Document::registerNodeList(LiveNodeListBase* list)
+void Document::registerNodeList(const LiveNodeListBase* list)
{
- if (list->hasIdNameCache())
- m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
+#if ENABLE(OILPAN)
+ m_nodeLists[list->invalidationType()].add(list);
+#else
m_nodeListCounts[list->invalidationType()]++;
+#endif
if (list->isRootedAtDocument())
m_listsInvalidatedAtDocument.add(list);
}
-void Document::unregisterNodeList(LiveNodeListBase* list)
+void Document::unregisterNodeList(const LiveNodeListBase* list)
{
- if (list->hasIdNameCache())
- m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
+#if ENABLE(OILPAN)
+ ASSERT(m_nodeLists[list->invalidationType()].contains(list));
+ m_nodeLists[list->invalidationType()].remove(list);
+#else
m_nodeListCounts[list->invalidationType()]--;
+#endif
if (list->isRootedAtDocument()) {
ASSERT(m_listsInvalidatedAtDocument.contains(list));
m_listsInvalidatedAtDocument.remove(list);
}
}
+void Document::registerNodeListWithIdNameCache(const LiveNodeListBase* list)
+{
+#if ENABLE(OILPAN)
+ m_nodeLists[InvalidateOnIdNameAttrChange].add(list);
+#else
+ m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
+#endif
+}
+
+void Document::unregisterNodeListWithIdNameCache(const LiveNodeListBase* list)
+{
+#if ENABLE(OILPAN)
+ ASSERT(m_nodeLists[InvalidateOnIdNameAttrChange].contains(list));
+ m_nodeLists[InvalidateOnIdNameAttrChange].remove(list);
+#else
+ ASSERT(m_nodeListCounts[InvalidateOnIdNameAttrChange] > 0);
+ m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
+#endif
+}
+
void Document::attachNodeIterator(NodeIterator* ni)
{
m_nodeIterators.add(ni);
@@ -3468,14 +3747,14 @@ void Document::detachNodeIterator(NodeIterator* ni)
m_nodeIterators.remove(ni);
}
-void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
+void Document::moveNodeIteratorsToNewDocument(Node& node, Document& newDocument)
{
- HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
- HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
- for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> > nodeIteratorsList = m_nodeIterators;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
if ((*it)->root() == node) {
detachNodeIterator(*it);
- newDocument->attachNodeIterator(*it);
+ newDocument.attachNodeIterator(*it);
}
}
}
@@ -3483,29 +3762,40 @@ void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenChanged(container);
}
}
-void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
+void Document::updateRangesAfterNodeMovedToAnotherDocument(const Node& node)
+{
+ ASSERT(node.document() != this);
+ if (m_ranges.isEmpty())
+ return;
+ AttachedRangeSet ranges = m_ranges;
+ AttachedRangeSet::const_iterator end = ranges.end();
+ for (AttachedRangeSet::const_iterator it = ranges.begin(); it != end; ++it)
+ (*it)->updateOwnerDocumentIfNeeded();
+}
+
+void Document::nodeChildrenWillBeRemoved(ContainerNode& container)
{
NoEventDispatchAssertion assertNoEventDispatch;
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenWillBeRemoved(container);
}
- HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
- for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
- for (Node* n = container->firstChild(); n; n = n->nextSibling())
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
+ for (Node* n = container.firstChild(); n; n = n->nextSibling())
(*it)->nodeWillBeRemoved(*n);
}
- if (Frame* frame = this->frame()) {
- for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
+ if (LocalFrame* frame = this->frame()) {
+ for (Node* n = container.firstChild(); n; n = n->nextSibling()) {
frame->eventHandler().nodeWillBeRemoved(*n);
frame->selection().nodeWillBeRemoved(*n);
frame->page()->dragCaretController().nodeWillBeRemoved(*n);
@@ -3515,17 +3805,17 @@ void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
void Document::nodeWillBeRemoved(Node& n)
{
- HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
- for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
(*it)->nodeWillBeRemoved(n);
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
+ AttachedRangeSet::const_iterator rangesEnd = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
(*it)->nodeWillBeRemoved(n);
}
- if (Frame* frame = this->frame()) {
+ if (LocalFrame* frame = this->frame()) {
frame->eventHandler().nodeWillBeRemoved(n);
frame->selection().nodeWillBeRemoved(n);
frame->page()->dragCaretController().nodeWillBeRemoved(n);
@@ -3535,8 +3825,8 @@ void Document::nodeWillBeRemoved(Node& n)
void Document::didInsertText(Node* text, unsigned offset, unsigned length)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didInsertText(text, offset, length);
}
@@ -3547,8 +3837,8 @@ void Document::didInsertText(Node* text, unsigned offset, unsigned length)
void Document::didRemoveText(Node* text, unsigned offset, unsigned length)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didRemoveText(text, offset, length);
}
@@ -3557,49 +3847,49 @@ void Document::didRemoveText(Node* text, unsigned offset, unsigned length)
m_markers->shiftMarkers(text, offset + length, 0 - length);
}
-void Document::didMergeTextNodes(Text* oldNode, unsigned offset)
+void Document::didMergeTextNodes(Text& oldNode, unsigned offset)
{
if (!m_ranges.isEmpty()) {
NodeWithIndex oldNodeWithIndex(oldNode);
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didMergeTextNodes(oldNodeWithIndex, offset);
}
if (m_frame)
- m_frame->selection().didMergeTextNodes(*oldNode, offset);
+ m_frame->selection().didMergeTextNodes(oldNode, offset);
// FIXME: This should update markers for spelling and grammar checking.
}
-void Document::didSplitTextNode(Text* oldNode)
+void Document::didSplitTextNode(Text& oldNode)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didSplitTextNode(oldNode);
}
if (m_frame)
- m_frame->selection().didSplitTextNode(*oldNode);
+ m_frame->selection().didSplitTextNode(oldNode);
// FIXME: This should update markers for spelling and grammar checking.
}
-void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
+void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
{
- DOMWindow* domWindow = this->domWindow();
+ LocalDOMWindow* domWindow = this->domWindow();
if (!domWindow)
return;
- domWindow->setAttributeEventListener(eventType, listener, isolatedWorld);
+ domWindow->setAttributeEventListener(eventType, listener);
}
-EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
+EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
{
- DOMWindow* domWindow = this->domWindow();
+ LocalDOMWindow* domWindow = this->domWindow();
if (!domWindow)
return 0;
- return domWindow->getAttributeEventListener(eventType, isolatedWorld);
+ return domWindow->getAttributeEventListener(eventType);
}
EventQueue* Document::eventQueue() const
@@ -3609,7 +3899,7 @@ EventQueue* Document::eventQueue() const
return m_domWindow->eventQueue();
}
-void Document::enqueueAnimationFrameEvent(PassRefPtr<Event> event)
+void Document::enqueueAnimationFrameEvent(PassRefPtrWillBeRawPtr<Event> event)
{
ensureScriptedAnimationController().enqueueEvent(event);
}
@@ -3617,26 +3907,40 @@ void Document::enqueueAnimationFrameEvent(PassRefPtr<Event> event)
void Document::enqueueScrollEventForNode(Node* target)
{
// Per the W3C CSSOM View Module only scroll events fired at the document should bubble.
- RefPtr<Event> scrollEvent = target->isDocumentNode() ? Event::createBubble(EventTypeNames::scroll) : Event::create(EventTypeNames::scroll);
+ RefPtrWillBeRawPtr<Event> scrollEvent = target->isDocumentNode() ? Event::createBubble(EventTypeNames::scroll) : Event::create(EventTypeNames::scroll);
scrollEvent->setTarget(target);
ensureScriptedAnimationController().enqueuePerFrameEvent(scrollEvent.release());
}
void Document::enqueueResizeEvent()
{
- RefPtr<Event> event = Event::create(EventTypeNames::resize);
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::resize);
event->setTarget(domWindow());
ensureScriptedAnimationController().enqueuePerFrameEvent(event.release());
}
-PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionState& exceptionState)
+Document::EventFactorySet& Document::eventFactories()
{
- RefPtr<Event> event = EventFactory::create(eventType);
- if (event)
- return event.release();
+ DEFINE_STATIC_LOCAL(EventFactorySet, s_eventFactory, ());
+ return s_eventFactory;
+}
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+void Document::registerEventFactory(PassOwnPtr<EventFactoryBase> eventFactory)
+{
+ ASSERT(!eventFactories().contains(eventFactory.get()));
+ eventFactories().add(eventFactory);
+}
+
+PassRefPtrWillBeRawPtr<Event> Document::createEvent(const String& eventType, ExceptionState& exceptionState)
+{
+ RefPtrWillBeRawPtr<Event> event = nullptr;
+ for (EventFactorySet::const_iterator it = eventFactories().begin(); it != eventFactories().end(); ++it) {
+ event = (*it)->create(eventType);
+ if (event)
+ return event.release();
+ }
+ exceptionState.throwDOMException(NotSupportedError, "The provided event type ('" + eventType + "') is invalid.");
+ return nullptr;
}
void Document::addMutationEventListenerTypeIfEnabled(ListenerType listenerType)
@@ -3666,7 +3970,7 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
UseCounter::count(*this, UseCounter::DOMCharacterDataModifiedEvent);
addMutationEventListenerTypeIfEnabled(DOMCHARACTERDATAMODIFIED_LISTENER);
} else if (eventType == EventTypeNames::overflowchanged) {
- UseCounter::count(*this, UseCounter::OverflowChangedEvent);
+ UseCounter::countDeprecation(*this, UseCounter::OverflowChangedEvent);
addListenerType(OVERFLOWCHANGED_LISTENER);
} else if (eventType == EventTypeNames::webkitAnimationStart || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == EventTypeNames::animationstart)) {
addListenerType(ANIMATIONSTART_LISTENER);
@@ -3676,17 +3980,8 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
addListenerType(ANIMATIONITERATION_LISTENER);
} else if (eventType == EventTypeNames::webkitTransitionEnd || eventType == EventTypeNames::transitionend) {
addListenerType(TRANSITIONEND_LISTENER);
- } else if (eventType == EventTypeNames::beforeload) {
- if (m_frame && m_frame->script().shouldBypassMainWorldContentSecurityPolicy()) {
- UseCounter::count(*this, UseCounter::BeforeLoadEventInIsolatedWorld);
- } else {
- UseCounter::count(*this, UseCounter::BeforeLoadEvent);
- }
- addListenerType(BEFORELOAD_LISTENER);
} else if (eventType == EventTypeNames::scroll) {
addListenerType(SCROLL_LISTENER);
- } else if (eventType == EventTypeNames::DOMFocusIn || eventType == EventTypeNames::DOMFocusOut) {
- UseCounter::count(*this, UseCounter::DOMFocusInOutEvent);
}
}
@@ -3699,7 +3994,8 @@ HTMLFrameOwnerElement* Document::ownerElement() const
{
if (!frame())
return 0;
- return frame()->ownerElement();
+ // FIXME: This probably breaks the attempts to layout after a load is finished in implicitClose(), and probably tons of other things...
+ return frame()->deprecatedLocalOwner();
}
String Document::cookie(ExceptionState& exceptionState) const
@@ -3798,7 +4094,7 @@ void Document::setDomain(const String& newDomain, ExceptionState& exceptionState
securityOrigin()->setDomainFromDOM(newDomain);
if (m_frame)
- m_frame->script().updateSecurityOrigin();
+ m_frame->script().updateSecurityOrigin(securityOrigin());
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-lastmodified
@@ -3825,7 +4121,7 @@ String Document::lastModified() const
const KURL& Document::firstPartyForCookies() const
{
- return topDocument()->url();
+ return topDocument().url();
}
static bool isValidNameNonASCII(const LChar* characters, unsigned length)
@@ -3910,7 +4206,7 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
U16_NEXT(characters, i, length, c)
if (c == ':') {
if (sawColon) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "The qualified name provided ('" + qualifiedName + "') contains multiple colons.");
return false; // multiple colons: not allowed
}
nameStart = true;
@@ -3918,13 +4214,25 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
colonPos = i - 1;
} else if (nameStart) {
if (!isValidNameStart(c)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ StringBuilder message;
+ message.appendLiteral("The qualified name provided ('");
+ message.append(qualifiedName);
+ message.appendLiteral("') contains the invalid name-start character '");
+ message.append(c);
+ message.appendLiteral("'.");
+ exceptionState.throwDOMException(InvalidCharacterError, message.toString());
return false;
}
nameStart = false;
} else {
if (!isValidNamePart(c)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ StringBuilder message;
+ message.appendLiteral("The qualified name provided ('");
+ message.append(qualifiedName);
+ message.appendLiteral("') contains the invalid character '");
+ message.append(c);
+ message.appendLiteral("'.");
+ exceptionState.throwDOMException(InvalidCharacterError, message.toString());
return false;
}
}
@@ -3936,7 +4244,7 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
} else {
prefix = AtomicString(characters, colonPos);
if (prefix.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "The qualified name provided ('" + qualifiedName + "') has an empty namespace prefix.");
return false;
}
int prefixStart = colonPos + 1;
@@ -3944,7 +4252,7 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
}
if (localName.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "The qualified name provided ('" + qualifiedName + "') has an empty local name.");
return false;
}
@@ -3956,7 +4264,7 @@ bool Document::parseQualifiedName(const AtomicString& qualifiedName, AtomicStrin
unsigned length = qualifiedName.length();
if (!length) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ exceptionState.throwDOMException(InvalidCharacterError, "The qualified name provided is empty.");
return false;
}
@@ -3974,29 +4282,50 @@ void Document::setEncodingData(const DocumentEncodingData& newData)
// document's title so that the user doesn't see an incorrectly decoded title
// in the title bar.
if (m_titleElement
- && encoding() != newData.encoding
- && !m_titleElement->firstElementChild()
+ && encoding() != newData.encoding()
+ && !ElementTraversal::firstWithin(*m_titleElement)
&& encoding() == Latin1Encoding()
&& m_titleElement->textContent().containsOnlyLatin1()) {
CString originalBytes = m_titleElement->textContent().latin1();
- OwnPtr<TextCodec> codec = newTextCodec(newData.encoding);
- String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
+ OwnPtr<TextCodec> codec = newTextCodec(newData.encoding());
+ String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), DataEOF);
m_titleElement->setTextContent(correctlyDecodedTitle);
}
m_encodingData = newData;
+
+ // FIXME: Should be removed as part of https://code.google.com/p/chromium/issues/detail?id=319643
+ bool shouldUseVisualOrdering = m_encodingData.encoding().usesVisualOrdering();
+ if (shouldUseVisualOrdering != m_visuallyOrdered) {
+ m_visuallyOrdered = shouldUseVisualOrdering;
+ // FIXME: How is possible to not have a renderer here?
+ if (renderView())
+ renderView()->style()->setRTLOrdering(m_visuallyOrdered ? VisualOrder : LogicalOrder);
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+}
+
+KURL Document::completeURL(const String& url) const
+{
+ return completeURLWithOverride(url, m_baseURL);
}
-KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
+KURL Document::completeURLWithOverride(const String& url, const KURL& baseURLOverride) const
{
// Always return a null URL when passed a null string.
// FIXME: Should we change the KURL constructor to have this behavior?
// See also [CSS]StyleSheet::completeURL(const String&)
if (url.isNull())
return KURL();
+ // This logic is deliberately spread over many statements in an attempt to track down http://crbug.com/312410.
const KURL* baseURLFromParent = 0;
- if (baseURLOverride.isEmpty() || baseURLOverride == blankURL()) {
+ bool shouldUseParentBaseURL = baseURLOverride.isEmpty();
+ if (!shouldUseParentBaseURL) {
+ const KURL& aboutBlankURL = blankURL();
+ shouldUseParentBaseURL = (baseURLOverride == aboutBlankURL);
+ }
+ if (shouldUseParentBaseURL) {
if (Document* parent = parentDocument())
baseURLFromParent = &parent->baseURL();
}
@@ -4006,26 +4335,39 @@ KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
return KURL(baseURL, url, encoding());
}
-KURL Document::completeURL(const String& url) const
-{
- return completeURL(url, m_baseURL);
-}
-
// Support for Javascript execCommand, and related methods
static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
if (!frame || frame->document() != document)
return Editor::Command();
- document->updateStyleIfNeeded();
+ document->updateRenderTreeIfNeeded();
return frame->editor().command(commandName, userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
}
bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
{
- return command(this, commandName, userInterface).execute(value);
+ // We don't allow recusrive |execCommand()| to protect against attack code.
+ // Recursive call of |execCommand()| could be happened by moving iframe
+ // with script triggered by insertion, e.g. <iframe src="javascript:...">
+ // <iframe onload="...">. This usage is valid as of the specification
+ // although, it isn't common use case, rather it is used as attack code.
+ static bool inExecCommand = false;
+ if (inExecCommand) {
+ String message = "We don't execute document.execCommand() this time, because it is called recursively.";
+ addConsoleMessage(JSMessageSource, WarningMessageLevel, message);
+ return false;
+ }
+ TemporaryChange<bool> executeScope(inExecCommand, true);
+
+ // Postpone DOM mutation events, which can execute scripts and change
+ // DOM tree against implementation assumption.
+ EventQueueScope eventQueueScope;
+ Editor::Command editorCommand = command(this, commandName, userInterface);
+ blink::Platform::current()->histogramSparse("WebCore.Document.execCommand", editorCommand.idForHistogram());
+ return editorCommand.execute(value);
}
bool Document::queryCommandEnabled(const String& commandName)
@@ -4069,11 +4411,7 @@ KURL Document::openSearchDescriptionURL()
if (!head())
return KURL();
- RefPtr<HTMLCollection> children = head()->children();
- for (unsigned i = 0; Node* child = children->item(i); i++) {
- if (!child->hasTagName(linkTag))
- continue;
- HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+ for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head()); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
continue;
if (linkElement->href().isEmpty())
@@ -4084,7 +4422,7 @@ KURL Document::openSearchDescriptionURL()
return KURL();
}
-void Document::pushCurrentScript(PassRefPtr<HTMLScriptElement> newCurrentScript)
+void Document::pushCurrentScript(PassRefPtrWillBeRawPtr<HTMLScriptElement> newCurrentScript)
{
ASSERT(newCurrentScript);
m_currentScriptStack.append(newCurrentScript);
@@ -4100,7 +4438,7 @@ void Document::applyXSLTransform(ProcessingInstruction* pi)
{
ASSERT(!pi->isLoading());
UseCounter::count(*this, UseCounter::XSLProcessingInstruction);
- RefPtr<XSLTProcessor> processor = XSLTProcessor::create();
+ RefPtrWillBeRawPtr<XSLTProcessor> processor = XSLTProcessor::create();
processor->setXSLStyleSheet(toXSLStyleSheet(pi->sheet()));
String resultMIMEType;
String newSource;
@@ -4108,7 +4446,7 @@ void Document::applyXSLTransform(ProcessingInstruction* pi)
if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
return;
// FIXME: If the transform failed we should probably report an error (like Mozilla does).
- Frame* ownerFrame = frame();
+ LocalFrame* ownerFrame = frame();
processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, ownerFrame);
InspectorInstrumentation::frameDocumentUpdated(ownerFrame);
}
@@ -4121,8 +4459,13 @@ void Document::setTransformSource(PassOwnPtr<TransformSource> source)
void Document::setDesignMode(InheritedBool value)
{
m_designMode = value;
- for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree().traverseNext(m_frame))
- frame->document()->setNeedsStyleRecalc();
+ for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext(m_frame)) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (!toLocalFrame(frame)->document())
+ break;
+ toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
}
Document::InheritedBool Document::getDesignMode() const
@@ -4139,54 +4482,79 @@ bool Document::inDesignMode() const
return false;
}
+String Document::designMode() const
+{
+ return inDesignMode() ? "on" : "off";
+}
+
+void Document::setDesignMode(const String& value)
+{
+ InheritedBool mode;
+ if (equalIgnoringCase(value, "on"))
+ mode = on;
+ else if (equalIgnoringCase(value, "off"))
+ mode = off;
+ else
+ mode = inherit;
+ setDesignMode(mode);
+}
+
Document* Document::parentDocument() const
{
if (!m_frame)
return 0;
Frame* parent = m_frame->tree().parent();
- if (!parent)
+ if (!parent || !parent->isLocalFrame())
return 0;
- return parent->document();
+ return toLocalFrame(parent)->document();
}
-Document* Document::topDocument() const
+Document& Document::topDocument() const
{
+ // FIXME: Not clear what topDocument() should do in the OOPI case--should it return the topmost
+ // available Document, or something else?
Document* doc = const_cast<Document*>(this);
Element* element;
while ((element = doc->ownerElement()))
doc = &element->document();
- return doc;
+ ASSERT(doc);
+ return *doc;
}
-WeakPtr<Document> Document::contextDocument()
+WeakPtrWillBeRawPtr<Document> Document::contextDocument()
{
if (m_contextDocument)
return m_contextDocument;
- if (m_frame)
+ if (m_frame) {
+#if ENABLE(OILPAN)
+ return this;
+#else
return m_weakFactory.createWeakPtr();
- return WeakPtr<Document>(0);
+#endif
+ }
+ return WeakPtrWillBeRawPtr<Document>(nullptr);
}
-PassRefPtr<Attr> Document::createAttribute(const AtomicString& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Document::createAttribute(const AtomicString& name, ExceptionState& exceptionState)
{
return createAttributeNS(nullAtom, name, exceptionState, true);
}
-PassRefPtr<Attr> Document::createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState, bool shouldIgnoreNamespaceChecks)
+PassRefPtrWillBeRawPtr<Attr> Document::createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState, bool shouldIgnoreNamespaceChecks)
{
AtomicString prefix, localName;
if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
+ return nullptr;
QualifiedName qName(prefix, localName, namespaceURI);
if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
+ exceptionState.throwDOMException(NamespaceError, "The namespace URI provided ('" + namespaceURI + "') is not valid for the qualified name provided ('" + qualifiedName + "').");
+ return nullptr;
}
- return Attr::create(*this, qName, emptyString());
+ return Attr::create(*this, qName, emptyAtom);
}
const SVGDocumentExtensions* Document::svgExtensions()
@@ -4194,77 +4562,77 @@ const SVGDocumentExtensions* Document::svgExtensions()
return m_svgExtensions.get();
}
-SVGDocumentExtensions* Document::accessSVGExtensions()
+SVGDocumentExtensions& Document::accessSVGExtensions()
{
if (!m_svgExtensions)
- m_svgExtensions = adoptPtr(new SVGDocumentExtensions(this));
- return m_svgExtensions.get();
+ m_svgExtensions = adoptPtrWillBeNoop(new SVGDocumentExtensions(this));
+ return *m_svgExtensions;
}
bool Document::hasSVGRootNode() const
{
- return documentElement() && documentElement()->hasTagName(SVGNames::svgTag);
+ return isSVGSVGElement(documentElement());
}
-PassRefPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
}
-PassRefPtr<HTMLCollection> Document::images()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::images()
{
return ensureCachedCollection(DocImages);
}
-PassRefPtr<HTMLCollection> Document::applets()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::applets()
{
return ensureCachedCollection(DocApplets);
}
-PassRefPtr<HTMLCollection> Document::embeds()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::embeds()
{
return ensureCachedCollection(DocEmbeds);
}
-PassRefPtr<HTMLCollection> Document::scripts()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::scripts()
{
return ensureCachedCollection(DocScripts);
}
-PassRefPtr<HTMLCollection> Document::links()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::links()
{
return ensureCachedCollection(DocLinks);
}
-PassRefPtr<HTMLCollection> Document::forms()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::forms()
{
return ensureCachedCollection(DocForms);
}
-PassRefPtr<HTMLCollection> Document::anchors()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::anchors()
{
return ensureCachedCollection(DocAnchors);
}
-PassRefPtr<HTMLCollection> Document::allForBinding()
+PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::allForBinding()
{
UseCounter::count(*this, UseCounter::DocumentAll);
return all();
}
-PassRefPtr<HTMLCollection> Document::all()
+PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::all()
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLAllCollection>(this, DocAll);
+ return ensureRareData().ensureNodeLists().addCache<HTMLAllCollection>(*this, DocAll);
}
-PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLNameCollection>(this, WindowNamedItems, name);
+ return ensureRareData().ensureNodeLists().addCache<WindowNameCollection>(*this, WindowNamedItems, name);
}
-PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLNameCollection>(this, DocumentNamedItems, name);
+ return ensureRareData().ensureNodeLists().addCache<DocumentNameCollection>(*this, DocumentNamedItems, name);
}
void Document::finishedParsing()
@@ -4278,12 +4646,26 @@ void Document::finishedParsing()
if (!m_documentTiming.domContentLoadedEventEnd)
m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
+ if (frame() && frame()->isMainFrame()) {
+ // Reset the text autosizing multipliers on main frame when DOM is loaded.
+ // This is to allow for a fresh text autosizing pass when the page layout
+ // changes significantly in the end.
+ if (TextAutosizer* textAutosizer = this->textAutosizer())
+ textAutosizer->recalculateMultipliers();
+ }
+
// The loader's finishedParsing() method may invoke script that causes this object to
// be dereferenced (when this document is in an iframe and the onload causes the iframe's src to change).
// Keep it alive until we are done.
- RefPtr<Document> protect(this);
+ RefPtrWillBeRawPtr<Document> protect(this);
+
+ if (RefPtr<LocalFrame> f = frame()) {
+ // Don't update the render tree if we haven't requested the main resource yet to avoid
+ // adding extra latency. Note that the first render tree update can be expensive since it
+ // triggers the parsing of the default stylesheets which are compiled-in.
+ const bool mainResourceWasAlreadyRequested =
+ m_frame->loader().stateMachine()->committedFirstRealDocumentLoad();
- if (RefPtr<Frame> f = frame()) {
// FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all
// resource loads are complete. HTMLObjectElements can start loading their resources from
// post attach callbacks triggered by recalcStyle(). This means if we parse out an <object>
@@ -4291,30 +4673,32 @@ void Document::finishedParsing()
// started the resource load and might fire the window load event too early. To avoid this
// we force the styles to be up to date before calling FrameLoader::finishedParsing().
// See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment 35.
- updateStyleIfNeeded();
+ if (mainResourceWasAlreadyRequested)
+ updateRenderTreeIfNeeded();
f->loader().finishedParsing();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "MarkDOMContent", "data", InspectorMarkLoadEvent::data(f.get()));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::domContentLoadedEventFired(f.get());
}
- // Schedule dropping of the DocumentSharedObjectPool. We keep it alive for a while after parsing finishes
+ // Schedule dropping of the ElementDataCache. We keep it alive for a while after parsing finishes
// so that dynamically inserted content can also benefit from sharing optimizations.
- // Note that we don't refresh the timer on pool access since that could lead to huge caches being kept
+ // Note that we don't refresh the timer on cache access since that could lead to huge caches being kept
// alive indefinitely by something innocuous like JS setting .innerHTML repeatedly on a timer.
- static const int timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds = 10;
- m_sharedObjectPoolClearTimer.startOneShot(timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds);
+ m_elementDataCacheClearTimer.startOneShot(10, FROM_HERE);
// Parser should have picked up all preloads by now
m_fetcher->clearPreloads();
- if (m_import)
- m_import->didFinishParsing();
+ if (HTMLImportLoader* import = importLoader())
+ import->didFinishParsing();
}
-void Document::sharedObjectPoolClearTimerFired(Timer<Document>*)
+void Document::elementDataCacheClearTimerFired(Timer<Document>*)
{
- m_sharedObjectPool.clear();
+ m_elementDataCache.clear();
}
Vector<IconURL> Document::iconURLs(int iconTypesMask)
@@ -4325,21 +4709,13 @@ Vector<IconURL> Document::iconURLs(int iconTypesMask)
Vector<IconURL> secondaryIcons;
// Start from the last child node so that icons seen later take precedence as required by the spec.
- RefPtr<HTMLCollection> children = head() ? head()->children() : 0;
- unsigned length = children ? children->length() : 0;
- for (unsigned i = 0; i < length; i++) {
- Node* child = children->item(i);
- if (!child->hasTagName(linkTag))
- continue;
- HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+ for (HTMLLinkElement* linkElement = head() ? Traversal<HTMLLinkElement>::firstChild(*head()) : 0; linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
if (!(linkElement->iconType() & iconTypesMask))
continue;
if (linkElement->href().isEmpty())
continue;
-#if !ENABLE(TOUCH_ICON_LOADING)
- if (linkElement->iconType() != Favicon)
+ if (!RuntimeEnabledFeatures::touchIconLoadingEnabled() && linkElement->iconType() != Favicon)
continue;
-#endif
IconURL newURL(linkElement->href(), linkElement->iconSizes(), linkElement->type(), linkElement->iconType());
if (linkElement->iconType() == Favicon) {
@@ -4374,6 +4750,35 @@ Vector<IconURL> Document::iconURLs(int iconTypesMask)
return iconURLs;
}
+Color Document::themeColor() const
+{
+ if (!RuntimeEnabledFeatures::themeColorEnabled())
+ return Color();
+
+ for (HTMLMetaElement* metaElement = head() ? Traversal<HTMLMetaElement>::firstChild(*head()) : 0; metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
+ RGBA32 rgb;
+ if (equalIgnoringCase(metaElement->name(), "theme-color") && BisonCSSParser::parseColor(rgb, metaElement->content().string().stripWhiteSpace(), true))
+ return Color(rgb);
+ }
+ return Color();
+}
+
+HTMLLinkElement* Document::linkManifest() const
+{
+ HTMLHeadElement* head = this->head();
+ if (!head)
+ return 0;
+
+ // The first link element with a manifest rel must be used. Others are ignored.
+ for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
+ if (!linkElement->relAttribute().isManifest())
+ continue;
+ return linkElement;
+ }
+
+ return 0;
+}
+
void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
{
if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
@@ -4390,7 +4795,14 @@ bool Document::useSecureKeyboardEntryWhenActive() const
void Document::initSecurityContext()
{
- initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_import));
+ initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_importsController));
+}
+
+static PassRefPtr<ContentSecurityPolicy> contentSecurityPolicyFor(Document* document)
+{
+ if (document->importsController())
+ return document->importsController()->master()->contentSecurityPolicy();
+ return ContentSecurityPolicy::create(document);
}
void Document::initSecurityContext(const DocumentInit& initializer)
@@ -4414,7 +4826,7 @@ void Document::initSecurityContext(const DocumentInit& initializer)
m_cookieURL = m_url;
enforceSandboxFlags(initializer.sandboxFlags());
setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));
- setContentSecurityPolicy(ContentSecurityPolicy::create(this));
+ setContentSecurityPolicy(contentSecurityPolicyFor(this));
if (Settings* settings = initializer.settings()) {
if (!settings->webSecurityEnabled()) {
@@ -4439,10 +4851,6 @@ void Document::initSecurityContext(const DocumentInit& initializer)
setBaseURLOverride(initializer.parentBaseURL());
}
- // FIXME: What happens if we inherit the security origin? This check may need to be later.
- // <iframe seamless src="about:blank"> likely won't work as-is.
- m_mayDisplaySeamlesslyWithParent = initializer.isSeamlessAllowedFor(this);
-
if (!shouldInheritSecurityOriginFromOwner(m_url))
return;
@@ -4472,8 +4880,8 @@ void Document::initSecurityContext(const DocumentInit& initializer)
void Document::initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders& headers)
{
- if (m_frame && m_frame->tree().parent() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
- contentSecurityPolicy()->copyStateFrom(m_frame->tree().parent()->document()->contentSecurityPolicy());
+ if (m_frame && m_frame->tree().parent() && m_frame->tree().parent()->isLocalFrame() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
+ contentSecurityPolicy()->copyStateFrom(toLocalFrame(m_frame->tree().parent())->document()->contentSecurityPolicy());
contentSecurityPolicy()->didReceiveHeaders(headers);
}
@@ -4486,9 +4894,10 @@ bool Document::allowInlineEventHandlers(Node* node, EventListener* listener, con
// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
// Also, if the listening node came from other document, which happens on context-less event dispatching,
// we also need to ask the owner document of the node.
- if (!m_frame)
+ LocalFrame* frame = executingFrame();
+ if (!frame)
return false;
- if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript))
+ if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
return false;
if (node && node->document() != this && !node->document().allowInlineEventHandlers(node, listener, contextURL, contextLine))
return false;
@@ -4501,11 +4910,12 @@ bool Document::allowExecutingScripts(Node* node)
// FIXME: Eventually we'd like to evaluate scripts which are inserted into a
// viewless document but this'll do for now.
// See http://bugs.webkit.org/show_bug.cgi?id=5727
- if (!frame() && !import())
+ LocalFrame* frame = executingFrame();
+ if (!frame)
return false;
- if (!node->document().frame() && !node->document().import())
+ if (!node->document().executingFrame())
return false;
- if (!contextDocument().get()->frame()->script().canExecuteScripts(AboutToExecuteScript))
+ if (!frame->script().canExecuteScripts(AboutToExecuteScript))
return false;
return true;
}
@@ -4520,7 +4930,7 @@ void Document::didUpdateSecurityOrigin()
{
if (!m_frame)
return;
- m_frame->script().updateSecurityOrigin();
+ m_frame->script().updateSecurityOrigin(securityOrigin());
}
bool Document::isContextThread() const
@@ -4532,7 +4942,7 @@ void Document::updateFocusAppearanceSoon(bool restorePreviousSelection)
{
m_updateFocusAppearanceRestoresSelection = restorePreviousSelection;
if (!m_updateFocusAppearanceTimer.isActive())
- m_updateFocusAppearanceTimer.startOneShot(0);
+ m_updateFocusAppearanceTimer.startOneShot(0, FROM_HERE);
}
void Document::cancelFocusAppearanceUpdate()
@@ -4563,23 +4973,31 @@ void Document::detachRange(Range* range)
m_ranges.remove(range);
}
-CanvasRenderingContext* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
+void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
{
- HTMLCanvasElement* element = getCSSCanvasElement(name);
- if (!element)
- return 0;
- element->setSize(IntSize(width, height));
- return element->getContext(type);
+ HTMLCanvasElement& element = getCSSCanvasElement(name);
+ element.setSize(IntSize(width, height));
+ CanvasRenderingContext* context = element.getContext(type);
+ if (!context)
+ return;
+
+ if (context->is2d()) {
+ is2d = true;
+ context2d = toCanvasRenderingContext2D(context);
+ } else if (context->is3d()) {
+ is3d = true;
+ context3d = toWebGLRenderingContext(context);
+ }
}
-HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
+HTMLCanvasElement& Document::getCSSCanvasElement(const String& name)
{
- RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, 0).iterator->value;
+ RefPtrWillBeMember<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, nullptr).storedValue->value;
if (!element) {
element = HTMLCanvasElement::create(*this);
element->setAccelerationDisabled(true);
}
- return element.get();
+ return *element;
}
void Document::initDNSPrefetch()
@@ -4612,23 +5030,23 @@ void Document::reportBlockedScriptExecutionToInspector(const String& directiveTe
InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
}
-void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* state)
+void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* scriptState)
{
- internalAddMessage(source, level, message, sourceURL, lineNumber, 0, state);
+ internalAddMessage(source, level, message, sourceURL, lineNumber, nullptr, scriptState);
}
-void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state)
+void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState)
{
if (!isContextThread()) {
m_taskRunner->postTask(AddConsoleMessageTask::create(source, level, message));
return;
}
- Page* page = this->page();
- if (!page)
+
+ if (!m_frame)
return;
String messageURL = sourceURL;
- if (!state && sourceURL.isNull() && !lineNumber) {
+ if (!scriptState && sourceURL.isNull() && !lineNumber) {
messageURL = url().string();
if (parsing() && !isInDocumentWrite() && scriptableDocumentParser()) {
ScriptableDocumentParser* parser = scriptableDocumentParser();
@@ -4636,7 +5054,7 @@ void Document::internalAddMessage(MessageSource source, MessageLevel level, cons
lineNumber = parser->lineNumber().oneBasedInt();
}
}
- page->console().addMessage(source, level, message, messageURL, lineNumber, 0, callStack, state, 0);
+ m_frame->console().addMessage(source, level, message, messageURL, lineNumber, 0, callStack, scriptState, 0);
}
void Document::addConsoleMessageWithRequestIdentifier(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier)
@@ -4646,11 +5064,11 @@ void Document::addConsoleMessageWithRequestIdentifier(MessageSource source, Mess
return;
}
- if (Page* page = this->page())
- page->console().addMessage(source, level, message, String(), 0, 0, 0, 0, requestIdentifier);
+ if (m_frame)
+ m_frame->console().addMessage(source, level, message, String(), 0, 0, nullptr, 0, requestIdentifier);
}
-// FIXME(crbug.com/305497): This should be removed after ExecutionContext-DOMWindow migration.
+// FIXME(crbug.com/305497): This should be removed after ExecutionContext-LocalDOMWindow migration.
void Document::postTask(PassOwnPtr<ExecutionContextTask> task)
{
m_taskRunner->postTask(task);
@@ -4674,10 +5092,12 @@ void Document::tasksWereResumed()
m_parser->resumeScheduledTasks();
if (m_scriptedAnimationController)
m_scriptedAnimationController->resume();
+
+ MutationObserver::resumeSuspendedObservers();
}
// FIXME: suspendScheduledTasks(), resumeScheduledTasks(), tasksNeedSuspension()
-// should be moved to DOMWindow once it inherits ExecutionContext
+// should be moved to LocalDOMWindow once it inherits ExecutionContext
void Document::suspendScheduledTasks()
{
ExecutionContext::suspendScheduledTasks();
@@ -4729,7 +5149,7 @@ HTMLDialogElement* Document::activeModalDialog() const
return toHTMLDialogElement(m_topLayerElements.last().get());
}
-void Document::webkitExitPointerLock()
+void Document::exitPointerLock()
{
if (!page())
return;
@@ -4740,7 +5160,7 @@ void Document::webkitExitPointerLock()
page()->pointerLockController().requestPointerUnlock();
}
-Element* Document::webkitPointerLockElement() const
+Element* Document::pointerLockElement() const
{
if (!page() || page()->pointerLockController().lockPending())
return 0;
@@ -4756,16 +5176,51 @@ void Document::decrementLoadEventDelayCount()
ASSERT(m_loadEventDelayCount);
--m_loadEventDelayCount;
- if (frame() && !m_loadEventDelayCount && !m_loadEventDelayTimer.isActive())
- m_loadEventDelayTimer.startOneShot(0);
+ if (!m_loadEventDelayCount)
+ checkLoadEventSoon();
+}
+
+void Document::checkLoadEventSoon()
+{
+ if (frame() && !m_loadEventDelayTimer.isActive())
+ m_loadEventDelayTimer.startOneShot(0, FROM_HERE);
+}
+
+bool Document::isDelayingLoadEvent()
+{
+#if ENABLE(OILPAN)
+ // Always delay load events until after garbage collection.
+ // This way we don't have to explicitly delay load events via
+ // incrementLoadEventDelayCount and decrementLoadEventDelayCount in
+ // Node destructors.
+ if (ThreadState::current()->isSweepInProgress()) {
+ if (!m_loadEventDelayCount)
+ checkLoadEventSoon();
+ return true;
+ }
+#endif
+ return m_loadEventDelayCount;
}
+
void Document::loadEventDelayTimerFired(Timer<Document>*)
{
if (frame())
frame()->loader().checkCompleted();
}
+void Document::loadPluginsSoon()
+{
+ // FIXME: Remove this timer once we don't need to compute layout to load plugins.
+ if (!m_pluginLoadingTimer.isActive())
+ m_pluginLoadingTimer.startOneShot(0, FROM_HERE);
+}
+
+void Document::pluginLoadingTimerFired(Timer<Document>*)
+{
+ updateLayout();
+}
+
ScriptedAnimationController& Document::ensureScriptedAnimationController()
{
if (!m_scriptedAnimationController) {
@@ -4796,96 +5251,112 @@ void Document::serviceScriptedAnimations(double monotonicAnimationStartTime)
m_scriptedAnimationController->serviceScriptedAnimations(monotonicAnimationStartTime);
}
-PassRefPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const
-{
+PassRefPtrWillBeRawPtr<Touch> Document::createTouch(LocalDOMWindow* window, EventTarget* target, int identifier, double pageX, double pageY, double screenX, double screenY, double radiusX, double radiusY, float rotationAngle, float force) const
+{
+ // Match behavior from when these types were integers, and avoid surprises from someone explicitly
+ // passing Infinity/NaN.
+ if (!std::isfinite(pageX))
+ pageX = 0;
+ if (!std::isfinite(pageY))
+ pageY = 0;
+ if (!std::isfinite(screenX))
+ screenX = 0;
+ if (!std::isfinite(screenY))
+ screenY = 0;
+ if (!std::isfinite(radiusX))
+ radiusX = 0;
+ if (!std::isfinite(radiusY))
+ radiusY = 0;
+ if (!std::isfinite(rotationAngle))
+ rotationAngle = 0;
+ if (!std::isfinite(force))
+ force = 0;
+
// FIXME: It's not clear from the documentation at
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html
// when this method should throw and nor is it by inspection of iOS behavior. It would be nice to verify any cases where it throws under iOS
// and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819
- Frame* frame = window ? window->frame() : this->frame();
- return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force);
+ LocalFrame* frame = window ? window->frame() : this->frame();
+ return Touch::create(frame, target, identifier, FloatPoint(screenX, screenY), FloatPoint(pageX, pageY), FloatSize(radiusX, radiusY), rotationAngle, force);
}
-PassRefPtr<TouchList> Document::createTouchList(Vector<RefPtr<Touch> >& touches) const
+PassRefPtrWillBeRawPtr<TouchList> Document::createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches) const
{
return TouchList::create(touches);
}
void Document::didAddTouchEventHandler(Node* handler)
{
+ // The node should either be in this document, or be the Document node of a child
+ // of this document.
+ ASSERT(&handler->document() == this
+ || (handler->isDocumentNode() && toDocument(handler)->parentDocument() == this));
if (!m_touchEventTargets.get())
m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
- m_touchEventTargets->add(handler);
- if (Document* parent = parentDocument()) {
- parent->didAddTouchEventHandler(this);
+ bool isFirstHandler = m_touchEventTargets->isEmpty();
+
+ if (!m_touchEventTargets->add(handler).isNewEntry) {
+ // Just incremented refcount, no real change.
+ // If this is a child document node, then the count should never go above 1.
+ ASSERT(!handler->isDocumentNode() || &handler->document() == this);
return;
}
- if (Page* page = this->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(this);
- if (m_touchEventTargets->size() == 1)
- page->chrome().client().needTouchEvents(true);
+
+ if (isFirstHandler) {
+ if (Document* parent = parentDocument()) {
+ parent->didAddTouchEventHandler(this);
+ } else {
+ // This is the first touch handler on the whole page.
+ if (FrameHost* frameHost = this->frameHost())
+ frameHost->chrome().client().needTouchEvents(true);
+ }
+ }
+
+ // When we're all done with all frames, ensure touch hit rects are marked as dirty.
+ if (!handler->isDocumentNode() || handler == this) {
+ if (Page* page = this->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->touchEventTargetRectsDidChange();
+ }
}
}
-void Document::didRemoveTouchEventHandler(Node* handler)
+void Document::didRemoveTouchEventHandler(Node* handler, bool clearAll)
{
+ // Note that we can't assert that |handler| is in this document because it might be in
+ // the process of moving out of it.
+ ASSERT(clearAll || m_touchEventTargets->contains(handler));
if (!m_touchEventTargets.get())
return;
- ASSERT(m_touchEventTargets->contains(handler));
- m_touchEventTargets->remove(handler);
- if (Document* parent = parentDocument()) {
- parent->didRemoveTouchEventHandler(this);
- return;
- }
- Page* page = this->page();
- if (!page)
- return;
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(this);
- if (m_touchEventTargets->size())
- return;
- for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document() && frame->document()->hasTouchEventHandlers())
+ if (clearAll) {
+ if (!m_touchEventTargets->contains(handler))
+ return;
+ m_touchEventTargets->removeAll(handler);
+ } else {
+ if (!m_touchEventTargets->remove(handler))
+ // Just decremented refcount, no real update.
return;
}
- page->chrome().client().needTouchEvents(false);
-}
-void Document::didRemoveEventTargetNode(Node* handler)
-{
- if (m_touchEventTargets && !m_touchEventTargets->isEmpty()) {
- if (handler == this)
- m_touchEventTargets->clear();
- else
- m_touchEventTargets->removeAll(handler);
- if (m_touchEventTargets->isEmpty() && parentDocument())
- parentDocument()->didRemoveEventTargetNode(this);
+ if (m_touchEventTargets->isEmpty()) {
+ if (Document* parent = parentDocument()) {
+ // This was the last handler in this document, update the parent document too.
+ parent->didRemoveTouchEventHandler(this, clearAll);
+ } else {
+ // We just removed the last touch handler on the whole page.
+ if (FrameHost* frameHost = this->frameHost())
+ frameHost->chrome().client().needTouchEvents(false);
+ }
}
-}
-
-void Document::resetLastHandledUserGestureTimestamp()
-{
- m_lastHandledUserGestureTimestamp = currentTime();
-}
-
-HTMLIFrameElement* Document::seamlessParentIFrame() const
-{
- if (!shouldDisplaySeamlesslyWithParent())
- return 0;
-
- return toHTMLIFrameElement(this->ownerElement());
-}
-bool Document::shouldDisplaySeamlesslyWithParent() const
-{
- if (!RuntimeEnabledFeatures::seamlessIFramesEnabled())
- return false;
- HTMLFrameOwnerElement* ownerElement = this->ownerElement();
- if (!ownerElement)
- return false;
- return m_mayDisplaySeamlesslyWithParent && ownerElement->hasTagName(iframeTag) && ownerElement->fastHasAttribute(seamlessAttr);
+ // When we're all done with all frames, ensure touch hit rects are marked as dirty.
+ if (!handler->isDocumentNode() || handler == this) {
+ if (Page* page = this->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->touchEventTargetRectsDidChange();
+ }
+ }
}
DocumentLoader* Document::loader() const
@@ -4907,7 +5378,7 @@ IntSize Document::initialViewportSize() const
{
if (!view())
return IntSize();
- return view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+ return view()->unscaledVisibleContentSize(IncludeScrollbars);
}
Node* eventTargetNodeForDocument(Document* doc)
@@ -4933,7 +5404,7 @@ void Document::adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>& quads
LayoutRect visibleContentRect = view()->visibleContentRect();
for (size_t i = 0; i < quads.size(); ++i) {
- quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
+ quads[i].move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y().toFloat()));
adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
}
}
@@ -4944,7 +5415,7 @@ void Document::adjustFloatRectForScrollAndAbsoluteZoom(FloatRect& rect, RenderOb
return;
LayoutRect visibleContentRect = view()->visibleContentRect();
- rect.move(-visibleContentRect.x(), -visibleContentRect.y());
+ rect.move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y().toFloat()));
adjustFloatRectForAbsoluteZoom(rect, renderer);
}
@@ -4961,13 +5432,12 @@ void Document::decrementActiveParserCount()
// FIXME: This should always be enabled, but it seems to cause
// http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
// see http://webkit.org/b/110554 and http://webkit.org/b/110401
- loader()->checkLoadComplete();
frame()->loader().checkLoadComplete();
}
-void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
+void Document::setContextFeatures(ContextFeatures& features)
{
- m_contextFeatures = features;
+ m_contextFeatures = PassRefPtrWillBeRawPtr<ContextFeatures>(features);
}
static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject* obj2)
@@ -4998,7 +5468,7 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
innerElementInDocument = innerElementInDocument->document().ownerElement();
}
- Element* oldActiveElement = activeElement();
+ Element* oldActiveElement = activeHoverElement();
if (oldActiveElement && !request.active()) {
// We are clearing the :active chain because the mouse has been released.
for (RenderObject* curr = oldActiveElement->renderer(); curr; curr = curr->parent()) {
@@ -5008,10 +5478,10 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
m_userActionElements.setInActiveChain(curr->node(), false);
}
}
- setActiveElement(0);
+ setActiveHoverElement(nullptr);
} else {
Element* newActiveElement = innerElementInDocument;
- if (!oldActiveElement && newActiveElement && request.active() && !request.touchMove()) {
+ if (!oldActiveElement && newActiveElement && !newActiveElement->isDisabledFormControl() && request.active() && !request.touchMove()) {
// We are setting the :active chain and freezing it. If future moves happen, they
// will need to reference this chain.
for (RenderObject* curr = newActiveElement->renderer(); curr; curr = curr->parent()) {
@@ -5019,19 +5489,19 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
m_userActionElements.setInActiveChain(curr->node(), true);
}
- setActiveElement(newActiveElement);
+ setActiveHoverElement(newActiveElement);
}
}
// If the mouse has just been pressed, set :active on the chain. Those (and only those)
// nodes should remain :active until the mouse is released.
- bool allowActiveChanges = !oldActiveElement && activeElement();
+ bool allowActiveChanges = !oldActiveElement && activeHoverElement();
// If the mouse is down and if this is a mouse move event, we want to restrict changes in
// :hover/:active to only apply to elements that are in the :active chain that we froze
// at the time the mouse went down.
bool mustBeInActiveChain = request.active() && request.move();
- RefPtr<Node> oldHoverNode = hoverNode();
+ RefPtrWillBeRawPtr<Node> oldHoverNode = hoverNode();
// Check to see if the hovered node has changed.
// If it hasn't, we do not need to do anything.
@@ -5048,10 +5518,10 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
// Locate the common ancestor render object for the two renderers.
RenderObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj);
- RefPtr<Node> ancestorNode(ancestor ? ancestor->node() : 0);
+ RefPtrWillBeRawPtr<Node> ancestorNode(ancestor ? ancestor->node() : 0);
- Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
- Vector<RefPtr<Node>, 32> nodesToAddToChain;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 32> nodesToRemoveFromChain;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 32> nodesToAddToChain;
if (oldHoverObj != newHoverObj) {
// If the old hovered node is not nil but it's renderer is, it was probably detached as part of the :hover style
@@ -5125,8 +5595,6 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
nodesToAddToChain[i]->dispatchMouseEvent(*event, EventTypeNames::mouseenter, 0, oldHoverNode.get());
}
}
-
- updateStyleIfNeeded();
}
bool Document::haveStylesheetsLoaded() const
@@ -5141,23 +5609,26 @@ Locale& Document::getCachedLocale(const AtomicString& locale)
return Locale::defaultLocale();
LocaleIdentifierToLocaleMap::AddResult result = m_localeCache.add(localeKey, nullptr);
if (result.isNewEntry)
- result.iterator->value = Locale::create(localeKey);
- return *(result.iterator->value);
+ result.storedValue->value = Locale::create(localeKey);
+ return *(result.storedValue->value);
}
Document& Document::ensureTemplateDocument()
{
- if (const Document* document = templateDocument())
- return *const_cast<Document*>(document);
+ if (isTemplateDocument())
+ return *this;
+
+ if (m_templateDocument)
+ return *m_templateDocument;
if (isHTMLDocument()) {
- DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL());
+ DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL()).withNewRegistrationContext();
m_templateDocument = HTMLDocument::create(init);
} else {
m_templateDocument = Document::create(DocumentInit(blankURL()));
}
- m_templateDocument->setTemplateDocumentHost(this); // balanced in dtor.
+ m_templateDocument->m_templateDocumentHost = this; // balanced in dtor.
return *m_templateDocument.get();
}
@@ -5168,7 +5639,7 @@ void Document::didAssociateFormControl(Element* element)
return;
m_associatedFormControls.add(element);
if (!m_didAssociateFormControlsTimer.isActive())
- m_didAssociateFormControlsTimer.startOneShot(0);
+ m_didAssociateFormControlsTimer.startOneShot(0, FROM_HERE);
}
void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
@@ -5177,7 +5648,7 @@ void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
if (!frame() || !frame()->page())
return;
- Vector<RefPtr<Element> > associatedFormControls;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > associatedFormControls;
copyToVector(m_associatedFormControls, associatedFormControls);
frame()->page()->chrome().client().didAssociateFormControls(associatedFormControls);
@@ -5199,24 +5670,24 @@ DocumentLifecycleNotifier& Document::lifecycleNotifier()
return static_cast<DocumentLifecycleNotifier&>(LifecycleContext<Document>::lifecycleNotifier());
}
-void Document::removedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, StyleResolverUpdateMode updateMode)
+void Document::removedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
{
// If we're in document teardown, then we don't need this notification of our sheet's removal.
// styleResolverChanged() is needed even when the document is inactive so that
// imported docuements (which is inactive) notifies the change to the master document.
if (isActive())
styleEngine()->modifiedStyleSheet(sheet);
- styleResolverChanged(when, updateMode);
+ styleResolverChanged(updateMode);
}
-void Document::modifiedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, StyleResolverUpdateMode updateMode)
+void Document::modifiedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
{
// If we're in document teardown, then we don't need this notification of our sheet's removal.
// styleResolverChanged() is needed even when the document is inactive so that
// imported docuements (which is inactive) notifies the change to the master document.
if (isActive())
styleEngine()->modifiedStyleSheet(sheet);
- styleResolverChanged(when, updateMode);
+ styleResolverChanged(updateMode);
}
TextAutosizer* Document::textAutosizer()
@@ -5233,4 +5704,170 @@ FastTextAutosizer* Document::fastTextAutosizer()
return m_fastTextAutosizer.get();
}
+void Document::setAutofocusElement(Element* element)
+{
+ if (!element) {
+ m_autofocusElement = nullptr;
+ return;
+ }
+ if (m_hasAutofocused)
+ return;
+ m_hasAutofocused = true;
+ ASSERT(!m_autofocusElement);
+ m_autofocusElement = element;
+ m_taskRunner->postTask(AutofocusTask::create());
+}
+
+Element* Document::activeElement() const
+{
+ if (Element* element = treeScope().adjustedFocusedElement())
+ return element;
+ return body();
+}
+
+bool Document::hasFocus() const
+{
+ Page* page = this->page();
+ if (!page)
+ return false;
+ if (!page->focusController().isActive() || !page->focusController().isFocused())
+ return false;
+ Frame* focusedFrame = page->focusController().focusedFrame();
+ if (focusedFrame && focusedFrame->isLocalFrame()) {
+ if (toLocalFrame(focusedFrame)->tree().isDescendantOf(frame()))
+ return true;
+ }
+ return false;
+}
+
+#if ENABLE(OILPAN)
+template<unsigned type>
+bool shouldInvalidateNodeListCachesForAttr(const HeapHashSet<WeakMember<const LiveNodeListBase> > nodeLists[], const QualifiedName& attrName)
+{
+ if (!nodeLists[type].isEmpty() && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
+ return true;
+ return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeLists, attrName);
+}
+
+template<>
+bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const HeapHashSet<WeakMember<const LiveNodeListBase> >[], const QualifiedName&)
+{
+ return false;
+}
+#else
+template<unsigned type>
+bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
+{
+ if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
+ return true;
+ return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
+}
+
+template<>
+bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
+{
+ return false;
+}
+#endif
+
+bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
+{
+ if (attrName) {
+#if ENABLE(OILPAN)
+ return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeLists, *attrName);
+#else
+ return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
+#endif
+ }
+
+ for (int type = 0; type < numNodeListInvalidationTypes; ++type) {
+#if ENABLE(OILPAN)
+ if (!m_nodeLists[type].isEmpty())
+#else
+ if (m_nodeListCounts[type])
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+void Document::invalidateNodeListCaches(const QualifiedName* attrName)
+{
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<const LiveNodeListBase> >::const_iterator end = m_listsInvalidatedAtDocument.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<const LiveNodeListBase> >::const_iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
+ (*it)->invalidateCacheForAttribute(attrName);
+}
+
+void Document::clearWeakMembers(Visitor* visitor)
+{
+ if (m_axObjectCache)
+ m_axObjectCache->clearWeakMembers(visitor);
+
+ // FIXME: Oilpan: Use a weak counted set instead.
+ if (m_touchEventTargets) {
+ Vector<Node*> deadNodes;
+ for (TouchEventTargetSet::iterator it = m_touchEventTargets->begin(); it != m_touchEventTargets->end(); ++it) {
+ if (!visitor->isAlive(it->key))
+ deadNodes.append(it->key);
+ }
+ for (unsigned i = 0; i < deadNodes.size(); ++i)
+ didClearTouchEventHandlers(deadNodes[i]);
+ }
+}
+
+void Document::trace(Visitor* visitor)
+{
+ visitor->trace(m_importsController);
+ visitor->trace(m_docType);
+ visitor->trace(m_implementation);
+ visitor->trace(m_autofocusElement);
+ visitor->trace(m_focusedElement);
+ visitor->trace(m_hoverNode);
+ visitor->trace(m_activeHoverElement);
+ visitor->trace(m_documentElement);
+ visitor->trace(m_titleElement);
+ visitor->trace(m_markers);
+ visitor->trace(m_cssTarget);
+ visitor->trace(m_currentScriptStack);
+ visitor->trace(m_scriptRunner);
+ visitor->trace(m_transformSourceDocument);
+ visitor->trace(m_listsInvalidatedAtDocument);
+#if ENABLE(OILPAN)
+ for (int i = 0; i < numNodeListInvalidationTypes; ++i)
+ visitor->trace(m_nodeLists[i]);
+#endif
+ visitor->trace(m_cssCanvasElements);
+ visitor->trace(m_topLayerElements);
+ visitor->trace(m_elemSheet);
+ visitor->trace(m_nodeIterators);
+ visitor->trace(m_ranges);
+ visitor->trace(m_styleEngine);
+ visitor->trace(m_formController);
+ visitor->trace(m_domWindow);
+ visitor->trace(m_fetcher);
+ visitor->trace(m_parser);
+ visitor->trace(m_contextFeatures);
+ visitor->trace(m_styleSheetList);
+ visitor->trace(m_mediaQueryMatcher);
+ visitor->trace(m_scriptedAnimationController);
+ visitor->trace(m_registrationContext);
+ visitor->trace(m_associatedFormControls);
+ visitor->trace(m_useElementsNeedingUpdate);
+ visitor->trace(m_layerUpdateSVGFilterElements);
+ visitor->trace(m_templateDocument);
+ visitor->trace(m_templateDocumentHost);
+ visitor->trace(m_visibilityObservers);
+ visitor->trace(m_userActionElements);
+ visitor->trace(m_svgExtensions);
+ visitor->trace(m_timeline);
+ visitor->trace(m_compositorPendingAnimations);
+ visitor->trace(m_contextDocument);
+ visitor->registerWeakMembers<Document, &Document::clearWeakMembers>(this);
+ DocumentSupplementable::trace(visitor);
+ TreeScope::trace(visitor);
+ ContainerNode::trace(visitor);
+ ExecutionContext::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.h b/chromium/third_party/WebKit/Source/core/dom/Document.h
index cc23012b679..a8f6f8050f5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Document.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Document.h
@@ -28,10 +28,11 @@
#ifndef Document_h
#define Document_h
+#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptValue.h"
-#include "core/animation/css/CSSPendingAnimations.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/CompositorPendingAnimations.h"
#include "core/dom/ContainerNode.h"
-#include "core/dom/DOMTimeStamp.h"
#include "core/dom/DocumentEncodingData.h"
#include "core/dom/DocumentInit.h"
#include "core/dom/DocumentLifecycle.h"
@@ -47,10 +48,13 @@
#include "core/dom/ViewportDescription.h"
#include "core/dom/custom/CustomElement.h"
#include "core/html/CollectionType.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "core/page/PageVisibilityState.h"
#include "core/rendering/HitTestRequest.h"
+#include "platform/Length.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
+#include "platform/weborigin/KURL.h"
#include "platform/weborigin/ReferrerPolicy.h"
#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
@@ -61,14 +65,13 @@
namespace WebCore {
class AXObjectCache;
-class AnimationClock;
class Attr;
class CDATASection;
class CSSFontSelector;
class CSSStyleDeclaration;
class CSSStyleSheet;
class CSSStyleSheetResource;
-class CanvasRenderingContext;
+class CanvasRenderingContext2D;
class CharacterData;
class Chrome;
class Comment;
@@ -76,11 +79,8 @@ class ContentSecurityPolicyResponseHeaders;
class ContextFeatures;
class CustomElementRegistrationContext;
class DOMImplementation;
-class DOMNamedFlowCollection;
-class DOMSecurityPolicy;
class DOMSelection;
-class DOMWindow;
-class DOMWrapperWorld;
+class LocalDOMWindow;
class Database;
class DatabaseThread;
class DocumentFragment;
@@ -89,19 +89,22 @@ class DocumentLifecycleObserver;
class DocumentLoader;
class DocumentMarkerController;
class DocumentParser;
-class DocumentSharedObjectPool;
-class DocumentTimeline;
+class DocumentState;
+class AnimationTimeline;
class DocumentType;
class Element;
+class ElementDataCache;
class Event;
+class EventFactoryBase;
class EventListener;
class ExceptionState;
-class MainThreadTaskRunner;
class FastTextAutosizer;
class FloatQuad;
class FloatRect;
+class FontFaceSet;
class FormController;
class Frame;
+class FrameHost;
class FrameView;
class HTMLAllCollection;
class HTMLCanvasElement;
@@ -113,6 +116,9 @@ class HTMLFrameOwnerElement;
class HTMLHeadElement;
class HTMLIFrameElement;
class HTMLImport;
+class HTMLImportLoader;
+class HTMLImportsController;
+class HTMLLinkElement;
class HTMLMapElement;
class HTMLNameCollection;
class HTMLScriptElement;
@@ -124,11 +130,12 @@ class LayoutPoint;
class LayoutRect;
class LiveNodeListBase;
class Locale;
+class LocalFrame;
class Location;
+class MainThreadTaskRunner;
class MediaQueryList;
class MediaQueryMatcher;
class MouseEventWithHitTestResults;
-class NamedFlowCollection;
class NodeFilter;
class NodeIterator;
class Page;
@@ -140,6 +147,7 @@ class RenderView;
class RequestAnimationFrameCallback;
class ResourceFetcher;
class SVGDocumentExtensions;
+class SVGUseElement;
class ScriptElementData;
class ScriptResource;
class ScriptRunner;
@@ -162,19 +170,13 @@ class TouchList;
class TransformSource;
class TreeWalker;
class VisitedLinkState;
+class WebGLRenderingContext;
class XMLHttpRequest;
struct AnnotatedRegionValue;
-class FontFaceSet;
-
typedef int ExceptionCode;
-enum RecalcStyleTime {
- RecalcStyleImmediately, // synchronous
- RecalcStyleDeferred // asynchronous
-};
-
enum StyleResolverUpdateMode {
// Discards the StyleResolver and rebuilds it.
FullStyleUpdate,
@@ -190,7 +192,6 @@ enum NodeListInvalidationType {
InvalidateOnForAttrChange,
InvalidateForFormControls,
InvalidateOnHRefAttrChange,
- InvalidateOnItemAttrChange,
InvalidateOnAnyAttrChange,
};
const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1;
@@ -205,20 +206,42 @@ enum DocumentClass {
PluginDocumentClass = 1 << 3,
MediaDocumentClass = 1 << 4,
SVGDocumentClass = 1 << 5,
+ XMLDocumentClass = 1 << 6,
};
typedef unsigned char DocumentClassFlags;
+class Document;
+
+class DocumentVisibilityObserver : public WillBeGarbageCollectedMixin {
+public:
+ DocumentVisibilityObserver(Document&);
+ virtual ~DocumentVisibilityObserver();
+
+ virtual void didChangeVisibilityState(PageVisibilityState) = 0;
+
+ // Classes that inherit Node and DocumentVisibilityObserver must have a
+ // virtual override of Node::didMoveToNewDocument that calls
+ // DocumentVisibilityObserver::setDocument
+ void setObservedDocument(Document&);
+
+protected:
+ void trace(Visitor*);
+
+private:
+ void registerObserver(Document&);
+ void unregisterObserver();
+
+ RawPtrWillBeMember<Document> m_document;
+};
+
class Document : public ContainerNode, public TreeScope, public SecurityContext, public ExecutionContext, public ExecutionContextClient
, public DocumentSupplementable, public LifecycleContext<Document> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Document);
public:
- static PassRefPtr<Document> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<Document> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new Document(initializer));
- }
- static PassRefPtr<Document> createXHTML(const DocumentInit& initializer = DocumentInit())
- {
- return adoptRef(new Document(initializer, XHTMLDocumentClass));
+ return adoptRefWillBeNoop(new Document(initializer));
}
virtual ~Document();
@@ -226,16 +249,23 @@ public:
void mediaQueryAffectingValueChanged();
+#if !ENABLE(OILPAN)
using ContainerNode::ref;
using ContainerNode::deref;
+#endif
using SecurityContext::securityOrigin;
using SecurityContext::contentSecurityPolicy;
using ExecutionContextClient::addConsoleMessage;
+ using TreeScope::getElementById;
- virtual bool canContainRangeEndPoint() const { return true; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
SelectorQueryCache& selectorQueryCache();
+ // Focus Management.
+ Element* activeElement() const;
+ bool hasFocus() const;
+
// DOM methods & attributes for Document
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
@@ -244,6 +274,8 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror);
DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
@@ -263,66 +295,51 @@ public:
bool shouldOverrideLegacyDescription(ViewportDescription::Type);
void setViewportDescription(const ViewportDescription&);
const ViewportDescription& viewportDescription() const { return m_viewportDescription; }
+ Length viewportDefaultMinWidth() const { return m_viewportDefaultMinWidth; }
+
#ifndef NDEBUG
bool didDispatchViewportPropertiesChanged() const { return m_didDispatchViewportPropertiesChanged; }
#endif
bool hasLegacyViewportTag() const { return m_legacyViewportDescription.isLegacyViewportType(); }
- void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_referrerPolicy = referrerPolicy; }
+ void setReferrerPolicy(ReferrerPolicy);
ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
String outgoingReferrer();
String outgoingOrigin() const;
- void setDoctype(PassRefPtr<DocumentType>);
+ void setDoctype(PassRefPtrWillBeRawPtr<DocumentType>);
DocumentType* doctype() const { return m_docType.get(); }
- DOMImplementation* implementation();
+ DOMImplementation& implementation();
Element* documentElement() const
{
return m_documentElement.get();
}
- bool hasManifest() const;
+ // Returns whether the Document has an AppCache manifest.
+ bool hasAppCacheManifest() const;
Location* location() const;
- PassRefPtr<Element> createElement(const AtomicString& name, ExceptionState&);
- PassRefPtr<DocumentFragment> createDocumentFragment();
- PassRefPtr<Text> createTextNode(const String& data);
- PassRefPtr<Comment> createComment(const String& data);
- PassRefPtr<CDATASection> createCDATASection(const String& data, ExceptionState&);
- PassRefPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionState&);
- PassRefPtr<Attr> createAttribute(const AtomicString& name, ExceptionState&);
- PassRefPtr<Attr> createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&, bool shouldIgnoreNamespaceChecks = false);
- PassRefPtr<Node> importNode(Node* importedNode, ExceptionState& ec) { return importNode(importedNode, true, ec); }
- PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionState&);
- PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&);
- PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
-
- PassRefPtr<DOMNamedFlowCollection> webkitGetNamedFlows();
-
- NamedFlowCollection* namedFlows();
+ PassRefPtrWillBeRawPtr<Element> createElement(const AtomicString& name, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> createDocumentFragment();
+ PassRefPtrWillBeRawPtr<Text> createTextNode(const String& data);
+ PassRefPtrWillBeRawPtr<Comment> createComment(const String& data);
+ PassRefPtrWillBeRawPtr<CDATASection> createCDATASection(const String& data, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> createAttribute(const AtomicString& name, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&, bool shouldIgnoreNamespaceChecks = false);
+ PassRefPtrWillBeRawPtr<Node> importNode(Node* importedNode, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> importNode(Node* importedNode, bool deep, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElement(const QualifiedName&, bool createdByParser);
bool regionBasedColumnsEnabled() const;
- /**
- * Retrieve all nodes that intersect a rect in the window's document, until it is fully enclosed by
- * the boundaries of a node.
- *
- * @param centerX x reference for the rectangle in CSS pixels
- * @param centerY y reference for the rectangle in CSS pixels
- * @param topPadding How much to expand the top of the rectangle
- * @param rightPadding How much to expand the right of the rectangle
- * @param bottomPadding How much to expand the bottom of the rectangle
- * @param leftPadding How much to expand the left of the rectangle
- */
- PassRefPtr<NodeList> nodesFromRect(int centerX, int centerY,
- unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding,
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent) const;
Element* elementFromPoint(int x, int y) const;
- PassRefPtr<Range> caretRangeFromPoint(int x, int y);
+ PassRefPtrWillBeRawPtr<Range> caretRangeFromPoint(int x, int y);
String readyState() const;
@@ -339,6 +356,8 @@ public:
void setContent(const String&);
String suggestedMIMEType() const;
+ void setMimeType(const AtomicString&);
+ AtomicString contentType() const; // DOM 4 document.contentType
const AtomicString& contentLanguage() const { return m_contentLanguage; }
void setContentLanguage(const AtomicString&);
@@ -355,33 +374,30 @@ public:
void setXMLStandalone(bool, ExceptionState&);
void setHasXMLDeclaration(bool hasXMLDeclaration) { m_hasXMLDeclaration = hasXMLDeclaration ? 1 : 0; }
- String documentURI() const { return m_documentURI; }
-
- virtual KURL baseURI() const;
+ virtual KURL baseURI() const OVERRIDE FINAL;
String visibilityState() const;
bool hidden() const;
- void dispatchVisibilityStateChangeEvent();
-
- DOMSecurityPolicy* securityPolicy();
+ void didChangeVisibilityState();
- PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState&);
- PassRefPtr<HTMLCollection> images();
- PassRefPtr<HTMLCollection> embeds();
- PassRefPtr<HTMLCollection> applets();
- PassRefPtr<HTMLCollection> links();
- PassRefPtr<HTMLCollection> forms();
- PassRefPtr<HTMLCollection> anchors();
- PassRefPtr<HTMLCollection> scripts();
- PassRefPtr<HTMLCollection> allForBinding();
- PassRefPtr<HTMLCollection> all();
+ PassRefPtrWillBeRawPtr<HTMLCollection> images();
+ PassRefPtrWillBeRawPtr<HTMLCollection> embeds();
+ PassRefPtrWillBeRawPtr<HTMLCollection> applets();
+ PassRefPtrWillBeRawPtr<HTMLCollection> links();
+ PassRefPtrWillBeRawPtr<HTMLCollection> forms();
+ PassRefPtrWillBeRawPtr<HTMLCollection> anchors();
+ PassRefPtrWillBeRawPtr<HTMLCollection> scripts();
+ PassRefPtrWillBeRawPtr<HTMLAllCollection> allForBinding();
+ PassRefPtrWillBeRawPtr<HTMLAllCollection> all();
- PassRefPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
- PassRefPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
bool isHTMLDocument() const { return m_documentClasses & HTMLDocumentClass; }
bool isXHTMLDocument() const { return m_documentClasses & XHTMLDocumentClass; }
+ bool isXMLDocument() const { return m_documentClasses & XMLDocumentClass; }
bool isImageDocument() const { return m_documentClasses & ImageDocumentClass; }
bool isSVGDocument() const { return m_documentClasses & SVGDocumentClass; }
bool isPluginDocument() const { return m_documentClasses & PluginDocumentClass; }
@@ -394,6 +410,9 @@ public:
bool isSrcdocDocument() const { return m_isSrcdocDocument; }
bool isMobileDocument() const { return m_isMobileDocument; }
+ bool isTransitionDocument() const { return m_isTransitionDocument; }
+ void setIsTransitionDocument() { m_isTransitionDocument = true; }
+
StyleResolver* styleResolver() const;
StyleResolver& ensureStyleResolver() const;
@@ -402,10 +421,8 @@ public:
bool sawElementsInKnownNamespaces() const { return m_sawElementsInKnownNamespaces; }
- void notifyRemovePendingSheetIfNeeded();
-
- bool haveStylesheetsLoaded() const;
- bool haveStylesheetsAndImportsLoaded() const { return haveImportsLoaded() && haveStylesheetsLoaded(); }
+ bool isRenderingReady() const { return haveImportsLoaded() && haveStylesheetsLoaded(); }
+ bool isScriptExecutionReady() const { return isRenderingReady(); }
// This is a DOM function.
StyleSheetList* styleSheets();
@@ -416,55 +433,61 @@ public:
void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
// Called when one or more stylesheets in the document may have been added, removed, or changed.
- void styleResolverChanged(RecalcStyleTime, StyleResolverUpdateMode = FullStyleUpdate);
+ void styleResolverChanged(StyleResolverUpdateMode = FullStyleUpdate);
+ void styleResolverMayHaveChanged();
// FIXME: Switch all callers of styleResolverChanged to these or better ones and then make them
// do something smarter.
- void removedStyleSheet(StyleSheet*, RecalcStyleTime when = RecalcStyleDeferred, StyleResolverUpdateMode = FullStyleUpdate);
- void addedStyleSheet(StyleSheet*, RecalcStyleTime when = RecalcStyleDeferred) { styleResolverChanged(when); }
- void modifiedStyleSheet(StyleSheet*, RecalcStyleTime when = RecalcStyleDeferred, StyleResolverUpdateMode = FullStyleUpdate);
- void changedSelectorWatch() { styleResolverChanged(RecalcStyleDeferred); }
+ void removedStyleSheet(StyleSheet*, StyleResolverUpdateMode = FullStyleUpdate);
+ void addedStyleSheet(StyleSheet*) { styleResolverChanged(); }
+ void modifiedStyleSheet(StyleSheet*, StyleResolverUpdateMode = FullStyleUpdate);
+ void changedSelectorWatch() { styleResolverChanged(); }
+
+ void scheduleUseShadowTreeUpdate(SVGUseElement&);
+ void unscheduleUseShadowTreeUpdate(SVGUseElement&);
+
+ // FIXME: SVG filters should change to store the filter on the RenderStyle
+ // instead of the RenderObject so we can get rid of this hack.
+ void scheduleSVGFilterLayerUpdateHack(Element&);
+ void unscheduleSVGFilterLayerUpdateHack(Element&);
void evaluateMediaQueryList();
- // Never returns 0.
- FormController* formController();
- Vector<String> formElementsState() const;
+ FormController& formController();
+ DocumentState* formElementsState() const;
void setStateForNewFormElements(const Vector<String>&);
FrameView* view() const; // can be null
- Frame* frame() const { return m_frame; } // can be null
+ LocalFrame* frame() const { return m_frame; } // can be null
+ FrameHost* frameHost() const; // can be null
Page* page() const; // can be null
Settings* settings() const; // can be null
float devicePixelRatio() const;
- PassRefPtr<Range> createRange();
+ PassRefPtrWillBeRawPtr<Range> createRange();
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, ExceptionState&);
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, ExceptionState&);
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, ExceptionState&);
+ PassRefPtrWillBeRawPtr<NodeIterator> createNodeIterator(Node* root, ExceptionState&);
+ PassRefPtrWillBeRawPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, ExceptionState&);
+ PassRefPtrWillBeRawPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>, ExceptionState&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, ExceptionState&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, ExceptionState&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TreeWalker> createTreeWalker(Node* root, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>, ExceptionState&);
// Special support for editing
- PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
- PassRefPtr<Text> createEditingTextNode(const String&);
+ PassRefPtrWillBeRawPtr<Text> createEditingTextNode(const String&);
- void setStyleDependentState(RenderStyle* documentStyle);
- void inheritHtmlAndBodyElementStyles(StyleRecalcChange);
- void recalcStyle(StyleRecalcChange);
- void updateStyleIfNeeded();
- void updateStyleForNodeIfNeeded(Node*);
+ void setupFontBuilder(RenderStyle* documentStyle);
+
+ void updateRenderTreeIfNeeded() { updateRenderTree(NoChange); }
+ void updateRenderTreeForNodeIfNeeded(Node*);
void updateLayout();
enum RunPostLayoutTasks {
RunPostLayoutTasksAsyhnchronously,
RunPostLayoutTasksSynchronously,
};
void updateLayoutIgnorePendingStylesheets(RunPostLayoutTasks = RunPostLayoutTasksAsyhnchronously);
- void partialUpdateLayoutIgnorePendingStylesheets(Node*);
PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*);
PassRefPtr<RenderStyle> styleForPage(int pageIndex);
@@ -485,6 +508,9 @@ public:
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
void prepareForDestruction();
+ // If you have a Document, use renderView() instead which is faster.
+ void renderer() const WTF_DELETED_FUNCTION;
+
RenderView* renderView() const { return m_renderView; }
AXObjectCache* existingAXObjectCache() const;
@@ -492,16 +518,15 @@ public:
void clearAXObjectCache();
// to get visually ordered hebrew and arabic pages right
- void setVisuallyOrdered();
bool visuallyOrdered() const { return m_visuallyOrdered; }
DocumentLoader* loader() const;
- void open(Document* ownerDocument = 0);
- PassRefPtr<DocumentParser> implicitOpen();
+ void open(Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
+ PassRefPtrWillBeRawPtr<DocumentParser> implicitOpen();
// close() is the DOM API document.close()
- void close();
+ void close(ExceptionState& = ASSERT_NO_EXCEPTION);
// In some situations (see the code), we ignore document.close().
// explicitClose() bypass these checks and actually tries to close the
// input stream.
@@ -522,9 +547,9 @@ public:
void cancelParsing();
- void write(const SegmentedString& text, Document* ownerDocument = 0);
- void write(const String& text, Document* ownerDocument = 0);
- void writeln(const String& text, Document* ownerDocument = 0);
+ void write(const SegmentedString& text, Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void write(const String& text, Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void writeln(const String& text, Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
bool wellFormed() const { return m_wellFormed; }
@@ -537,21 +562,21 @@ public:
void setBaseURLOverride(const KURL&);
const KURL& baseURLOverride() const { return m_baseURLOverride; }
const KURL& baseElementURL() const { return m_baseElementURL; }
- const String& baseTarget() const { return m_baseTarget; }
+ const AtomicString& baseTarget() const { return m_baseTarget; }
void processBaseElement();
KURL completeURL(const String&) const;
- KURL completeURL(const String&, const KURL& baseURLOverride) const;
+ KURL completeURLWithOverride(const String&, const KURL& baseURLOverride) const;
- virtual String userAgent(const KURL&) const;
- virtual void disableEval(const String& errorMessage);
+ virtual String userAgent(const KURL&) const OVERRIDE FINAL;
+ virtual void disableEval(const String& errorMessage) OVERRIDE FINAL;
- bool canNavigate(Frame* targetFrame);
- Frame* findUnsafeParentScrollPropagationBoundary();
+ bool canNavigate(const Frame& targetFrame);
+ LocalFrame* findUnsafeParentScrollPropagationBoundary();
- CSSStyleSheet* elementSheet();
+ CSSStyleSheet& elementSheet();
- virtual PassRefPtr<DocumentParser> createParser();
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser();
DocumentParser* parser() const { return m_parser.get(); }
ScriptableDocumentParser* scriptableDocumentParser() const;
@@ -566,7 +591,6 @@ public:
enum CompatibilityMode { QuirksMode, LimitedQuirksMode, NoQuirksMode };
void setCompatibilityMode(CompatibilityMode m);
- void lockCompatibilityMode() { m_compatibilityModeLocked = true; }
CompatibilityMode compatibilityMode() const { return m_compatibilityMode; }
String compatMode() const;
@@ -584,11 +608,9 @@ public:
bool isLoadCompleted();
void setParsing(bool);
- bool parsing() const { return m_bParsing; }
- int minimumLayoutDelay();
+ bool parsing() const { return m_isParsing; }
- bool shouldScheduleLayout();
- bool shouldParserYieldAgressivelyBeforeScriptExecution();
+ bool shouldScheduleLayout() const;
int elapsedTime() const;
TextLinkColors& textLinkColors() { return m_textLinkColors; }
@@ -604,18 +626,16 @@ public:
String selectedStylesheetSet() const;
void setSelectedStylesheetSet(const String&);
- bool setFocusedElement(PassRefPtr<Element>, FocusDirection = FocusDirectionNone);
+ bool setFocusedElement(PassRefPtrWillBeRawPtr<Element>, FocusType = FocusTypeNone);
Element* focusedElement() const { return m_focusedElement.get(); }
UserActionElementSet& userActionElements() { return m_userActionElements; }
const UserActionElementSet& userActionElements() const { return m_userActionElements; }
void setNeedsFocusedElementCheck();
- void didRunCheckFocusedElementTask() { m_didPostCheckFocusedElementTask = false; }
+ void setAutofocusElement(Element*);
+ Element* autofocusElement() const { return m_autofocusElement.get(); }
- void setHoverNode(PassRefPtr<Node>);
- Node* hoverNode() const { return m_hoverNode.get(); }
-
- void setActiveElement(PassRefPtr<Element>);
- Element* activeElement() const { return m_activeElement.get(); }
+ void setActiveHoverElement(PassRefPtrWillBeRawPtr<Element>);
+ Element* activeHoverElement() const { return m_activeHoverElement.get(); }
void removeFocusedElementOfSubtree(Node*, bool amongChildrenOnly = false);
void hoveredNodeDetached(Node*);
@@ -627,44 +647,45 @@ public:
void setCSSTarget(Element*);
Element* cssTarget() const { return m_cssTarget; }
- void scheduleStyleRecalc();
- void unscheduleStyleRecalc();
- bool hasPendingStyleRecalc() const;
+ void scheduleRenderTreeUpdateIfNeeded();
bool hasPendingForcedStyleRecalc() const;
- void styleRecalcTimerFired(Timer<Document>*);
- void registerNodeList(LiveNodeListBase*);
- void unregisterNodeList(LiveNodeListBase*);
+ void registerNodeList(const LiveNodeListBase*);
+ void unregisterNodeList(const LiveNodeListBase*);
+ void registerNodeListWithIdNameCache(const LiveNodeListBase*);
+ void unregisterNodeListWithIdNameCache(const LiveNodeListBase*);
bool shouldInvalidateNodeListCaches(const QualifiedName* attrName = 0) const;
void invalidateNodeListCaches(const QualifiedName* attrName);
void attachNodeIterator(NodeIterator*);
void detachNodeIterator(NodeIterator*);
- void moveNodeIteratorsToNewDocument(Node*, Document*);
+ void moveNodeIteratorsToNewDocument(Node&, Document&);
void attachRange(Range*);
void detachRange(Range*);
void updateRangesAfterChildrenChanged(ContainerNode*);
+ void updateRangesAfterNodeMovedToAnotherDocument(const Node&);
// nodeChildrenWillBeRemoved is used when removing all node children at once.
- void nodeChildrenWillBeRemoved(ContainerNode*);
+ void nodeChildrenWillBeRemoved(ContainerNode&);
// nodeWillBeRemoved is only safe when removing one node at a time.
void nodeWillBeRemoved(Node&);
bool canReplaceChild(const Node& newChild, const Node& oldChild) const;
void didInsertText(Node*, unsigned offset, unsigned length);
void didRemoveText(Node*, unsigned offset, unsigned length);
- void didMergeTextNodes(Text* oldNode, unsigned offset);
- void didSplitTextNode(Text* oldNode);
+ void didMergeTextNodes(Text& oldNode, unsigned offset);
+ void didSplitTextNode(Text& oldNode);
- void clearDOMWindow() { m_domWindow = 0; }
- DOMWindow* domWindow() const { return m_domWindow; }
+ void clearDOMWindow() { m_domWindow = nullptr; }
+ LocalDOMWindow* domWindow() const { return m_domWindow; }
- // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
- void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
- EventListener* getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
+ // Helper functions for forwarding LocalDOMWindow event related tasks to the LocalDOMWindow if it exists.
+ void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+ EventListener* getWindowAttributeEventListener(const AtomicString& eventType);
- PassRefPtr<Event> createEvent(const String& eventType, ExceptionState&);
+ static void registerEventFactory(PassOwnPtr<EventFactoryBase>);
+ static PassRefPtrWillBeRawPtr<Event> createEvent(const String& eventType, ExceptionState&);
// keep track of what types of event listeners are registered, so we don't
// dispatch events unnecessarily
@@ -680,9 +701,8 @@ public:
ANIMATIONSTART_LISTENER = 1 << 8,
ANIMATIONITERATION_LISTENER = 1 << 9,
TRANSITIONEND_LISTENER = 1 << 10,
- BEFORELOAD_LISTENER = 1 << 11,
SCROLL_LISTENER = 1 << 12
- // 3 bits remaining
+ // 4 bits remaining
};
bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }
@@ -705,9 +725,9 @@ public:
*
* @param equiv The http header name (value of the meta tag's "equiv" attribute)
* @param content The header value (value of the meta tag's "content" attribute)
+ * @param inDocumentHeadElement Is the element in the document's <head> element?
*/
- void processHttpEquiv(const AtomicString& equiv, const AtomicString& content);
- void processViewport(const String& features, ViewportDescription::Type origin);
+ void processHttpEquiv(const AtomicString& equiv, const AtomicString& content, bool inDocumentHeadElement);
void updateViewportDescription();
void processReferrerPolicy(const String& policy);
@@ -715,9 +735,6 @@ public:
// Returns 0 if this is the top level document.
HTMLFrameOwnerElement* ownerElement() const;
- HTMLIFrameElement* seamlessParentIFrame() const;
- bool shouldDisplaySeamlesslyWithParent() const;
-
String title() const { return m_title; }
void setTitle(const String&);
@@ -725,6 +742,9 @@ public:
void setTitleElement(const String& title, Element* titleElement);
void removeTitle(Element* titleElement);
+ const AtomicString& dir();
+ void setDir(const AtomicString&);
+
String cookie(ExceptionState&) const;
void setCookie(const String&, ExceptionState&);
@@ -765,11 +785,17 @@ public:
static bool hasValidNamespaceForAttributes(const QualifiedName&);
HTMLElement* body() const;
- void setBody(PassRefPtr<HTMLElement>, ExceptionState&);
+ void setBody(PassRefPtrWillBeRawPtr<HTMLElement>, ExceptionState&);
+
+ HTMLHeadElement* head() const;
- HTMLHeadElement* head();
+ // Decide which element is to define the viewport's overflow policy. If |rootStyle| is set, use
+ // that as the style for the root element, rather than obtaining it on our own. The reason for
+ // this is that style may not have been associated with the elements yet - in which case it may
+ // have been calculated on the fly (without associating it with the actual element) somewhere.
+ Element* viewportDefiningElement(RenderStyle* rootStyle = 0) const;
- DocumentMarkerController* markers() const { return m_markers.get(); }
+ DocumentMarkerController& markers() const { return *m_markers; }
bool directionSetOnDocumentElement() const { return m_directionSetOnDocumentElement; }
bool writingModeSetOnDocumentElement() const { return m_writingModeSetOnDocumentElement; }
@@ -790,36 +816,45 @@ public:
void setDesignMode(InheritedBool value);
InheritedBool getDesignMode() const;
bool inDesignMode() const;
+ String designMode() const;
+ void setDesignMode(const String&);
Document* parentDocument() const;
- Document* topDocument() const;
- WeakPtr<Document> contextDocument();
+ Document& topDocument() const;
+ WeakPtrWillBeRawPtr<Document> contextDocument();
ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
HTMLScriptElement* currentScript() const { return !m_currentScriptStack.isEmpty() ? m_currentScriptStack.last().get() : 0; }
- void pushCurrentScript(PassRefPtr<HTMLScriptElement>);
+ void pushCurrentScript(PassRefPtrWillBeRawPtr<HTMLScriptElement>);
void popCurrentScript();
void applyXSLTransform(ProcessingInstruction* pi);
- PassRefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
+ PassRefPtrWillBeRawPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; }
void setTransformSource(PassOwnPtr<TransformSource>);
TransformSource* transformSource() const { return m_transformSource.get(); }
- void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
+ void incDOMTreeVersion() { ASSERT(m_lifecycle.stateAllowsTreeMutations()); m_domTreeVersion = ++s_globalTreeVersion; }
uint64_t domTreeVersion() const { return m_domTreeVersion; }
enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
+ bool ignoreLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == IgnoreLayoutWithPendingSheets; }
bool hasNodesWithPlaceholderStyle() const { return m_hasNodesWithPlaceholderStyle; }
void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
Vector<IconURL> iconURLs(int iconTypesMask);
+ Color themeColor() const;
+
+ // Returns the HTMLLinkElement currently in use for the Web Manifest.
+ // Returns null if there is no such element.
+ HTMLLinkElement* linkManifest() const;
+
void setUseSecureKeyboardEntryWhenActive(bool);
bool useSecureKeyboardEntryWhenActive() const;
@@ -827,28 +862,28 @@ public:
void cancelFocusAppearanceUpdate();
// Extension for manipulating canvas drawing contexts for use in CSS
- CanvasRenderingContext* getCSSCanvasContext(const String& type, const String& name, int width, int height);
- HTMLCanvasElement* getCSSCanvasElement(const String& name);
+ void getCSSCanvasContext(const String& type, const String& name, int width, int height, bool&, RefPtrWillBeRawPtr<CanvasRenderingContext2D>&, bool&, RefPtrWillBeRawPtr<WebGLRenderingContext>&);
+ HTMLCanvasElement& getCSSCanvasElement(const String& name);
bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
void parseDNSPrefetchControlHeader(const String&);
- // FIXME(crbug.com/305497): This should be removed once DOMWindow is an ExecutionContext.
+ // FIXME(crbug.com/305497): This should be removed once LocalDOMWindow is an ExecutionContext.
virtual void postTask(PassOwnPtr<ExecutionContextTask>) OVERRIDE; // Executes the task on context's thread asynchronously.
- virtual void tasksWereSuspended() OVERRIDE;
- virtual void tasksWereResumed() OVERRIDE;
- virtual void suspendScheduledTasks() OVERRIDE;
- virtual void resumeScheduledTasks() OVERRIDE;
- virtual bool tasksNeedSuspension() OVERRIDE;
+ virtual void tasksWereSuspended() OVERRIDE FINAL;
+ virtual void tasksWereResumed() OVERRIDE FINAL;
+ virtual void suspendScheduledTasks() OVERRIDE FINAL;
+ virtual void resumeScheduledTasks() OVERRIDE FINAL;
+ virtual bool tasksNeedSuspension() OVERRIDE FINAL;
void finishedParsing();
void setEncodingData(const DocumentEncodingData& newData);
- const WTF::TextEncoding& encoding() const { return m_encodingData.encoding; }
+ const WTF::TextEncoding& encoding() const { return m_encodingData.encoding(); }
- bool encodingWasDetectedHeuristically() const { return m_encodingData.wasDetectedHeuristically; }
- bool sawDecodingError() const { return m_encodingData.sawDecodingError; }
+ bool encodingWasDetectedHeuristically() const { return m_encodingData.wasDetectedHeuristically(); }
+ bool sawDecodingError() const { return m_encodingData.sawDecodingError(); }
void setAnnotatedRegionsDirty(bool f) { m_annotatedRegionsDirty = f; }
bool annotatedRegionsDirty() const { return m_annotatedRegionsDirty; }
@@ -857,10 +892,10 @@ public:
const Vector<AnnotatedRegionValue>& annotatedRegions() const;
void setAnnotatedRegions(const Vector<AnnotatedRegionValue>&);
- virtual void removeAllEventListeners();
+ virtual void removeAllEventListeners() OVERRIDE FINAL;
const SVGDocumentExtensions* svgExtensions();
- SVGDocumentExtensions* accessSVGExtensions();
+ SVGDocumentExtensions& accessSVGExtensions();
void initSecurityContext();
void initSecurityContext(const DocumentInit&);
@@ -885,56 +920,60 @@ public:
bool loadEventStillNeeded() const { return m_loadEventProgress == LoadEventNotRun; }
bool processingLoadEvent() const { return m_loadEventProgress == LoadEventInProgress; }
bool loadEventFinished() const { return m_loadEventProgress >= LoadEventCompleted; }
+ bool unloadStarted() const { return m_loadEventProgress >= PageHideInProgress; }
void setContainsPlugins() { m_containsPlugins = true; }
bool containsPlugins() const { return m_containsPlugins; }
- virtual bool isContextThread() const;
- virtual bool isJSExecutionForbidden() const { return false; }
+ virtual bool isContextThread() const OVERRIDE FINAL;
+ virtual bool isJSExecutionForbidden() const OVERRIDE FINAL { return false; }
bool containsValidityStyleRules() const { return m_containsValidityStyleRules; }
void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }
void enqueueResizeEvent();
void enqueueScrollEventForNode(Node*);
- void enqueueAnimationFrameEvent(PassRefPtr<Event>);
-
- const QualifiedName& idAttributeName() const { return m_idAttributeName; }
+ void enqueueAnimationFrameEvent(PassRefPtrWillBeRawPtr<Event>);
bool hasFullscreenElementStack() const { return m_hasFullscreenElementStack; }
void setHasFullscreenElementStack() { m_hasFullscreenElementStack = true; }
- void webkitExitPointerLock();
- Element* webkitPointerLockElement() const;
+ void exitPointerLock();
+ Element* pointerLockElement() const;
// Used to allow element that loads data without going through a FrameLoader to delay the 'load' event.
void incrementLoadEventDelayCount() { ++m_loadEventDelayCount; }
void decrementLoadEventDelayCount();
- bool isDelayingLoadEvent() const { return m_loadEventDelayCount; }
+ void checkLoadEventSoon();
+ bool isDelayingLoadEvent();
+ void loadPluginsSoon();
- PassRefPtr<Touch> createTouch(DOMWindow*, EventTarget*, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const;
- PassRefPtr<TouchList> createTouchList(Vector<RefPtr<Touch> >&) const;
+ PassRefPtrWillBeRawPtr<Touch> createTouch(LocalDOMWindow*, EventTarget*, int identifier, double pageX, double pageY, double screenX, double screenY, double radiusX, double radiusY, float rotationAngle, float force) const;
+ PassRefPtrWillBeRawPtr<TouchList> createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >&) const;
- const DocumentTiming* timing() const { return &m_documentTiming; }
+ const DocumentTiming& timing() const { return m_documentTiming; }
int requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
void cancelAnimationFrame(int id);
void serviceScriptedAnimations(double monotonicAnimationStartTime);
- virtual EventTarget* errorEventTarget();
- virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>);
+ virtual EventTarget* errorEventTarget() OVERRIDE FINAL;
+ virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>) OVERRIDE FINAL;
void initDNSPrefetch();
- double lastHandledUserGestureTimestamp() const { return m_lastHandledUserGestureTimestamp; }
- void resetLastHandledUserGestureTimestamp();
-
bool hasTouchEventHandlers() const { return (m_touchEventTargets.get()) ? m_touchEventTargets->size() : false; }
+ // Called when a single touch event handler has been added or removed for a node.
+ // The Node should always be in this Document, except for child Documents which report
+ // themselves to their parent exactly once if they have any touch handlers.
+ // Handlers added/removed from the LocalDOMWindow are reported as the Document.
void didAddTouchEventHandler(Node*);
- void didRemoveTouchEventHandler(Node*);
+ void didRemoveTouchEventHandler(Node* handler) { didRemoveTouchEventHandler(handler, false); }
- void didRemoveEventTargetNode(Node*);
+ // Called whenever all touch event handlers have been removed for a node (such as when the
+ // node itself is being removed from the document).
+ void didClearTouchEventHandlers(Node* handler) { didRemoveTouchEventHandler(handler, true); }
const TouchEventTargetSet* touchEventTargets() const { return m_touchEventTargets.get(); }
@@ -947,14 +986,16 @@ public:
TextAutosizer* textAutosizer();
FastTextAutosizer* fastTextAutosizer();
- PassRefPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState&);
- PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState&);
ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionState&);
ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionState&, CustomElement::NameSet validNames = CustomElement::StandardNames);
CustomElementRegistrationContext* registrationContext() { return m_registrationContext.get(); }
- void setImport(HTMLImport*);
- HTMLImport* import() const { return m_import; }
+ void setImportsController(HTMLImportsController*);
+ HTMLImportsController* importsController() const { return m_importsController; }
+ HTMLImportLoader* importLoader() const;
+
bool haveImportsLoaded() const;
void didLoadAllImports();
@@ -966,46 +1007,46 @@ public:
void incrementActiveParserCount() { ++m_activeParserCount; }
void decrementActiveParserCount();
- void setContextFeatures(PassRefPtr<ContextFeatures>);
- ContextFeatures* contextFeatures() const { return m_contextFeatures.get(); }
+ void setContextFeatures(ContextFeatures&);
+ ContextFeatures& contextFeatures() const { return *m_contextFeatures; }
- DocumentSharedObjectPool* sharedObjectPool() { return m_sharedObjectPool.get(); }
+ ElementDataCache* elementDataCache() { return m_elementDataCache.get(); }
+ void didLoadAllScriptBlockingResources();
void didRemoveAllPendingStylesheet();
- void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
void clearStyleResolver();
- void notifySeamlessChildDocumentsOfStylesheetUpdate() const;
- bool inStyleRecalc() { return m_inStyleRecalc; }
+ bool inStyleRecalc() const { return m_lifecycle.state() == DocumentLifecycle::InStyleRecalc; }
// Return a Locale for the default locale if the argument is null or empty.
Locale& getCachedLocale(const AtomicString& locale = nullAtom);
- AnimationClock& animationClock() { return *m_animationClock; }
- DocumentTimeline* timeline() const { return m_timeline.get(); }
- DocumentTimeline* transitionTimeline() const { return m_transitionTimeline.get(); }
- CSSPendingAnimations& cssPendingAnimations() { return m_cssPendingAnimations; }
+ AnimationClock& animationClock() { return m_animationClock; }
+ AnimationTimeline& timeline() const { return *m_timeline; }
+ CompositorPendingAnimations& compositorPendingAnimations() { return m_compositorPendingAnimations; }
void addToTopLayer(Element*, const Element* before = 0);
void removeFromTopLayer(Element*);
- const Vector<RefPtr<Element> >& topLayerElements() const { return m_topLayerElements; }
+ const WillBeHeapVector<RefPtrWillBeMember<Element> >& topLayerElements() const { return m_topLayerElements; }
HTMLDialogElement* activeModalDialog() const;
- const Document* templateDocument() const;
+ // A non-null m_templateDocumentHost implies that |this| was created by ensureTemplateDocument().
+ bool isTemplateDocument() const { return !!m_templateDocumentHost; }
Document& ensureTemplateDocument();
- void setTemplateDocumentHost(Document* templateDocumentHost) { m_templateDocumentHost = templateDocumentHost; }
Document* templateDocumentHost() { return m_templateDocumentHost; }
void didAssociateFormControl(Element*);
void addConsoleMessageWithRequestIdentifier(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier);
- virtual DOMWindow* executingWindow() OVERRIDE { return domWindow(); }
- virtual void userEventWasHandled() OVERRIDE { resetLastHandledUserGestureTimestamp(); }
+ virtual LocalDOMWindow* executingWindow() OVERRIDE FINAL;
+ LocalFrame* executingFrame();
DocumentLifecycleNotifier& lifecycleNotifier();
- bool isActive() const { return m_lifecyle.state() == DocumentLifecycle::Active; }
- bool isStopped() const { return m_lifecyle.state() == DocumentLifecycle::Stopped; }
+ DocumentLifecycle& lifecycle() { return m_lifecycle; }
+ bool isActive() const { return m_lifecycle.isActive(); }
+ bool isStopped() const { return m_lifecycle.state() == DocumentLifecycle::Stopped; }
+ bool isDisposed() const { return m_lifecycle.state() == DocumentLifecycle::Disposed; }
enum HttpRefreshType {
HttpRefreshFromHeader,
@@ -1016,71 +1057,106 @@ public:
void updateSecurityOrigin(PassRefPtr<SecurityOrigin>);
PassOwnPtr<LifecycleNotifier<Document> > createLifecycleNotifier();
+ void setHasViewportUnits() { m_hasViewportUnits = true; }
+ bool hasViewportUnits() const { return m_hasViewportUnits; }
+ void notifyResizeForViewportUnits();
+
+ void registerVisibilityObserver(DocumentVisibilityObserver*);
+ void unregisterVisibilityObserver(DocumentVisibilityObserver*);
+
+ void updateStyleInvalidationIfNeeded();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ bool hasSVGFilterElementsRequiringLayerUpdate() const { return m_layerUpdateSVGFilterElements.size(); }
+ void didRecalculateStyleForElement() { ++m_styleRecalcElementCounter; }
+
protected:
Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);
- virtual void didUpdateSecurityOrigin() OVERRIDE;
+ virtual void didUpdateSecurityOrigin() OVERRIDE FINAL;
void clearXMLVersion() { m_xmlVersion = String(); }
+#if !ENABLE(OILPAN)
virtual void dispose() OVERRIDE;
+#endif
+
+ virtual PassRefPtrWillBeRawPtr<Document> cloneDocumentWithoutChildren();
- virtual PassRefPtr<Document> cloneDocumentWithoutChildren();
+ bool importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtrWillBeRawPtr<ContainerNode> newContainerNode, ExceptionState&);
+ void lockCompatibilityMode() { m_compatibilityModeLocked = true; }
private:
friend class Node;
friend class IgnoreDestructiveWriteCountIncrementer;
ScriptedAnimationController& ensureScriptedAnimationController();
- virtual SecurityContext& securityContext() OVERRIDE { return *this; }
- virtual EventQueue* eventQueue() const FINAL;
+ virtual SecurityContext& securityContext() OVERRIDE FINAL { return *this; }
+ virtual EventQueue* eventQueue() const OVERRIDE FINAL;
+
+ // FIXME: Rename the StyleRecalc state to RenderTreeUpdate.
+ bool hasPendingStyleRecalc() const { return m_lifecycle.state() == DocumentLifecycle::VisualUpdatePending; }
+
+ bool shouldScheduleRenderTreeUpdate() const;
+ void scheduleRenderTreeUpdate();
+ bool needsFullRenderTreeUpdate() const;
+ bool needsRenderTreeUpdate() const;
+
+ void inheritHtmlAndBodyElementStyles(StyleRecalcChange);
+
+ bool dirtyElementsForLayerUpdate();
void updateDistributionIfNeeded();
+ void updateUseShadowTreesIfNeeded();
+ void evaluateMediaQueryListIfNeeded();
+
+ void updateRenderTree(StyleRecalcChange);
+ void updateStyle(StyleRecalcChange);
void detachParser();
- virtual bool isDocument() const OVERRIDE { return true; }
+ void clearWeakMembers(Visitor*);
+
+ virtual bool isDocument() const OVERRIDE FINAL { return true; }
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual bool childTypeAllowed(NodeType) const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
+ virtual String nodeName() const OVERRIDE FINAL;
+ virtual NodeType nodeType() const OVERRIDE FINAL;
+ virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
void cloneDataFromDocument(const Document&);
- virtual void refExecutionContext() { ref(); }
- virtual void derefExecutionContext() { deref(); }
+#if !ENABLE(OILPAN)
+ virtual void refExecutionContext() OVERRIDE FINAL { ref(); }
+ virtual void derefExecutionContext() OVERRIDE FINAL { deref(); }
+#endif
- virtual const KURL& virtualURL() const; // Same as url(), but needed for ExecutionContext to implement it without a performance loss for direct calls.
- virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
+ virtual const KURL& virtualURL() const OVERRIDE FINAL; // Same as url(), but needed for ExecutionContext to implement it without a performance loss for direct calls.
+ virtual KURL virtualCompleteURL(const String&) const OVERRIDE FINAL; // Same as completeURL() for the same reason as above.
- virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE;
- virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*);
- void internalAddMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState*);
+ virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE FINAL;
+ virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*) OVERRIDE FINAL;
+ void internalAddMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>, ScriptState*);
- virtual double timerAlignmentInterval() const;
+ virtual double timerAlignmentInterval() const OVERRIDE FINAL;
void updateTitle(const String&);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
- void executeScriptsWaitingForResourcesIfNeeded();
-
- void seamlessParentUpdatedStylesheets();
-
- void recalcStyleForLayoutIgnoringPendingStylesheets();
-
- PassRefPtr<NodeList> handleZeroPadding(const HitTestRequest&, HitTestResult&) const;
+ void executeScriptsWaitingForResourcesTimerFired(Timer<Document>*);
void loadEventDelayTimerFired(Timer<Document>*);
+ void pluginLoadingTimerFired(Timer<Document>*);
PageVisibilityState pageVisibilityState() const;
- PassRefPtr<HTMLCollection> ensureCachedCollection(CollectionType);
+ PassRefPtrWillBeRawPtr<HTMLCollection> ensureCachedCollection(CollectionType);
- // Note that dispatching a window load event may cause the DOMWindow to be detached from
- // the Frame, so callers should take a reference to the DOMWindow (which owns us) to
+ // Note that dispatching a window load event may cause the LocalDOMWindow to be detached from
+ // the LocalFrame, so callers should take a reference to the LocalDOMWindow (which owns us) to
// prevent the Document from getting blown away from underneath them.
void dispatchWindowLoadEvent();
@@ -1088,7 +1164,9 @@ private:
void addMutationEventListenerTypeIfEnabled(ListenerType);
void didAssociateFormControlsTimerFired(Timer<Document>*);
- void styleResolverThrowawayTimerFired(Timer<Document>*);
+
+ void clearFocusedElementSoon();
+ void clearFocusedElementTimerFired(Timer<Document>*);
void processHttpEquivDefaultStyle(const AtomicString& content);
void processHttpEquivRefresh(const AtomicString& content);
@@ -1096,10 +1174,19 @@ private:
void processHttpEquivXFrameOptions(const AtomicString& content);
void processHttpEquivContentSecurityPolicy(const AtomicString& equiv, const AtomicString& content);
- DocumentLifecycle m_lifecyle;
+ void didRemoveTouchEventHandler(Node*, bool clearAll);
+
+ bool haveStylesheetsLoaded() const;
+
+ void setHoverNode(PassRefPtrWillBeRawPtr<Node>);
+ Node* hoverNode() const { return m_hoverNode.get(); }
+
+ typedef HashSet<OwnPtr<EventFactoryBase> > EventFactorySet;
+ static EventFactorySet& eventFactories();
+
+ DocumentLifecycle m_lifecycle;
bool m_hasNodesWithPlaceholderStyle;
- bool m_needsNotifyRemoveAllPendingStylesheet;
bool m_evaluateMediaQueriesOnStyleRecalc;
// If we do ignore the pending stylesheet count, then we need to add a boolean
@@ -1107,14 +1194,17 @@ private:
// do eventually load.
PendingSheetLayout m_pendingSheetLayout;
- Frame* m_frame;
- DOMWindow* m_domWindow;
- HTMLImport* m_import;
+ LocalFrame* m_frame;
+ RawPtrWillBeMember<LocalDOMWindow> m_domWindow;
+ // FIXME: oilpan: when we get rid of the transition types change the
+ // HTMLImportsController to not be a DocumentSupplement since it is
+ // redundant with oilpan.
+ RawPtrWillBeMember<HTMLImportsController> m_importsController;
- RefPtr<ResourceFetcher> m_fetcher;
- RefPtr<DocumentParser> m_parser;
+ RefPtrWillBeMember<ResourceFetcher> m_fetcher;
+ RefPtrWillBeMember<DocumentParser> m_parser;
unsigned m_activeParserCount;
- RefPtr<ContextFeatures> m_contextFeatures;
+ RefPtrWillBeMember<ContextFeatures> m_contextFeatures;
bool m_wellFormed;
@@ -1125,19 +1215,15 @@ private:
KURL m_baseElementURL; // The URL set by the <base> element.
KURL m_cookieURL; // The URL to use for cookie access.
- // Document.documentURI:
- // Although URL-like, Document.documentURI can actually be set to any
- // string by content. Document.documentURI affects m_baseURL unless the
- // document contains a <base> element, in which case the <base> element
- // takes precedence.
- String m_documentURI;
+ AtomicString m_baseTarget;
- String m_baseTarget;
+ // Mime-type of the document in case it was cloned or created by XHR.
+ AtomicString m_mimeType;
- RefPtr<DocumentType> m_docType;
- OwnPtr<DOMImplementation> m_implementation;
+ RefPtrWillBeMember<DocumentType> m_docType;
+ OwnPtrWillBeMember<DOMImplementation> m_implementation;
- RefPtr<CSSStyleSheet> m_elemSheet;
+ RefPtrWillBeMember<CSSStyleSheet> m_elemSheet;
bool m_printing;
bool m_paginatedForScreen;
@@ -1145,38 +1231,39 @@ private:
CompatibilityMode m_compatibilityMode;
bool m_compatibilityModeLocked; // This is cheaper than making setCompatibilityMode virtual.
- bool m_didPostCheckFocusedElementTask;
- RefPtr<Element> m_focusedElement;
- RefPtr<Node> m_hoverNode;
- RefPtr<Element> m_activeElement;
- RefPtr<Element> m_documentElement;
+ Timer<Document> m_executeScriptsWaitingForResourcesTimer;
+
+ bool m_hasAutofocused;
+ Timer<Document> m_clearFocusedElementTimer;
+ RefPtrWillBeMember<Element> m_autofocusElement;
+ RefPtrWillBeMember<Element> m_focusedElement;
+ RefPtrWillBeMember<Node> m_hoverNode;
+ RefPtrWillBeMember<Element> m_activeHoverElement;
+ RefPtrWillBeMember<Element> m_documentElement;
UserActionElementSet m_userActionElements;
uint64_t m_domTreeVersion;
static uint64_t s_globalTreeVersion;
- HashSet<NodeIterator*> m_nodeIterators;
- HashSet<Range*> m_ranges;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> > m_nodeIterators;
+ typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<Range> > AttachedRangeSet;
+ AttachedRangeSet m_ranges;
unsigned short m_listenerTypes;
MutationObserverOptions m_mutationObserverTypes;
- OwnPtr<StyleEngine> m_styleEngine;
- RefPtr<StyleSheetList> m_styleSheetList;
+ OwnPtrWillBeMember<StyleEngine> m_styleEngine;
+ RefPtrWillBeMember<StyleSheetList> m_styleSheetList;
- OwnPtr<FormController> m_formController;
+ OwnPtrWillBeMember<FormController> m_formController;
TextLinkColors m_textLinkColors;
const OwnPtr<VisitedLinkState> m_visitedLinkState;
- bool m_loadingSheet;
bool m_visuallyOrdered;
ReadyState m_readyState;
- bool m_bParsing;
-
- Timer<Document> m_styleRecalcTimer;
- bool m_inStyleRecalc;
+ bool m_isParsing;
bool m_gotoAnchorNeededAfterStylesheetsLoad;
bool m_isDNSPrefetchEnabled;
@@ -1191,26 +1278,25 @@ private:
String m_title;
String m_rawTitle;
bool m_titleSetExplicitly;
- RefPtr<Element> m_titleElement;
+ RefPtrWillBeMember<Element> m_titleElement;
OwnPtr<AXObjectCache> m_axObjectCache;
- OwnPtr<DocumentMarkerController> m_markers;
+ OwnPtrWillBeMember<DocumentMarkerController> m_markers;
Timer<Document> m_updateFocusAppearanceTimer;
- Element* m_cssTarget;
+ RawPtrWillBeMember<Element> m_cssTarget;
LoadEventProgress m_loadEventProgress;
double m_startTime;
- bool m_overMinimumLayoutThreshold;
- OwnPtr<ScriptRunner> m_scriptRunner;
+ OwnPtrWillBeMember<ScriptRunner> m_scriptRunner;
- Vector<RefPtr<HTMLScriptElement> > m_currentScriptStack;
+ WillBeHeapVector<RefPtrWillBeMember<HTMLScriptElement> > m_currentScriptStack;
OwnPtr<TransformSource> m_transformSource;
- RefPtr<Document> m_transformSourceDocument;
+ RefPtrWillBeMember<Document> m_transformSourceDocument;
String m_xmlEncoding;
String m_xmlVersion;
@@ -1223,16 +1309,24 @@ private:
InheritedBool m_designMode;
- HashSet<LiveNodeListBase*> m_listsInvalidatedAtDocument;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<const LiveNodeListBase> > m_listsInvalidatedAtDocument;
+#if ENABLE(OILPAN)
+ // Oilpan keeps track of all registered NodeLists.
+ //
+ // FIXME: Oilpan: improve - only need to know if a NodeList
+ // is currently alive or not for the different types.
+ HeapHashSet<WeakMember<const LiveNodeListBase> > m_nodeLists[numNodeListInvalidationTypes];
+#else
unsigned m_nodeListCounts[numNodeListInvalidationTypes];
+#endif
- OwnPtr<SVGDocumentExtensions> m_svgExtensions;
+ OwnPtrWillBeMember<SVGDocumentExtensions> m_svgExtensions;
Vector<AnnotatedRegionValue> m_annotatedRegions;
bool m_hasAnnotatedRegions;
bool m_annotatedRegionsDirty;
- HashMap<String, RefPtr<HTMLCanvasElement> > m_cssCanvasElements;
+ WillBeHeapHashMap<String, RefPtrWillBeMember<HTMLCanvasElement> > m_cssCanvasElements;
OwnPtr<SelectorQueryCache> m_selectorQueryCache;
@@ -1244,55 +1338,50 @@ private:
bool m_sawElementsInKnownNamespaces;
bool m_isSrcdocDocument;
bool m_isMobileDocument;
- // Set in Document::initSecurityContext() at Document creation, per:
- // http://www.whatwg.org/specs/web-apps/current-work/#attr-iframe-seamless
- bool m_mayDisplaySeamlesslyWithParent;
+ bool m_isTransitionDocument;
RenderView* m_renderView;
+#if !ENABLE(OILPAN)
WeakPtrFactory<Document> m_weakFactory;
- WeakPtr<Document> m_contextDocument;
-
- QualifiedName m_idAttributeName;
+#endif
+ WeakPtrWillBeWeakMember<Document> m_contextDocument;
bool m_hasFullscreenElementStack; // For early return in FullscreenElementStack::fromIfExists()
- Vector<RefPtr<Element> > m_topLayerElements;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > m_topLayerElements;
int m_loadEventDelayCount;
Timer<Document> m_loadEventDelayTimer;
+ Timer<Document> m_pluginLoadingTimer;
ViewportDescription m_viewportDescription;
ViewportDescription m_legacyViewportDescription;
+ Length m_viewportDefaultMinWidth;
+ bool m_didSetReferrerPolicy;
ReferrerPolicy m_referrerPolicy;
bool m_directionSetOnDocumentElement;
bool m_writingModeSetOnDocumentElement;
DocumentTiming m_documentTiming;
- RefPtr<MediaQueryMatcher> m_mediaQueryMatcher;
+ RefPtrWillBeMember<MediaQueryMatcher> m_mediaQueryMatcher;
bool m_writeRecursionIsTooDeep;
unsigned m_writeRecursionDepth;
OwnPtr<TouchEventTargetSet> m_touchEventTargets;
- double m_lastHandledUserGestureTimestamp;
-
- RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
+ RefPtrWillBeMember<ScriptedAnimationController> m_scriptedAnimationController;
OwnPtr<MainThreadTaskRunner> m_taskRunner;
OwnPtr<TextAutosizer> m_textAutosizer;
OwnPtr<FastTextAutosizer> m_fastTextAutosizer;
- RefPtr<CustomElementRegistrationContext> m_registrationContext;
-
- RefPtr<NamedFlowCollection> m_namedFlows;
+ RefPtrWillBeMember<CustomElementRegistrationContext> m_registrationContext;
- RefPtr<DOMSecurityPolicy> m_domSecurityPolicy;
+ void elementDataCacheClearTimerFired(Timer<Document>*);
+ Timer<Document> m_elementDataCacheClearTimer;
- void sharedObjectPoolClearTimerFired(Timer<Document>*);
- Timer<Document> m_sharedObjectPoolClearTimer;
-
- OwnPtr<DocumentSharedObjectPool> m_sharedObjectPool;
+ OwnPtr<ElementDataCache> m_elementDataCache;
#ifndef NDEBUG
bool m_didDispatchViewportPropertiesChanged;
@@ -1301,32 +1390,29 @@ private:
typedef HashMap<AtomicString, OwnPtr<Locale> > LocaleIdentifierToLocaleMap;
LocaleIdentifierToLocaleMap m_localeCache;
- OwnPtr<AnimationClock> m_animationClock;
- RefPtr<DocumentTimeline> m_timeline;
- RefPtr<DocumentTimeline> m_transitionTimeline;
- CSSPendingAnimations m_cssPendingAnimations;
+ AnimationClock m_animationClock;
+ RefPtrWillBeMember<AnimationTimeline> m_timeline;
+ CompositorPendingAnimations m_compositorPendingAnimations;
- RefPtr<Document> m_templateDocument;
- Document* m_templateDocumentHost; // Manually managed weakref (backpointer from m_templateDocument).
+ RefPtrWillBeMember<Document> m_templateDocument;
+ // With Oilpan the templateDocument and the templateDocumentHost
+ // live and die together. Without Oilpan, the templateDocumentHost
+ // is a manually managed backpointer from m_templateDocument.
+ RawPtrWillBeMember<Document> m_templateDocumentHost;
Timer<Document> m_didAssociateFormControlsTimer;
- HashSet<RefPtr<Element> > m_associatedFormControls;
-};
+ WillBeHeapHashSet<RefPtrWillBeMember<Element> > m_associatedFormControls;
-inline void Document::notifyRemovePendingSheetIfNeeded()
-{
- if (m_needsNotifyRemoveAllPendingStylesheet)
- didRemoveAllPendingStylesheet();
-}
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGUseElement> > m_useElementsNeedingUpdate;
+ WillBeHeapHashSet<RawPtrWillBeMember<Element> > m_layerUpdateSVGFilterElements;
-inline const Document* Document::templateDocument() const
-{
- // If DOCUMENT does not have a browsing context, Let TEMPLATE CONTENTS OWNER be DOCUMENT and abort these steps.
- if (!m_frame)
- return this;
+ bool m_hasViewportUnits;
- return m_templateDocument.get();
-}
+ typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<DocumentVisibilityObserver> > DocumentVisibilityObserverSet;
+ DocumentVisibilityObserverSet m_visibilityObservers;
+
+ int m_styleRecalcElementCounter;
+};
inline bool Document::shouldOverrideLegacyDescription(ViewportDescription::Type origin)
{
@@ -1336,18 +1422,17 @@ inline bool Document::shouldOverrideLegacyDescription(ViewportDescription::Type
return origin >= m_legacyViewportDescription.type;
}
-inline Document* toDocument(ExecutionContext* executionContext)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!executionContext || executionContext->isDocument());
- return static_cast<Document*>(executionContext);
-}
-
-inline const Document* toDocument(const ExecutionContext* executionContext)
+inline void Document::scheduleRenderTreeUpdateIfNeeded()
{
- ASSERT_WITH_SECURITY_IMPLICATION(!executionContext || executionContext->isDocument());
- return static_cast<const Document*>(executionContext);
+ // Inline early out to avoid the function calls below.
+ if (hasPendingStyleRecalc())
+ return;
+ if (shouldScheduleRenderTreeUpdate() && needsRenderTreeUpdate())
+ scheduleRenderTreeUpdate();
}
+DEFINE_TYPE_CASTS(Document, ExecutionContextClient, client, client->isDocument(), client.isDocument());
+DEFINE_TYPE_CASTS(Document, ExecutionContext, context, context->isDocument(), context.isDocument());
DEFINE_NODE_TYPE_CASTS(Document, isDocumentNode());
#define DEFINE_DOCUMENT_TYPE_CASTS(thisType) \
@@ -1365,7 +1450,7 @@ inline bool operator!=(const Document* a, const Document& b) { return !(a == b);
inline bool Node::isDocumentNode() const
{
- return this == documentInternal();
+ return this == document();
}
Node* eventTargetNodeForDocument(Document*);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.idl b/chromium/third_party/WebKit/Source/core/dom/Document.idl
index 366966261f7..c0b3801f4d3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Document.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Document.idl
@@ -20,8 +20,10 @@
callback CustomElementConstructor = Element ();
+typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext;
+
[
- SpecialWrapFor=HTMLDocument|SVGDocument
+ SpecialWrapFor=HTMLDocument|XMLDocument
] interface Document : Node {
// DOM Level 1 Core
@@ -29,22 +31,22 @@ callback CustomElementConstructor = Element ();
readonly attribute DOMImplementation implementation;
readonly attribute Element documentElement;
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElement(DOMString tagName);
+ [CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Element createElement(DOMString tagName);
DocumentFragment createDocumentFragment();
- [PerWorldBindings] Text createTextNode(DOMString data);
+ Text createTextNode(DOMString data);
Comment createComment(DOMString data);
[RaisesException, MeasureAs=DocumentCreateCDATASection] CDATASection createCDATASection([Default=Undefined] optional DOMString data); // Removed from DOM4.
[RaisesException] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
[RaisesException, MeasureAs=DocumentCreateAttribute] Attr createAttribute([Default=Undefined] optional DOMString name); // Removed from DOM4.
- [PerWorldBindings] NodeList getElementsByTagName(DOMString localName);
+ HTMLCollection getElementsByTagName(DOMString localName);
// Introduced in DOM Level 2:
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node importNode(Node node, optional boolean deep);
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName);
- [RaisesException, MeasureAs=DocumentCreateAttributeNS] Attr createAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+ [CustomElementCallbacks, LogActivity, RaisesException] Node importNode(Node node, optional boolean deep);
+ [CustomElementCallbacks, LogActivity, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName);
+ [RaisesException, DeprecateAs=DocumentCreateAttributeNS] Attr createAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
[TreatNullAs=NullString,Default=Undefined] optional DOMString qualifiedName); // Removed from DOM4.
- NodeList getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
+ HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
[PerWorldBindings] Element getElementById(DOMString elementId);
// DOM Level 3 Core
@@ -57,7 +59,7 @@ callback CustomElementConstructor = Element ();
[RaisesException, CustomElementCallbacks] Node adoptNode(Node node);
- [TreatReturnedNullStringAs=Null] readonly attribute DOMString documentURI;
+ [TreatReturnedNullStringAs=Null, ImplementedAs=url] readonly attribute DOMString documentURI;
// DOM Level 2 Events (DocumentEvents interface)
@@ -78,7 +80,7 @@ callback CustomElementConstructor = Element ();
// DOM Level 2 Abstract Views (DocumentView interface)
- [ImplementedAs=domWindow] readonly attribute Window defaultView;
+ [ImplementedAs=executingWindow] readonly attribute Window defaultView;
// DOM Level 2 Style (DocumentStyle interface)
@@ -89,6 +91,9 @@ callback CustomElementConstructor = Element ();
CSSStyleDeclaration getOverrideStyle([Default=Undefined] optional Element element,
[Default=Undefined] optional DOMString pseudoElement);
+ // DOM 4
+ readonly attribute DOMString contentType;
+
// Common extensions
[CustomElementCallbacks]
boolean execCommand([Default=Undefined] optional DOMString command,
@@ -102,7 +107,8 @@ callback CustomElementConstructor = Element ();
DOMString queryCommandValue([Default=Undefined] optional DOMString command);
// Moved down from HTMLDocument
-
+ [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString dir;
+ [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString designMode;
[TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString title;
readonly attribute DOMString referrer;
[TreatNullAs=NullString, RaisesException=Setter] attribute DOMString domain;
@@ -110,27 +116,31 @@ callback CustomElementConstructor = Element ();
[TreatNullAs=NullString, RaisesException] attribute DOMString cookie;
- [RaisesException=Setter, CustomElementCallbacks] attribute HTMLElement body;
+ [RaisesException=Setter, CustomElementCallbacks, PerWorldBindings] attribute HTMLElement body;
readonly attribute HTMLHeadElement head;
readonly attribute HTMLCollection images;
readonly attribute HTMLCollection applets;
+ readonly attribute HTMLCollection embeds;
+ [ImplementedAs=embeds] readonly attribute HTMLCollection plugins;
readonly attribute HTMLCollection links;
readonly attribute HTMLCollection forms;
+ readonly attribute HTMLCollection scripts;
readonly attribute HTMLCollection anchors;
readonly attribute DOMString lastModified;
[PerWorldBindings] NodeList getElementsByName([Default=Undefined] optional DOMString elementName);
- [PerWorldBindings, ActivityLogging=ForIsolatedWorlds, PutForwards=href] readonly attribute Location location;
+ [LogActivity, PutForwards=href] readonly attribute Location location;
// IE extensions
[MeasureAs=DocumentCharset, TreatReturnedNullStringAs=Undefined, TreatNullAs=NullString] attribute DOMString charset;
- [MeasureAs=DocumentCharset, TreatReturnedNullStringAs=Undefined] readonly attribute DOMString defaultCharset;
+ [MeasureAs=DocumentDefaultCharset, TreatReturnedNullStringAs=Undefined] readonly attribute DOMString defaultCharset;
[TreatReturnedNullStringAs=Undefined] readonly attribute DOMString readyState;
Element elementFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
+ [MeasureAs=DocumentCaretRangeFromPoint]
Range caretRangeFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
@@ -141,23 +151,21 @@ callback CustomElementConstructor = Element ();
// WebKit extensions
[TreatReturnedNullStringAs=Null] readonly attribute DOMString preferredStylesheetSet;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;
- CanvasRenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
+ [MeasureAs=DocumentGetCSSCanvasContext] RenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
// HTML 5
- NodeList getElementsByClassName(DOMString classNames);
+ HTMLCollection getElementsByClassName(DOMString classNames);
+ readonly attribute Element activeElement;
+ boolean hasFocus();
readonly attribute DOMString compatMode;
- // NodeSelector - Selector API
- [RaisesException] Element querySelector(DOMString selectors);
- [RaisesException] NodeList querySelectorAll(DOMString selectors);
-
- void webkitExitPointerLock();
- readonly attribute Element webkitPointerLockElement;
-
- [RuntimeEnabled=CSSRegions] WebKitNamedFlowCollection webkitGetNamedFlows();
+ [MeasureAs=DocumentExitPointerLock] void exitPointerLock();
+ [MeasureAs=DocumentPointerLockElement] readonly attribute Element pointerLockElement;
+ [MeasureAs=PrefixedDocumentExitPointerLock, ImplementedAs=exitPointerLock] void webkitExitPointerLock();
+ [MeasureAs=PrefixedDocumentPointerLockElement, ImplementedAs=pointerLockElement] readonly attribute Element webkitPointerLockElement;
// Event handler attributes
attribute EventHandler onbeforecopy;
@@ -166,6 +174,8 @@ callback CustomElementConstructor = Element ();
attribute EventHandler oncopy;
attribute EventHandler oncut;
attribute EventHandler onpaste;
+ attribute EventHandler onpointerlockchange;
+ attribute EventHandler onpointerlockerror;
attribute EventHandler onreadystatechange;
attribute EventHandler onsearch;
[RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] attribute EventHandler onsecuritypolicyviolation;
@@ -179,24 +189,24 @@ callback CustomElementConstructor = Element ();
attribute EventHandler onwebkitfullscreenerror;
attribute EventHandler onwebkitpointerlockchange;
attribute EventHandler onwebkitpointerlockerror;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onwheel;
+ [LogActivity=SetterOnly] attribute EventHandler onwheel;
[RuntimeEnabled=Touch] Touch createTouch([Default=Undefined] optional Window window,
[Default=Undefined] optional EventTarget target,
[Default=Undefined] optional long identifier,
- [Default=Undefined] optional long pageX,
- [Default=Undefined] optional long pageY,
- [Default=Undefined] optional long screenX,
- [Default=Undefined] optional long screenY,
- [Default=Undefined] optional long webkitRadiusX,
- [Default=Undefined] optional long webkitRadiusY,
+ [Default=Undefined] optional double pageX,
+ [Default=Undefined] optional double pageY,
+ [Default=Undefined] optional double screenX,
+ [Default=Undefined] optional double screenY,
+ [Default=Undefined] optional double webkitRadiusX,
+ [Default=Undefined] optional double webkitRadiusY,
[Default=Undefined] optional float webkitRotationAngle,
[Default=Undefined] optional float webkitForce);
[RuntimeEnabled=Touch] TouchList createTouchList(Touch... touches);
- [RuntimeEnabled=CustomElements, CallWith=ScriptState, CustomElementCallbacks, RaisesException] CustomElementConstructor registerElement(DOMString name, optional Dictionary options);
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElement(DOMString localName, [TreatNullAs=NullString] DOMString typeExtension);
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName,
+ [CallWith=ScriptState, CustomElementCallbacks, RaisesException, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString name, optional Dictionary options);
+ [CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Element createElement(DOMString localName, [TreatNullAs=NullString] DOMString typeExtension);
+ [CustomElementCallbacks, LogActivity, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName,
[TreatNullAs=NullString] DOMString typeExtension);
// Page visibility API.
@@ -209,9 +219,6 @@ callback CustomElementConstructor = Element ();
[MeasureAs=PrefixedPageVisibility, ImplementedAs=visibilityState] readonly attribute DOMString webkitVisibilityState;
[MeasureAs=PrefixedPageVisibility, ImplementedAs=hidden] readonly attribute boolean webkitHidden;
- // Security Policy API: http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-interfaces
- [RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] readonly attribute SecurityPolicy securityPolicy;
-
readonly attribute HTMLScriptElement currentScript;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp
index fb06c70817b..23d69f5ceb4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp
@@ -29,29 +29,28 @@
*/
#include "config.h"
-#include "core/dom/NodeList.h"
+#include "core/dom/DocumentEncodingData.h"
-#include "core/dom/Node.h"
+#include "core/html/parser/TextResourceDecoder.h"
namespace WebCore {
-void NodeList::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<Node>& returnValue0, bool& returnValue1Enabled, unsigned& returnValue1)
+DocumentEncodingData::DocumentEncodingData()
+ : m_wasDetectedHeuristically(false)
+ , m_sawDecodingError(false)
{
- // Length property cannot be overridden.
- DEFINE_STATIC_LOCAL(const AtomicString, length, ("length", AtomicString::ConstructFromLiteral));
- if (name == length) {
- returnValue1Enabled = true;
- returnValue1 = this->length();
- return;
- }
-
- Node* result = namedItem(name);
- if (!result)
- return;
+}
- returnValue0Enabled = true;
- returnValue0 = result;
+DocumentEncodingData::DocumentEncodingData(const TextResourceDecoder& decoder)
+{
+ m_encoding = decoder.encoding();
+ m_wasDetectedHeuristically = decoder.encodingWasDetectedHeuristically();
+ m_sawDecodingError = decoder.sawError();
}
+void DocumentEncodingData::setEncoding(const WTF::TextEncoding& encoding)
+{
+ m_encoding = encoding;
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h
index 5a696afdd17..2016aa531ae 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h
@@ -34,19 +34,31 @@
#include "wtf/text/TextEncoding.h"
namespace WebCore {
+class TextResourceDecoder;
-struct DocumentEncodingData {
- DocumentEncodingData()
- : wasDetectedHeuristically(false)
- , sawDecodingError(false)
- {
- }
+class DocumentEncodingData {
+public:
+ DocumentEncodingData();
+ explicit DocumentEncodingData(const TextResourceDecoder&);
- WTF::TextEncoding encoding;
- bool wasDetectedHeuristically;
- bool sawDecodingError;
+ const WTF::TextEncoding& encoding() const { return m_encoding; }
+ void setEncoding(const WTF::TextEncoding&);
+ bool wasDetectedHeuristically() const { return m_wasDetectedHeuristically; }
+ bool sawDecodingError() const { return m_sawDecodingError; }
+
+private:
+ WTF::TextEncoding m_encoding;
+ bool m_wasDetectedHeuristically;
+ bool m_sawDecodingError;
};
+inline bool operator!=(const DocumentEncodingData& a, const DocumentEncodingData& b)
+{
+ return a.encoding() != b.encoding()
+ || a.wasDetectedHeuristically() != b.wasDetectedHeuristically()
+ || a.sawDecodingError() != b.sawDecodingError();
+}
+
} // namespace WebCore
#endif // DocumentEncodingData_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
index 141d571fe3f..a88cbf8a5de 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
@@ -35,9 +35,9 @@ DocumentFragment::DocumentFragment(Document* document, ConstructionType construc
ScriptWrappable::init(this);
}
-PassRefPtr<DocumentFragment> DocumentFragment::create(Document& document)
+PassRefPtrWillBeRawPtr<DocumentFragment> DocumentFragment::create(Document& document)
{
- return adoptRef(new DocumentFragment(&document, Node::CreateDocumentFragment));
+ return adoptRefWillBeNoop(new DocumentFragment(&document, Node::CreateDocumentFragment));
}
String DocumentFragment::nodeName() const
@@ -64,9 +64,9 @@ bool DocumentFragment::childTypeAllowed(NodeType type) const
}
}
-PassRefPtr<Node> DocumentFragment::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> DocumentFragment::cloneNode(bool deep)
{
- RefPtr<DocumentFragment> clone = create(document());
+ RefPtrWillBeRawPtr<DocumentFragment> clone = create(document());
if (deep)
cloneChildNodes(clone.get());
return clone.release();
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h
index 4730abcd065..a4292d41c1a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h
@@ -33,25 +33,25 @@ class ExecutionContext;
class DocumentFragment : public ContainerNode {
public:
- static PassRefPtr<DocumentFragment> create(Document&);
+ static PassRefPtrWillBeRawPtr<DocumentFragment> create(Document&);
void parseHTML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
bool parseXML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
- virtual bool canContainRangeEndPoint() const { return true; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return true; }
virtual bool isTemplateContent() const { return false; }
protected:
DocumentFragment(Document*, ConstructionType = CreateContainer);
- virtual String nodeName() const;
+ virtual String nodeName() const OVERRIDE FINAL;
private:
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
- virtual bool childTypeAllowed(NodeType) const;
+ virtual NodeType nodeType() const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
+ virtual bool childTypeAllowed(NodeType) const OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(DocumentFragment, nodeType() == Node::DOCUMENT_FRAGMENT_NODE);
+DEFINE_NODE_TYPE_CASTS(DocumentFragment, isDocumentFragment());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl
index 4f1ecf98231..005032a254e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl
@@ -21,9 +21,8 @@
Constructor,
ConstructorCallWith=Document,
] interface DocumentFragment : Node {
- // NodeSelector - Selector API
- [RaisesException] Element querySelector(DOMString selectors);
- [RaisesException] NodeList querySelectorAll(DOMString selectors);
+ // NonElementParentNode API.
+ Element getElementById(DOMString elementId);
};
DocumentFragment implements ParentNode;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp
index 407e55d3082..b1f88cdb3ce 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp
@@ -30,47 +30,47 @@
namespace WebCore {
-bool DocumentFullscreen::webkitIsFullScreen(Document* document)
+bool DocumentFullscreen::webkitIsFullScreen(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitIsFullScreen();
return false;
}
-bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document* document)
+bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitFullScreenKeyboardInputAllowed();
return false;
}
-Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document* document)
+Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitCurrentFullScreenElement();
return 0;
}
-void DocumentFullscreen::webkitCancelFullScreen(Document* document)
+void DocumentFullscreen::webkitCancelFullScreen(Document& document)
{
- FullscreenElementStack::from(document)->webkitCancelFullScreen();
+ FullscreenElementStack::from(document).webkitCancelFullScreen();
}
-bool DocumentFullscreen::webkitFullscreenEnabled(Document* document)
+bool DocumentFullscreen::webkitFullscreenEnabled(Document& document)
{
return FullscreenElementStack::webkitFullscreenEnabled(document);
}
-Element* DocumentFullscreen::webkitFullscreenElement(Document* document)
+Element* DocumentFullscreen::webkitFullscreenElement(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitFullscreenElement();
return 0;
}
-void DocumentFullscreen::webkitExitFullscreen(Document* document)
+void DocumentFullscreen::webkitExitFullscreen(Document& document)
{
- FullscreenElementStack::from(document)->webkitExitFullscreen();
+ FullscreenElementStack::from(document).webkitExitFullscreen();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h
index ff5338da300..01a5ac96cf6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h
@@ -33,14 +33,14 @@ class Element;
class DocumentFullscreen {
public:
- static bool webkitIsFullScreen(Document*);
- static bool webkitFullScreenKeyboardInputAllowed(Document*);
- static Element* webkitCurrentFullScreenElement(Document*);
- static void webkitCancelFullScreen(Document*);
+ static bool webkitIsFullScreen(Document&);
+ static bool webkitFullScreenKeyboardInputAllowed(Document&);
+ static Element* webkitCurrentFullScreenElement(Document&);
+ static void webkitCancelFullScreen(Document&);
- static bool webkitFullscreenEnabled(Document*);
- static Element* webkitFullscreenElement(Document*);
- static void webkitExitFullscreen(Document*);
+ static bool webkitFullscreenEnabled(Document&);
+ static Element* webkitFullscreenElement(Document&);
+ static void webkitExitFullscreen(Document&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl
index 561ad8018b4..65c6f80058a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl
@@ -18,15 +18,16 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
partial interface Document {
// Mozilla version
- [RuntimeEnabled=Fullscreen] readonly attribute boolean webkitIsFullScreen;
- [RuntimeEnabled=Fullscreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
- [RuntimeEnabled=Fullscreen] readonly attribute Element webkitCurrentFullScreenElement;
- [RuntimeEnabled=Fullscreen] void webkitCancelFullScreen();
+ [MeasureAs=PrefixedDocumentIsFullscreen] readonly attribute boolean webkitIsFullScreen;
+ [MeasureAs=PrefixedDocumentFullScreenKeyboardInputAllowed] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
+ [MeasureAs=PrefixedDocumentCurrentFullScreenElement] readonly attribute Element webkitCurrentFullScreenElement;
+ [MeasureAs=PrefixedDocumentCancelFullScreen] void webkitCancelFullScreen();
// W3C version
- [RuntimeEnabled=Fullscreen] readonly attribute boolean webkitFullscreenEnabled;
- [RuntimeEnabled=Fullscreen] readonly attribute Element webkitFullscreenElement;
- [RuntimeEnabled=Fullscreen] void webkitExitFullscreen();
+ [MeasureAs=PrefixedDocumentFullscreenEnabled] readonly attribute boolean webkitFullscreenEnabled;
+ [MeasureAs=PrefixedDocumentFullscreenElement] readonly attribute Element webkitFullscreenElement;
+ [MeasureAs=PrefixedDocumentExitFullscreen] void webkitExitFullscreen();
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp
index 90b4dd996f1..a71dc74a634 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp
@@ -28,27 +28,28 @@
#include "config.h"
#include "core/dom/DocumentInit.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImportsController.h"
-#include "core/frame/Frame.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-static Document* parentDocument(Frame* frame)
+// FIXME: Broken with OOPI.
+static Document* parentDocument(LocalFrame* frame)
{
if (!frame)
return 0;
- Element* ownerElement = frame->ownerElement();
+ Element* ownerElement = frame->deprecatedLocalOwner();
if (!ownerElement)
return 0;
return &ownerElement->document();
}
-static Document* ownerDocument(Frame* frame)
+static Document* ownerDocument(LocalFrame* frame)
{
if (!frame)
return 0;
@@ -56,18 +57,19 @@ static Document* ownerDocument(Frame* frame)
Frame* ownerFrame = frame->tree().parent();
if (!ownerFrame)
ownerFrame = frame->loader().opener();
- if (!ownerFrame)
+ if (!ownerFrame || !ownerFrame->isLocalFrame())
return 0;
- return ownerFrame->document();
+ return toLocalFrame(ownerFrame)->document();
}
-DocumentInit::DocumentInit(const KURL& url, Frame* frame, WeakPtr<Document> contextDocument, HTMLImport* import)
+DocumentInit::DocumentInit(const KURL& url, LocalFrame* frame, WeakPtrWillBeRawPtr<Document> contextDocument, HTMLImportsController* importsController)
: m_url(url)
, m_frame(frame)
, m_parent(parentDocument(frame))
, m_owner(ownerDocument(frame))
, m_contextDocument(contextDocument)
- , m_import(import)
+ , m_importsController(importsController)
+ , m_createNewRegistrationContext(false)
{
}
@@ -77,8 +79,9 @@ DocumentInit::DocumentInit(const DocumentInit& other)
, m_parent(other.m_parent)
, m_owner(other.m_owner)
, m_contextDocument(other.m_contextDocument)
- , m_import(other.m_import)
+ , m_importsController(other.m_importsController)
, m_registrationContext(other.m_registrationContext)
+ , m_createNewRegistrationContext(other.m_createNewRegistrationContext)
{
}
@@ -88,8 +91,8 @@ DocumentInit::~DocumentInit()
bool DocumentInit::shouldSetURL() const
{
- Frame* frame = frameForSecurityContext();
- return (frame && frame->ownerElement()) || !m_url.isEmpty();
+ LocalFrame* frame = frameForSecurityContext();
+ return (frame && frame->owner()) || !m_url.isEmpty();
}
bool DocumentInit::shouldTreatURLAsSrcdocDocument() const
@@ -97,25 +100,12 @@ bool DocumentInit::shouldTreatURLAsSrcdocDocument() const
return m_parent && m_frame->loader().shouldTreatURLAsSrcdocDocument(m_url);
}
-bool DocumentInit::isSeamlessAllowedFor(Document* child) const
-{
- if (!m_parent)
- return false;
- if (m_parent->isSandboxed(SandboxSeamlessIframes))
- return false;
- if (child->isSrcdocDocument())
- return true;
- if (m_parent->securityOrigin()->canAccess(child->securityOrigin()))
- return true;
- return m_parent->securityOrigin()->canRequest(child->url());
-}
-
-Frame* DocumentInit::frameForSecurityContext() const
+LocalFrame* DocumentInit::frameForSecurityContext() const
{
if (m_frame)
return m_frame;
- if (m_import)
- return m_import->frame();
+ if (m_importsController)
+ return m_importsController->master()->frame();
return 0;
}
@@ -138,31 +128,35 @@ KURL DocumentInit::parentBaseURL() const
DocumentInit& DocumentInit::withRegistrationContext(CustomElementRegistrationContext* registrationContext)
{
- ASSERT(!m_registrationContext);
+ ASSERT(!m_createNewRegistrationContext && !m_registrationContext);
m_registrationContext = registrationContext;
return *this;
}
-PassRefPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(Document* document) const
+DocumentInit& DocumentInit::withNewRegistrationContext()
{
- if (!RuntimeEnabledFeatures::customElementsEnabled() && !RuntimeEnabledFeatures::embedderCustomElementsEnabled())
- return 0;
+ ASSERT(!m_createNewRegistrationContext && !m_registrationContext);
+ m_createNewRegistrationContext = true;
+ return *this;
+}
+PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(Document* document) const
+{
if (!document->isHTMLDocument() && !document->isXHTMLDocument())
- return 0;
+ return nullptr;
- if (m_registrationContext)
- return m_registrationContext.get();
+ if (m_createNewRegistrationContext)
+ return CustomElementRegistrationContext::create();
- return CustomElementRegistrationContext::create();
+ return m_registrationContext.get();
}
-WeakPtr<Document> DocumentInit::contextDocument() const
+WeakPtrWillBeRawPtr<Document> DocumentInit::contextDocument() const
{
return m_contextDocument;
}
-DocumentInit DocumentInit::fromContext(WeakPtr<Document> contextDocument, const KURL& url)
+DocumentInit DocumentInit::fromContext(WeakPtrWillBeRawPtr<Document> contextDocument, const KURL& url)
{
return DocumentInit(url, 0, contextDocument, 0);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h
index 911d14f4620..3458f02678e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h
@@ -30,6 +30,7 @@
#include "core/dom/SandboxFlags.h"
#include "core/dom/SecurityContext.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -39,19 +40,20 @@ namespace WebCore {
class CustomElementRegistrationContext;
class Document;
-class Frame;
-class HTMLImport;
+class LocalFrame;
+class HTMLImportsController;
class Settings;
-class DocumentInit {
+class DocumentInit FINAL {
+ STACK_ALLOCATED();
public:
- explicit DocumentInit(const KURL& = KURL(), Frame* = 0, WeakPtr<Document> = WeakPtr<Document>(), HTMLImport* = 0);
+ explicit DocumentInit(const KURL& = KURL(), LocalFrame* = 0, WeakPtrWillBeRawPtr<Document> = nullptr, HTMLImportsController* = 0);
DocumentInit(const DocumentInit&);
~DocumentInit();
const KURL& url() const { return m_url; }
- Frame* frame() const { return m_frame; }
- HTMLImport* import() const { return m_import; }
+ LocalFrame* frame() const { return m_frame; }
+ HTMLImportsController* importsController() const { return m_importsController; }
bool hasSecurityContext() const { return frameForSecurityContext(); }
bool shouldTreatURLAsSrcdocDocument() const;
@@ -62,26 +64,27 @@ public:
Document* parent() const { return m_parent.get(); }
Document* owner() const { return m_owner.get(); }
KURL parentBaseURL() const;
- Frame* ownerFrame() const;
+ LocalFrame* ownerFrame() const;
Settings* settings() const;
DocumentInit& withRegistrationContext(CustomElementRegistrationContext*);
+ DocumentInit& withNewRegistrationContext();
+ PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
+ WeakPtrWillBeRawPtr<Document> contextDocument() const;
- PassRefPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
- WeakPtr<Document> contextDocument() const;
-
- static DocumentInit fromContext(WeakPtr<Document> contextDocument, const KURL& = KURL());
+ static DocumentInit fromContext(WeakPtrWillBeRawPtr<Document> contextDocument, const KURL& = KURL());
private:
- Frame* frameForSecurityContext() const;
+ LocalFrame* frameForSecurityContext() const;
KURL m_url;
- Frame* m_frame;
- RefPtr<Document> m_parent;
- RefPtr<Document> m_owner;
- WeakPtr<Document> m_contextDocument;
- HTMLImport* m_import;
- RefPtr<CustomElementRegistrationContext> m_registrationContext;
+ LocalFrame* m_frame;
+ RefPtrWillBeMember<Document> m_parent;
+ RefPtrWillBeMember<Document> m_owner;
+ WeakPtrWillBeMember<Document> m_contextDocument;
+ RawPtrWillBeMember<HTMLImportsController> m_importsController;
+ RefPtrWillBeMember<CustomElementRegistrationContext> m_registrationContext;
+ bool m_createNewRegistrationContext;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp
index 157548f32b0..c7e2615062a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp
@@ -35,8 +35,35 @@
namespace WebCore {
+static DocumentLifecycle::DeprecatedTransition* s_deprecatedTransitionStack = 0;
+
+DocumentLifecycle::Scope::Scope(DocumentLifecycle& lifecycle, State finalState)
+ : m_lifecycle(lifecycle)
+ , m_finalState(finalState)
+{
+}
+
+DocumentLifecycle::Scope::~Scope()
+{
+ m_lifecycle.advanceTo(m_finalState);
+}
+
+DocumentLifecycle::DeprecatedTransition::DeprecatedTransition(State from, State to)
+ : m_previous(s_deprecatedTransitionStack)
+ , m_from(from)
+ , m_to(to)
+{
+ s_deprecatedTransitionStack = this;
+}
+
+DocumentLifecycle::DeprecatedTransition::~DeprecatedTransition()
+{
+ s_deprecatedTransitionStack = m_previous;
+}
+
DocumentLifecycle::DocumentLifecycle()
: m_state(Uninitialized)
+ , m_detachCount(0)
{
}
@@ -44,11 +71,96 @@ DocumentLifecycle::~DocumentLifecycle()
{
}
+#if ASSERT_ENABLED
+
+bool DocumentLifecycle::canAdvanceTo(State state) const
+{
+ if (state > m_state)
+ return true;
+ if (m_state == Disposed) {
+ // FIXME: We can dispose a document multiple times. This seems wrong.
+ // See https://code.google.com/p/chromium/issues/detail?id=301668.
+ return state == Disposed;
+ }
+ if (m_state == StyleClean) {
+ // We can synchronously recalc style.
+ if (state == InStyleRecalc)
+ return true;
+ // We can synchronously perform layout.
+ if (state == InPreLayout)
+ return true;
+ if (state == InPerformLayout)
+ return true;
+ // We can redundant arrive in the style clean state.
+ if (state == StyleClean)
+ return true;
+ return false;
+ }
+ if (m_state == InPreLayout) {
+ if (state == InStyleRecalc)
+ return true;
+ if (state == StyleClean)
+ return true;
+ if (state == InPreLayout)
+ return true;
+ return false;
+ }
+ if (m_state == AfterPerformLayout) {
+ // We can synchronously recompute layout in AfterPerformLayout.
+ // FIXME: Ideally, we would unnest this recursion into a loop.
+ return state == InPreLayout;
+ }
+ if (m_state == LayoutClean) {
+ // We can synchronously recalc style.
+ if (state == InStyleRecalc)
+ return true;
+ // We can synchronously perform layout.
+ if (state == InPreLayout)
+ return true;
+ if (state == InPerformLayout)
+ return true;
+ // We can redundant arrive in the layout clean state. This situation
+ // can happen when we call layout recursively and we unwind the stack.
+ if (state == LayoutClean)
+ return true;
+ if (state == StyleClean)
+ return true;
+ return false;
+ }
+ if (m_state == CompositingClean) {
+ if (state == InStyleRecalc)
+ return true;
+ if (state == InPreLayout)
+ return true;
+ if (state == InCompositingUpdate)
+ return true;
+ return false;
+ }
+ return false;
+}
+
+bool DocumentLifecycle::canRewindTo(State state) const
+{
+ // This transition is bogus, but we've whitelisted it anyway.
+ if (s_deprecatedTransitionStack && m_state == s_deprecatedTransitionStack->from() && state == s_deprecatedTransitionStack->to())
+ return true;
+ return m_state == StyleClean || m_state == AfterPerformLayout || m_state == LayoutClean || m_state == CompositingClean;
+}
+
+#endif
+
void DocumentLifecycle::advanceTo(State state)
{
- // FIXME: We can dispose a document multiple times. This seems wrong.
- // See https://code.google.com/p/chromium/issues/detail?id=301668.
- ASSERT(state > m_state || (state == Disposed && m_state == Disposed));
+ ASSERT(canAdvanceTo(state));
+ m_state = state;
+}
+
+void DocumentLifecycle::ensureStateAtMost(State state)
+{
+ ASSERT(state == VisualUpdatePending || state == StyleClean || state == LayoutClean);
+ if (m_state <= state)
+ return;
+ ASSERT(canRewindTo(state));
m_state = state;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h
index c3f919635e8..449ed15b533 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h
@@ -31,6 +31,7 @@
#ifndef DocumentLifecycle_h
#define DocumentLifecycle_h
+#include "wtf/Assertions.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
@@ -41,23 +42,130 @@ public:
enum State {
Uninitialized,
Inactive,
- Active,
+
+ // When the document is active, it traverses these states.
+
+ VisualUpdatePending,
+
+ InStyleRecalc,
+ StyleClean,
+
+ InPreLayout,
+ InPerformLayout,
+ AfterPerformLayout,
+ LayoutClean,
+
+ InCompositingUpdate,
+ CompositingClean,
+
+ // Once the document starts shuting down, we cannot return
+ // to the style/layout/rendering states.
Stopping,
Stopped,
Disposed,
};
+ class Scope {
+ WTF_MAKE_NONCOPYABLE(Scope);
+ public:
+ Scope(DocumentLifecycle&, State finalState);
+ ~Scope();
+
+ void setFinalState(State finalState) { m_finalState = finalState; }
+
+ private:
+ DocumentLifecycle& m_lifecycle;
+ State m_finalState;
+ };
+
+ class DeprecatedTransition {
+ WTF_MAKE_NONCOPYABLE(DeprecatedTransition);
+ public:
+ DeprecatedTransition(State from, State to);
+ ~DeprecatedTransition();
+
+ State from() const { return m_from; }
+ State to() const { return m_to; }
+
+ private:
+ DeprecatedTransition* m_previous;
+ State m_from;
+ State m_to;
+ };
+
+ class DetachScope {
+ WTF_MAKE_NONCOPYABLE(DetachScope);
+ public:
+ explicit DetachScope(DocumentLifecycle& documentLifecycle)
+ : m_documentLifecycle(documentLifecycle)
+ {
+ m_documentLifecycle.incrementDetachCount();
+ }
+
+ ~DetachScope()
+ {
+ m_documentLifecycle.decrementDetachCount();
+ }
+
+ private:
+ DocumentLifecycle& m_documentLifecycle;
+ };
+
DocumentLifecycle();
~DocumentLifecycle();
+ bool isActive() const { return m_state > Inactive && m_state < Stopping; }
State state() const { return m_state; }
+ bool stateAllowsTreeMutations() const;
+ bool stateAllowsRenderTreeMutations() const;
+ bool stateAllowsDetach() const;
+
void advanceTo(State);
+ void ensureStateAtMost(State);
+
+ void incrementDetachCount() { m_detachCount++; }
+ void decrementDetachCount()
+ {
+ ASSERT(m_detachCount > 0);
+ m_detachCount--;
+ }
private:
+#if ASSERT_ENABLED
+ bool canAdvanceTo(State) const;
+ bool canRewindTo(State) const;
+#endif
+
State m_state;
+ int m_detachCount;
};
+inline bool DocumentLifecycle::stateAllowsTreeMutations() const
+{
+ // FIXME: We should not allow mutations in InPreLayout or AfterPerformLayout either,
+ // but we need to fix MediaList listeners and plugins first.
+ return m_state != InStyleRecalc
+ && m_state != InPerformLayout
+ && m_state != InCompositingUpdate;
+}
+
+inline bool DocumentLifecycle::stateAllowsRenderTreeMutations() const
+{
+ return m_detachCount || m_state == InStyleRecalc;
+}
+
+inline bool DocumentLifecycle::stateAllowsDetach() const
+{
+ return m_state == VisualUpdatePending
+ || m_state == InStyleRecalc
+ || m_state == StyleClean
+ || m_state == InPreLayout
+ || m_state == LayoutClean
+ || m_state == CompositingClean
+ || m_state == Stopping;
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h
index 07888bd1b74..7e7b062f768 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h
@@ -39,10 +39,12 @@ public:
static PassOwnPtr<DocumentLifecycleNotifier> create(Document*);
void notifyDocumentWasDetached();
+#if !ENABLE(OILPAN)
void notifyDocumentWasDisposed();
+#endif
- virtual void addObserver(Observer*) OVERRIDE;
- virtual void removeObserver(Observer*) OVERRIDE;
+ virtual void addObserver(Observer*) OVERRIDE FINAL;
+ virtual void removeObserver(Observer*) OVERRIDE FINAL;
private:
explicit DocumentLifecycleNotifier(Document*);
@@ -63,12 +65,14 @@ inline void DocumentLifecycleNotifier::notifyDocumentWasDetached()
(*i)->documentWasDetached();
}
+#if !ENABLE(OILPAN)
inline void DocumentLifecycleNotifier::notifyDocumentWasDisposed()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverDocumentObservers);
for (DocumentObserverSet::iterator i = m_documentObservers.begin(); i != m_documentObservers.end(); ++i)
(*i)->documentWasDisposed();
}
+#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h
index 47233c51a72..02d18a1d26e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h
@@ -40,7 +40,9 @@ public:
explicit DocumentLifecycleObserver(Document*);
virtual ~DocumentLifecycleObserver();
virtual void documentWasDetached() { }
+#if !ENABLE(OILPAN)
virtual void documentWasDisposed() { }
+#endif
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp
index 12b903937f6..a37e522286a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp
@@ -37,12 +37,12 @@ DocumentMarkerDetails::~DocumentMarkerDetails()
{
}
-class DocumentMarkerDescription : public DocumentMarkerDetails {
+class DocumentMarkerDescription FINAL : public DocumentMarkerDetails {
public:
static PassRefPtr<DocumentMarkerDescription> create(const String&);
const String& description() const { return m_description; }
- virtual bool isDescription() const { return true; }
+ virtual bool isDescription() const OVERRIDE { return true; }
private:
DocumentMarkerDescription(const String& description)
@@ -66,12 +66,12 @@ inline DocumentMarkerDescription* toDocumentMarkerDescription(DocumentMarkerDeta
}
-class DocumentMarkerTextMatch : public DocumentMarkerDetails {
+class DocumentMarkerTextMatch FINAL : public DocumentMarkerDetails {
public:
static PassRefPtr<DocumentMarkerTextMatch> instanceFor(bool);
bool activeMatch() const { return m_match; }
- virtual bool isTextMatch() const { return true; }
+ virtual bool isTextMatch() const OVERRIDE { return true; }
private:
explicit DocumentMarkerTextMatch(bool match)
@@ -117,7 +117,7 @@ DocumentMarker::DocumentMarker(MarkerType type, unsigned startOffset, unsigned e
: m_type(type)
, m_startOffset(startOffset)
, m_endOffset(endOffset)
- , m_details(description.isEmpty() ? 0 : DocumentMarkerDescription::create(description))
+ , m_details(description.isEmpty() ? nullptr : DocumentMarkerDescription::create(description))
, m_hash(0)
{
}
@@ -126,7 +126,7 @@ DocumentMarker::DocumentMarker(MarkerType type, unsigned startOffset, unsigned e
: m_type(type)
, m_startOffset(startOffset)
, m_endOffset(endOffset)
- , m_details(description.isEmpty() ? 0 : DocumentMarkerDescription::create(description))
+ , m_details(description.isEmpty() ? nullptr : DocumentMarkerDescription::create(description))
, m_hash(hash)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h
index ded6b9d1c79..bed144af853 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h
@@ -23,9 +23,7 @@
#ifndef DocumentMarker_h
#define DocumentMarker_h
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
+#include "wtf/VectorTraits.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -152,4 +150,11 @@ public:
} // namespace WebCore
+namespace WTF {
+
+template<>
+struct VectorTraits<WebCore::DocumentMarker> : SimpleClassVectorTraits<WebCore::DocumentMarker> { };
+
+} // namespace WTF
+
#endif // DocumentMarker_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp
index ef4fa8220e6..c115627d87f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp
@@ -71,9 +71,7 @@ DocumentMarkerController::DocumentMarkerController()
{
}
-DocumentMarkerController::~DocumentMarkerController()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentMarkerController);
void DocumentMarkerController::clear()
{
@@ -85,7 +83,7 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description, hash));
}
}
@@ -94,7 +92,7 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description));
}
}
@@ -103,28 +101,17 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset()));
}
}
-void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type)
-{
- addMarker(node, DocumentMarker(type, startOffset, startOffset + length));
-}
-
-void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type, PassRefPtr<DocumentMarkerDetails> details)
-{
- addMarker(node, DocumentMarker(type, startOffset, startOffset + length, details));
-}
-
-
void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch)
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
unsigned startOffset = textPiece->startOffset();
unsigned endOffset = textPiece->endOffset();
addMarker(textPiece->startContainer(), DocumentMarker(startOffset, endOffset, activeMatch));
@@ -134,7 +121,7 @@ void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activ
// the whole purpose of tickmarks on the scrollbar is to show where
// matches off-screen are (that haven't been painted yet).
Node* node = textPiece->startContainer();
- Vector<DocumentMarker*> markers = markersFor(node);
+ WillBeHeapVector<DocumentMarker*> markers = markersFor(node);
toRenderedDocumentMarker(markers[markers.size() - 1])->setRenderedRect(range->boundingBox());
}
}
@@ -152,7 +139,7 @@ void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::Marke
return;
ASSERT(!m_markers.isEmpty());
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
int startOffset = textPiece->startOffset();
int endOffset = textPiece->endOffset();
removeMarkers(textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker);
@@ -200,18 +187,18 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa
m_possiblyExistingMarkerTypes.add(newMarker.type());
- OwnPtr<MarkerLists>& markers = m_markers.add(node, nullptr).iterator->value;
+ OwnPtrWillBeMember<MarkerLists>& markers = m_markers.add(node, nullptr).storedValue->value;
if (!markers) {
- markers = adoptPtr(new MarkerLists);
+ markers = adoptPtrWillBeNoop(new MarkerLists);
markers->grow(DocumentMarker::MarkerTypeIndexesCount);
}
DocumentMarker::MarkerTypeIndex markerListIndex = MarkerTypeToMarkerIndex(newMarker.type());
if (!markers->at(markerListIndex)) {
- markers->insert(markerListIndex, adoptPtr(new MarkerList));
+ markers->insert(markerListIndex, adoptPtrWillBeNoop(new MarkerList));
}
- OwnPtr<MarkerList>& list = markers->at(markerListIndex);
+ OwnPtrWillBeMember<MarkerList>& list = markers->at(markerListIndex);
if (list->isEmpty() || list->last().endOffset() < newMarker.startOffset()) {
list->append(RenderedDocumentMarker(newMarker));
} else {
@@ -226,7 +213,7 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa
// repaint the affected node
if (node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
void DocumentMarkerController::mergeOverlapping(MarkerList* list, DocumentMarker& toInsert)
@@ -260,7 +247,7 @@ void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset,
bool docDirty = false;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list)
continue;
@@ -287,7 +274,7 @@ void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset,
// repaint the affected node
if (docDirty && dstNode->renderer())
- dstNode->renderer()->repaint();
+ dstNode->renderer()->paintInvalidationForWholeRenderer();
}
void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
@@ -306,7 +293,7 @@ void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, i
bool docDirty = false;
size_t emptyListsCount = 0;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty()) {
if (list.get() && list->isEmpty())
list.clear();
@@ -368,7 +355,7 @@ void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, i
// repaint the affected node
if (docDirty && node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType)
@@ -382,7 +369,7 @@ DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoin
for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
// inner loop; process each marker in this node
MarkerLists* markers = nodeIterator->value.get();
- OwnPtr<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)];
unsigned markerCount = list.get() ? list->size() : 0;
for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
RenderedDocumentMarker& marker = list->at(markerIndex);
@@ -395,16 +382,16 @@ DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoin
return 0;
}
-Vector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
+WillBeHeapVector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
{
- Vector<DocumentMarker*> result;
+ WillBeHeapVector<DocumentMarker*> result;
MarkerLists* markers = m_markers.get(node);
if (!markers)
return result;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty() || !markerTypes.contains(list->begin()->type()))
continue;
@@ -416,13 +403,13 @@ Vector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, Documen
return result;
}
-Vector<DocumentMarker*> DocumentMarkerController::markers()
+WillBeHeapVector<DocumentMarker*> DocumentMarkerController::markers()
{
- Vector<DocumentMarker*> result;
+ WillBeHeapVector<DocumentMarker*> result;
for (MarkerMap::iterator i = m_markers.begin(); i != m_markers.end(); ++i) {
MarkerLists* markers = i->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
for (size_t j = 0; list.get() && j < list->size(); ++j)
result.append(&(list->at(j)));
}
@@ -431,12 +418,12 @@ Vector<DocumentMarker*> DocumentMarkerController::markers()
return result;
}
-Vector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes)
+WillBeHeapVector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes)
{
if (!possiblyHasMarkers(markerTypes))
- return Vector<DocumentMarker*>();
+ return WillBeHeapVector<DocumentMarker*>();
- Vector<DocumentMarker*> foundMarkers;
+ WillBeHeapVector<DocumentMarker*> foundMarkers;
Node* startContainer = range->startContainer();
ASSERT(startContainer);
@@ -445,9 +432,9 @@ Vector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, D
Node* pastLastNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
- Vector<DocumentMarker*> markers = markersFor(node);
- Vector<DocumentMarker*>::const_iterator end = markers.end();
- for (Vector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
+ WillBeHeapVector<DocumentMarker*> markers = markersFor(node);
+ WillBeHeapVector<DocumentMarker*>::const_iterator end = markers.end();
+ for (WillBeHeapVector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
DocumentMarker* marker = *it;
if (!markerTypes.contains(marker->type()))
continue;
@@ -475,7 +462,7 @@ Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker
// inner loop; process each marker in this node
MarkerLists* markers = nodeIterator->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty() || list->begin()->type() != markerType)
continue;
for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) {
@@ -492,6 +479,11 @@ Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker
return result;
}
+void DocumentMarkerController::trace(Visitor* visitor)
+{
+ visitor->trace(m_markers);
+}
+
void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerTypes markerTypes)
{
if (!possiblyHasMarkers(markerTypes))
@@ -534,7 +526,7 @@ void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterato
MarkerLists* markers = iterator->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty()) {
if (list.get() && list->isEmpty())
list.clear();
@@ -554,7 +546,7 @@ void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterato
if (needsRepainting) {
if (RenderObject* renderer = iterator->key->renderer())
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
}
if (nodeCanBeRemoved) {
@@ -578,13 +570,13 @@ void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes marker
// inner loop: process each marker in the current node
MarkerLists* markers = i->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty() || !markerTypes.contains(list->begin()->type()))
continue;
// cause the node to be redrawn
if (RenderObject* renderer = node->renderer()) {
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
break;
}
}
@@ -600,7 +592,7 @@ void DocumentMarkerController::invalidateRenderedRectsForMarkersInRect(const Lay
// inner loop: process each rect in the current node
MarkerLists* markers = i->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
for (size_t markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex)
list->at(markerIndex).invalidate(r);
}
@@ -619,7 +611,7 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in
bool docDirty = false;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list)
continue;
MarkerList::iterator startPos = std::lower_bound(list->begin(), list->end(), startOffset, startsAfter);
@@ -635,7 +627,7 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in
// repaint the affected node
if (docDirty && node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
void DocumentMarkerController::setMarkersActive(Range* range, bool active)
@@ -663,7 +655,7 @@ void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset
return;
bool docDirty = false;
- OwnPtr<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::TextMatch)];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::TextMatch)];
if (!list)
return;
MarkerList::iterator startPos = std::upper_bound(list->begin(), list->end(), startOffset, endsBefore);
@@ -679,7 +671,7 @@ void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset
// repaint the affected node
if (docDirty && node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes)
@@ -695,9 +687,9 @@ bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTy
Node* pastLastNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
- Vector<DocumentMarker*> markers = markersFor(node);
- Vector<DocumentMarker*>::const_iterator end = markers.end();
- for (Vector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
+ WillBeHeapVector<DocumentMarker*> markers = markersFor(node);
+ WillBeHeapVector<DocumentMarker*>::const_iterator end = markers.end();
+ for (WillBeHeapVector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
DocumentMarker* marker = *it;
if (!markerTypes.contains(marker->type()))
continue;
@@ -721,7 +713,7 @@ void DocumentMarkerController::showMarkers() const
fprintf(stderr, "%p", node);
MarkerLists* markers = m_markers.get(node);
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
for (unsigned markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex) {
const DocumentMarker& marker = list->at(markerIndex);
fprintf(stderr, " %d:[%d:%d](%d)", marker.type(), marker.startOffset(), marker.endOffset(), marker.activeMatch());
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h
index a3b023f7d4c..01093354ce1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h
@@ -29,6 +29,7 @@
#include "core/dom/DocumentMarker.h"
#include "platform/geometry/IntRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
@@ -41,19 +42,17 @@ class Node;
class Range;
class RenderedDocumentMarker;
-class DocumentMarkerController {
- WTF_MAKE_NONCOPYABLE(DocumentMarkerController); WTF_MAKE_FAST_ALLOCATED;
+class DocumentMarkerController FINAL : public NoBaseWillBeGarbageCollected<DocumentMarkerController> {
+ WTF_MAKE_NONCOPYABLE(DocumentMarkerController); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentMarkerController);
public:
DocumentMarkerController();
- ~DocumentMarkerController();
void clear();
void addMarker(Range*, DocumentMarker::MarkerType);
void addMarker(Range*, DocumentMarker::MarkerType, const String& description);
void addMarker(Range*, DocumentMarker::MarkerType, const String& description, uint32_t hash);
- void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType);
- void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType, PassRefPtr<DocumentMarkerDetails>);
void addTextMatchMarker(const Range*, bool activeMatch);
void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta);
@@ -76,11 +75,13 @@ public:
void setMarkersActive(Node*, unsigned startOffset, unsigned endOffset, bool);
DocumentMarker* markerContainingPoint(const LayoutPoint&, DocumentMarker::MarkerType);
- Vector<DocumentMarker*> markersFor(Node*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
- Vector<DocumentMarker*> markersInRange(Range*, DocumentMarker::MarkerTypes);
- Vector<DocumentMarker*> markers();
+ WillBeHeapVector<DocumentMarker*> markersFor(Node*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
+ WillBeHeapVector<DocumentMarker*> markersInRange(Range*, DocumentMarker::MarkerTypes);
+ WillBeHeapVector<DocumentMarker*> markers();
Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType);
+ void trace(Visitor*);
+
#ifndef NDEBUG
void showMarkers() const;
#endif
@@ -88,9 +89,9 @@ public:
private:
void addMarker(Node*, const DocumentMarker&);
- typedef Vector<RenderedDocumentMarker> MarkerList;
- typedef Vector<OwnPtr<MarkerList>, DocumentMarker::MarkerTypeIndexesCount> MarkerLists;
- typedef HashMap<const Node*, OwnPtr<MarkerLists> > MarkerMap;
+ typedef WillBeHeapVector<RenderedDocumentMarker> MarkerList;
+ typedef WillBeHeapVector<OwnPtrWillBeMember<MarkerList>, DocumentMarker::MarkerTypeIndexesCount> MarkerLists;
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<const Node>, OwnPtrWillBeMember<MarkerLists> > MarkerMap;
void mergeOverlapping(MarkerList*, DocumentMarker&);
bool possiblyHasMarkers(DocumentMarker::MarkerTypes);
void removeMarkersFromList(MarkerMap::iterator, DocumentMarker::MarkerTypes);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp
index f7132ed5527..62a4d58cdd5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp
@@ -51,10 +51,10 @@ protected:
virtual void SetUp() OVERRIDE;
Document& document() const { return *m_document; }
- DocumentMarkerController& markerController() const { return *m_document->markers(); }
+ DocumentMarkerController& markerController() const { return m_document->markers(); }
- PassRefPtr<Text> createTextNode(const char*);
- void markNodeContents(PassRefPtr<Node>);
+ PassRefPtrWillBeRawPtr<Text> createTextNode(const char*);
+ void markNodeContents(PassRefPtrWillBeRawPtr<Node>);
void setBodyInnerHTML(const char*);
private:
@@ -69,17 +69,17 @@ void DocumentMarkerControllerTest::SetUp()
ASSERT(m_document);
}
-PassRefPtr<Text> DocumentMarkerControllerTest::createTextNode(const char* textContents)
+PassRefPtrWillBeRawPtr<Text> DocumentMarkerControllerTest::createTextNode(const char* textContents)
{
return document().createTextNode(String::fromUTF8(textContents));
}
-void DocumentMarkerControllerTest::markNodeContents(PassRefPtr<Node> node)
+void DocumentMarkerControllerTest::markNodeContents(PassRefPtrWillBeRawPtr<Node> node)
{
// Force renderers to be created; TextIterator, which is used in
// DocumentMarkerControllerTest::addMarker(), needs them.
document().updateLayout();
- RefPtr<Range> range = rangeOfContents(node.get());
+ RefPtrWillBeRawPtr<Range> range = rangeOfContents(node.get());
markerController().addMarker(range.get(), DocumentMarker::Spelling);
}
@@ -88,28 +88,45 @@ void DocumentMarkerControllerTest::setBodyInnerHTML(const char* bodyContent)
document().body()->setInnerHTML(String::fromUTF8(bodyContent), ASSERT_NO_EXCEPTION);
}
+TEST_F(DocumentMarkerControllerTest, DidMoveToNewDocument)
+{
+ setBodyInnerHTML("<b><i>foo</i></b>");
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ markNodeContents(parent.get());
+ EXPECT_EQ(1u, markerController().markers().size());
+ RefPtrWillBePersistent<Document> anotherDocument = Document::create();
+ anotherDocument->adoptNode(parent.get(), ASSERT_NO_EXCEPTION);
+
+ // No more reference to marked node.
+ Heap::collectAllGarbage();
+ EXPECT_EQ(0u, markerController().markers().size());
+ EXPECT_EQ(0u, anotherDocument->markers().markers().size());
+}
+
TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByNormalize)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
parent->appendChild(createTextNode("bar").get());
markNodeContents(parent.get());
EXPECT_EQ(2u, markerController().markers().size());
parent->normalize();
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(1u, markerController().markers().size());
}
TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveChildren)
{
setBodyInnerHTML("<b><i>foo</i></b>");
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent.get());
EXPECT_EQ(1u, markerController().markers().size());
parent->removeChildren();
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -117,12 +134,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedByRemoveMarked)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
parent->removeChild(parent->firstChild());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -130,12 +148,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveAncestor)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
parent->parentNode()->parentNode()->removeChild(parent->parentNode());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -143,12 +162,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveParent)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
parent->parentNode()->removeChild(parent.get());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -156,12 +176,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByReplaceChild)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent.get());
EXPECT_EQ(1u, markerController().markers().size());
parent->replaceChild(createTextNode("bar").get(), parent->firstChild());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -169,12 +190,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedBySetInnerHTML)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
setBodyInnerHTML("");
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h
index 133a34df77f..37b43850ba3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h
@@ -45,6 +45,7 @@ public:
void remove(const Node*);
bool isEmpty() const { return m_nodes.isEmpty(); }
void clear() { m_nodes.clear(); }
+ size_t size() const { return m_nodes.size(); }
typedef ListHashSet<Node*, 32>::iterator iterator;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
index 494d266768f..b75d1823a0c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
@@ -31,41 +31,34 @@
#include "config.h"
#include "core/dom/DocumentOrderedMap.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/TreeScope.h"
-#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLMapElement.h"
namespace WebCore {
using namespace HTMLNames;
-inline bool keyMatchesId(StringImpl* key, Element* element)
+inline bool keyMatchesId(StringImpl* key, Element& element)
{
- return element->getIdAttribute().impl() == key;
+ return element.getIdAttribute().impl() == key;
}
-inline bool keyMatchesMapName(StringImpl* key, Element* element)
+inline bool keyMatchesMapName(StringImpl* key, Element& element)
{
- return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().impl() == key;
+ return isHTMLMapElement(element) && toHTMLMapElement(element).getName().impl() == key;
}
-inline bool keyMatchesLowercasedMapName(StringImpl* key, Element* element)
+inline bool keyMatchesLowercasedMapName(StringImpl* key, Element& element)
{
- return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().lower().impl() == key;
+ return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lower().impl() == key;
}
-inline bool keyMatchesLabelForAttribute(StringImpl* key, Element* element)
+inline bool keyMatchesLabelForAttribute(StringImpl* key, Element& element)
{
- return isHTMLLabelElement(element) && element->getAttribute(forAttr).impl() == key;
-}
-
-void DocumentOrderedMap::clear()
-{
- m_map.clear();
- m_duplicateCounts.clear();
+ return isHTMLLabelElement(element) && element.getAttribute(forAttr).impl() == key;
}
void DocumentOrderedMap::add(StringImpl* key, Element* element)
@@ -73,29 +66,15 @@ void DocumentOrderedMap::add(StringImpl* key, Element* element)
ASSERT(key);
ASSERT(element);
- if (!m_duplicateCounts.contains(key)) {
- // Fast path. The key is not already in m_duplicateCounts, so we assume that it's
- // also not already in m_map and try to add it. If that add succeeds, we're done.
- Map::AddResult addResult = m_map.add(key, element);
- if (addResult.isNewEntry)
- return;
-
- // The add failed, so this key was already cached in m_map.
- // There are multiple elements with this key. Remove the m_map
- // cache for this key so get searches for it next time it is called.
- m_map.remove(addResult.iterator);
- m_duplicateCounts.add(key);
- } else {
- // There are multiple elements with this key. Remove the m_map
- // cache for this key so get will search for it next time it is called.
- Map::iterator cachedItem = m_map.find(key);
- if (cachedItem != m_map.end()) {
- m_map.remove(cachedItem);
- m_duplicateCounts.add(key);
- }
- }
+ Map::AddResult addResult = m_map.add(key, adoptPtr(new MapEntry(element)));
+ if (addResult.isNewEntry)
+ return;
- m_duplicateCounts.add(key);
+ OwnPtr<MapEntry>& entry = addResult.storedValue->value;
+ ASSERT(entry->count);
+ entry->element = 0;
+ entry->count++;
+ entry->orderedList.clear();
}
void DocumentOrderedMap::remove(StringImpl* key, Element* element)
@@ -103,36 +82,47 @@ void DocumentOrderedMap::remove(StringImpl* key, Element* element)
ASSERT(key);
ASSERT(element);
- Map::iterator cachedItem = m_map.find(key);
- if (cachedItem != m_map.end() && cachedItem->value == element)
- m_map.remove(cachedItem);
- else
- m_duplicateCounts.remove(key);
+ Map::iterator it = m_map.find(key);
+ if (it == m_map.end())
+ return;
+
+ OwnPtr<MapEntry>& entry = it->value;
+ ASSERT(entry->count);
+ if (entry->count == 1) {
+ ASSERT(!entry->element || entry->element == element);
+ m_map.remove(it);
+ } else {
+ if (entry->element == element) {
+ ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element);
+ entry->element = entry->orderedList.size() > 1 ? entry->orderedList[1] : 0;
+ }
+ entry->count--;
+ entry->orderedList.clear();
+ }
}
-template<bool keyMatches(StringImpl*, Element*)>
+template<bool keyMatches(StringImpl*, Element&)>
inline Element* DocumentOrderedMap::get(StringImpl* key, const TreeScope* scope) const
{
ASSERT(key);
ASSERT(scope);
- Element* element = m_map.get(key);
- if (element)
- return element;
+ MapEntry* entry = m_map.get(key);
+ if (!entry)
+ return 0;
- if (m_duplicateCounts.contains(key)) {
- // We know there's at least one node that matches; iterate to find the first one.
- ASSERT(scope->rootNode());
- for (element = ElementTraversal::firstWithin(*scope->rootNode()); element; element = ElementTraversal::next(*element)) {
- if (!keyMatches(key, element))
- continue;
- m_duplicateCounts.remove(key);
- m_map.set(key, element);
- return element;
- }
- ASSERT_NOT_REACHED();
- }
+ ASSERT(entry->count);
+ if (entry->element)
+ return entry->element;
+ // We know there's at least one node that matches; iterate to find the first one.
+ for (Element* element = ElementTraversal::firstWithin(scope->rootNode()); element; element = ElementTraversal::next(*element)) {
+ if (!keyMatches(key, *element))
+ continue;
+ entry->element = element;
+ return element;
+ }
+ ASSERT_NOT_REACHED();
return 0;
}
@@ -141,6 +131,34 @@ Element* DocumentOrderedMap::getElementById(StringImpl* key, const TreeScope* sc
return get<keyMatchesId>(key, scope);
}
+const Vector<Element*>& DocumentOrderedMap::getAllElementsById(StringImpl* key, const TreeScope* scope) const
+{
+ ASSERT(key);
+ ASSERT(scope);
+ DEFINE_STATIC_LOCAL(Vector<Element*>, emptyVector, ());
+
+ Map::iterator it = m_map.find(key);
+ if (it == m_map.end())
+ return emptyVector;
+
+ OwnPtr<MapEntry>& entry = it->value;
+ ASSERT(entry->count);
+
+ if (entry->orderedList.isEmpty()) {
+ entry->orderedList.reserveCapacity(entry->count);
+ for (Element* element = entry->element ? entry->element : ElementTraversal::firstWithin(scope->rootNode()); entry->orderedList.size() < entry->count; element = ElementTraversal::next(*element)) {
+ ASSERT(element);
+ if (!keyMatchesId(key, *element))
+ continue;
+ entry->orderedList.uncheckedAppend(element);
+ }
+ if (!entry->element)
+ entry->element = entry->orderedList.first();
+ }
+
+ return entry->orderedList;
+}
+
Element* DocumentOrderedMap::getElementByMapName(StringImpl* key, const TreeScope* scope) const
{
return get<keyMatchesMapName>(key, scope);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
index b6fc8e07e0d..e5158ee1715 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
@@ -31,7 +31,7 @@
#ifndef DocumentOrderedMap_h
#define DocumentOrderedMap_h
-#include "wtf/HashCountedSet.h"
+#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/text/StringImpl.h"
@@ -44,38 +44,44 @@ class DocumentOrderedMap {
public:
void add(StringImpl*, Element*);
void remove(StringImpl*, Element*);
- void clear();
bool contains(StringImpl*) const;
bool containsMultiple(StringImpl*) const;
// concrete instantiations of the get<>() method template
Element* getElementById(StringImpl*, const TreeScope*) const;
+ const Vector<Element*>& getAllElementsById(StringImpl*, const TreeScope*) const;
Element* getElementByMapName(StringImpl*, const TreeScope*) const;
Element* getElementByLowercasedMapName(StringImpl*, const TreeScope*) const;
Element* getElementByLabelForAttribute(StringImpl*, const TreeScope*) const;
- void checkConsistency() const;
-
private:
- template<bool keyMatches(StringImpl*, Element*)> Element* get(StringImpl*, const TreeScope*) const;
+ template<bool keyMatches(StringImpl*, Element&)> Element* get(StringImpl*, const TreeScope*) const;
+
+ struct MapEntry {
+ explicit MapEntry(Element* firstElement)
+ : element(firstElement)
+ , count(1)
+ { }
+
+ Element* element;
+ unsigned count;
+ Vector<Element*> orderedList;
+ };
- typedef HashMap<StringImpl*, Element*> Map;
+ typedef HashMap<StringImpl*, OwnPtr<MapEntry> > Map;
- // We maintain the invariant that m_duplicateCounts is the count of all elements with a given key
- // excluding the one referenced in m_map, if any. This means it one less than the total count
- // when the first node with a given key is cached, otherwise the same as the total count.
mutable Map m_map;
- mutable HashCountedSet<StringImpl*> m_duplicateCounts;
};
inline bool DocumentOrderedMap::contains(StringImpl* id) const
{
- return m_map.contains(id) || m_duplicateCounts.contains(id);
+ return m_map.contains(id);
}
inline bool DocumentOrderedMap::containsMultiple(StringImpl* id) const
{
- return m_duplicateCounts.contains(id);
+ Map::const_iterator it = m_map.find(id);
+ return it != m_map.end() && it->value->count > 1;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp
index ac2ffa99a21..2fef5ff92c0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp
@@ -25,8 +25,9 @@
#include "config.h"
#include "core/dom/DocumentParser.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/dom/Document.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "wtf/Assertions.h"
namespace WebCore {
@@ -41,10 +42,17 @@ DocumentParser::DocumentParser(Document* document)
DocumentParser::~DocumentParser()
{
+#if !ENABLE(OILPAN)
// Document is expected to call detach() before releasing its ref.
// This ASSERT is slightly awkward for parsers with a fragment case
// as there is no Document to release the ref.
ASSERT(!m_document);
+#endif
+}
+
+void DocumentParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
}
void DocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder>)
@@ -76,7 +84,7 @@ void DocumentParser::stopParsing()
void DocumentParser::detach()
{
m_state = DetachedState;
- m_document = 0;
+ m_document = nullptr;
}
void DocumentParser::suspendScheduledTasks()
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h
index c0b502ae36b..c8ed45f5f20 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h
@@ -24,9 +24,9 @@
#ifndef DocumentParser_h
#define DocumentParser_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
namespace WebCore {
@@ -36,9 +36,10 @@ class SegmentedString;
class ScriptableDocumentParser;
class TextResourceDecoder;
-class DocumentParser : public RefCounted<DocumentParser> {
+class DocumentParser : public RefCountedWillBeGarbageCollectedFinalized<DocumentParser> {
public:
virtual ~DocumentParser();
+ virtual void trace(Visitor*);
virtual ScriptableDocumentParser* asScriptableDocumentParser() { return 0; }
@@ -97,6 +98,7 @@ public:
// callstacks, but not produce any more nodes.
// It is impossible for the parser to touch the rest of WebCore after
// detach is called.
+ // Oilpan: We don't need to call detach when a Document is destructed.
virtual void detach();
void setDocumentWasLoadedAsPartOfNavigation() { m_documentWasLoadedAsPartOfNavigation = true; }
@@ -121,7 +123,7 @@ private:
// Every DocumentParser needs a pointer back to the document.
// m_document will be 0 after the parser is stopped.
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp
deleted file mode 100644
index 985f04cdde9..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "config.h"
-#include "core/dom/DocumentSharedObjectPool.h"
-
-#include "core/dom/Element.h"
-
-namespace WebCore {
-
-class ShareableElementDataCacheKey {
-public:
- ShareableElementDataCacheKey(const Attribute* attributes, unsigned attributeCount)
- : m_attributes(attributes)
- , m_attributeCount(attributeCount)
- { }
-
- bool operator!=(const ShareableElementDataCacheKey& other) const
- {
- if (m_attributeCount != other.m_attributeCount)
- return true;
- return memcmp(m_attributes, other.m_attributes, sizeof(Attribute) * m_attributeCount);
- }
-
- unsigned hash() const
- {
- return StringHasher::hashMemory(m_attributes, m_attributeCount * sizeof(Attribute));
- }
-
-private:
- const Attribute* m_attributes;
- unsigned m_attributeCount;
-};
-
-class ShareableElementDataCacheEntry {
-public:
- ShareableElementDataCacheEntry(const ShareableElementDataCacheKey& k, PassRefPtr<ShareableElementData> v)
- : key(k)
- , value(v)
- { }
-
- ShareableElementDataCacheKey key;
- RefPtr<ShareableElementData> value;
-};
-
-PassRefPtr<ShareableElementData> DocumentSharedObjectPool::cachedShareableElementDataWithAttributes(const Vector<Attribute>& attributes)
-{
- ASSERT(!attributes.isEmpty());
-
- ShareableElementDataCacheKey cacheKey(attributes.data(), attributes.size());
- unsigned cacheHash = cacheKey.hash();
-
- ShareableElementDataCache::iterator cacheIterator = m_shareableElementDataCache.add(cacheHash, nullptr).iterator;
- if (cacheIterator->value && cacheIterator->value->key != cacheKey)
- cacheHash = 0;
-
- RefPtr<ShareableElementData> elementData;
- if (cacheHash && cacheIterator->value)
- elementData = cacheIterator->value->value;
- else
- elementData = ShareableElementData::createWithAttributes(attributes);
-
- if (!cacheHash || cacheIterator->value)
- return elementData.release();
-
- cacheIterator->value = adoptPtr(new ShareableElementDataCacheEntry(ShareableElementDataCacheKey(elementData->m_attributeArray, elementData->length()), elementData));
-
- return elementData.release();
-}
-
-DocumentSharedObjectPool::DocumentSharedObjectPool()
-{
-}
-
-DocumentSharedObjectPool::~DocumentSharedObjectPool()
-{
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
index 94421382571..cd55b40c5ee 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -27,166 +27,105 @@
#include "config.h"
#include "core/dom/DocumentStyleSheetCollection.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
-#include "core/css/CSSStyleSheet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
-#include "core/dom/Element.h"
+#include "core/dom/DocumentStyleSheetCollector.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/StyleEngine.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLLinkElement.h"
-#include "core/html/HTMLStyleElement.h"
-#include "core/frame/Settings.h"
-#include "core/svg/SVGStyleElement.h"
+#include "core/dom/StyleSheetCandidate.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-using namespace HTMLNames;
-
DocumentStyleSheetCollection::DocumentStyleSheetCollection(TreeScope& treeScope)
- : StyleSheetCollection(treeScope)
+ : TreeScopeStyleSheetCollection(treeScope)
{
- ASSERT(treeScope.rootNode() == treeScope.rootNode()->document());
+ ASSERT(treeScope.rootNode() == treeScope.rootNode().document());
}
-void DocumentStyleSheetCollection::collectStyleSheetsFromCandidates(StyleEngine* engine, StyleSheetCollectionBase& collection, DocumentStyleSheetCollection::CollectFor collectFor)
+void DocumentStyleSheetCollection::collectStyleSheetsFromCandidates(StyleEngine* engine, DocumentStyleSheetCollector& collector)
{
DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
Node* n = *it;
- StyleSheet* sheet = 0;
- CSSStyleSheet* activeSheet = 0;
- if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && !document()->isHTMLDocument()) {
- // Processing instruction (XML documents only).
- // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
- ProcessingInstruction* pi = toProcessingInstruction(n);
- // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
- if (RuntimeEnabledFeatures::xsltEnabled() && pi->isXSL() && !document()->transformSourceDocument()) {
- // Don't apply XSL transforms until loading is finished.
- if (!document()->parsing() && !pi->isLoading())
- document()->applyXSLTransform(pi);
- return;
- }
- sheet = pi->sheet();
- if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
- activeSheet = toCSSStyleSheet(sheet);
- } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
- Element* e = toElement(n);
- AtomicString title = e->getAttribute(titleAttr);
- bool enabledViaScript = false;
- if (e->hasLocalName(linkTag)) {
- // <LINK> element
- HTMLLinkElement* linkElement = toHTMLLinkElement(n);
- enabledViaScript = linkElement->isEnabledViaScript();
- if (!linkElement->isDisabled() && linkElement->styleSheetIsLoading()) {
- // it is loading but we should still decide which style sheet set to use
- if (!enabledViaScript && !title.isEmpty() && engine->preferredStylesheetSetName().isEmpty()) {
- const AtomicString& rel = e->getAttribute(relAttr);
- if (!rel.contains("alternate")) {
- engine->setPreferredStylesheetSetName(title);
- engine->setSelectedStylesheetSetName(title);
- }
- }
-
- continue;
- }
- sheet = linkElement->sheet();
- if (!sheet)
- title = nullAtom;
- } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
- sheet = toSVGStyleElement(n)->sheet();
- } else {
- sheet = toHTMLStyleElement(n)->sheet();
- }
-
- if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
- activeSheet = toCSSStyleSheet(sheet);
-
- // Check to see if this sheet belongs to a styleset
- // (thus making it PREFERRED or ALTERNATE rather than
- // PERSISTENT).
- AtomicString rel = e->getAttribute(relAttr);
- if (!enabledViaScript && sheet && !title.isEmpty()) {
- // Yes, we have a title.
- if (engine->preferredStylesheetSetName().isEmpty()) {
- // No preferred set has been established. If
- // we are NOT an alternate sheet, then establish
- // us as the preferred set. Otherwise, just ignore
- // this sheet.
- if (e->hasLocalName(styleTag) || !rel.contains("alternate")) {
- engine->setPreferredStylesheetSetName(title);
- engine->setSelectedStylesheetSetName(title);
- }
- }
- if (title != engine->preferredStylesheetSetName())
- activeSheet = 0;
- }
-
- if (rel.contains("alternate") && title.isEmpty())
- activeSheet = 0;
+ StyleSheetCandidate candidate(*n);
+
+ ASSERT(!candidate.isXSL());
+ if (candidate.isImport()) {
+ Document* document = candidate.importedDocument();
+ if (!document)
+ continue;
+ if (collector.hasVisited(document))
+ continue;
+ collector.willVisit(document);
+ document->styleEngine()->updateStyleSheetsInImport(collector);
+ continue;
}
- if (sheet && collectFor == CollectForList)
- collection.appendSheetForList(sheet);
- if (activeSheet)
- collection.appendActiveStyleSheet(activeSheet);
- }
-}
+ if (candidate.isEnabledAndLoading()) {
+ // it is loading but we should still decide which style sheet set to use
+ if (candidate.hasPreferrableName(engine->preferredStylesheetSetName()))
+ engine->selectStylesheetSetName(candidate.title());
+ continue;
+ }
-static void collectActiveCSSStyleSheetsFromSeamlessParents(StyleSheetCollectionBase& collection, Document* document)
-{
- HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
- if (!seamlessParentIFrame)
- return;
- collection.appendActiveStyleSheets(seamlessParentIFrame->document().styleEngine()->activeAuthorStyleSheets());
+ StyleSheet* sheet = candidate.sheet();
+ if (!sheet)
+ continue;
+
+ if (candidate.hasPreferrableName(engine->preferredStylesheetSetName()))
+ engine->selectStylesheetSetName(candidate.title());
+ collector.appendSheetForList(sheet);
+ if (candidate.canBeActivated(engine->preferredStylesheetSetName()))
+ collector.appendActiveStyleSheet(toCSSStyleSheet(sheet));
+ }
}
-void DocumentStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollectionBase& collection, DocumentStyleSheetCollection::CollectFor colletFor)
+void DocumentStyleSheetCollection::collectStyleSheets(StyleEngine* engine, DocumentStyleSheetCollector& collector)
{
- ASSERT(document()->styleEngine() == engine);
- collection.appendActiveStyleSheets(engine->injectedAuthorStyleSheets());
- collection.appendActiveStyleSheets(engine->documentAuthorStyleSheets());
- collectActiveCSSStyleSheetsFromSeamlessParents(collection, document());
- collectStyleSheetsFromCandidates(engine, collection, colletFor);
+ ASSERT(document().styleEngine() == engine);
+ collector.appendActiveStyleSheets(engine->injectedAuthorStyleSheets());
+ collector.appendActiveStyleSheets(engine->documentAuthorStyleSheets());
+ collectStyleSheetsFromCandidates(engine, collector);
}
-bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
+void DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
- StyleSheetCollectionBase collection;
- engine->collectDocumentActiveStyleSheets(collection);
+ StyleSheetCollection collection;
+ ActiveDocumentStyleSheetCollector collector(collection);
+ collectStyleSheets(engine, collector);
StyleSheetChange change;
analyzeStyleSheetChange(updateMode, collection, change);
if (change.styleResolverUpdateType == Reconstruct) {
engine->clearMasterResolver();
- engine->resetFontSelector();
+ // FIMXE: The following depends on whether StyleRuleFontFace was modified or not.
+ // No need to always-clear font cache.
+ engine->clearFontCache();
} else if (StyleResolver* styleResolver = engine->resolver()) {
// FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
// Need to change "false" to some valid condition.
styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
if (change.styleResolverUpdateType != Additive) {
- ASSERT(change.styleResolverUpdateType == Reset || change.styleResolverUpdateType == ResetStyleResolverAndFontSelector);
+ ASSERT(change.styleResolverUpdateType == Reset);
resetAllRuleSetsInTreeScope(styleResolver);
- if (change.styleResolverUpdateType == ResetStyleResolverAndFontSelector)
- engine->resetFontSelector();
+ engine->removeFontFaceRules(change.fontFaceRulesToRemove);
styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
} else {
styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), collection.activeAuthorStyleSheets());
}
- } else if (change.styleResolverUpdateType == ResetStyleResolverAndFontSelector) {
- engine->resetFontSelector();
}
+ if (change.requiresFullStyleRecalc)
+ document().setNeedsStyleRecalc(SubtreeStyleChange);
+
m_scopingNodesForStyleScoped.didRemoveScopingNodes();
+
collection.swap(*this);
- updateUsesRemUnits();
- return change.requiresFullStyleRecalc;
+ updateUsesRemUnits();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h
index 9920ad8a848..84de5f865ca 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h
@@ -28,31 +28,30 @@
#ifndef DocumentStyleSheetCollection_h
#define DocumentStyleSheetCollection_h
-#include "core/dom/StyleSheetCollection.h"
+#include "core/dom/TreeScopeStyleSheetCollection.h"
namespace WebCore {
-class CSSStyleSheet;
-class StyleSheet;
-class StyleSheetCollection;
+class DocumentStyleSheetCollector;
class StyleEngine;
class TreeScope;
-class DocumentStyleSheetCollection FINAL : public StyleSheetCollection {
- WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
+class DocumentStyleSheetCollection FINAL : public TreeScopeStyleSheetCollection {
+ WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
explicit DocumentStyleSheetCollection(TreeScope&);
- enum CollectFor {
- CollectForList,
- DontCollectForList
- };
+ void updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
+ void collectStyleSheets(StyleEngine*, DocumentStyleSheetCollector&);
- bool updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
- void collectStyleSheets(StyleEngine*, StyleSheetCollectionBase&, CollectFor);
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ TreeScopeStyleSheetCollection::trace(visitor);
+ }
private:
- void collectStyleSheetsFromCandidates(StyleEngine*, StyleSheetCollectionBase&, CollectFor);
+ void collectStyleSheetsFromCandidates(StyleEngine*, DocumentStyleSheetCollector&);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp
new file mode 100644
index 00000000000..47818b9392d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/DocumentStyleSheetCollector.h"
+
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleSheet.h"
+#include "core/dom/DocumentStyleSheetCollection.h"
+
+namespace WebCore {
+
+DocumentStyleSheetCollector::DocumentStyleSheetCollector(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetsForList, WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeList, WillBeHeapHashSet<RawPtrWillBeMember<Document> >& visitedDocuments)
+ : m_styleSheetsForStyleSheetList(sheetsForList)
+ , m_activeAuthorStyleSheets(activeList)
+ , m_visitedDocuments(visitedDocuments)
+{
+}
+
+DocumentStyleSheetCollector::~DocumentStyleSheetCollector()
+{
+}
+
+void DocumentStyleSheetCollector::appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
+{
+ m_activeAuthorStyleSheets.appendVector(sheets);
+}
+
+void DocumentStyleSheetCollector::appendActiveStyleSheet(CSSStyleSheet* sheet)
+{
+ m_activeAuthorStyleSheets.append(sheet);
+}
+
+void DocumentStyleSheetCollector::appendSheetForList(StyleSheet* sheet)
+{
+ m_styleSheetsForStyleSheetList.append(sheet);
+}
+
+ActiveDocumentStyleSheetCollector::ActiveDocumentStyleSheetCollector(StyleSheetCollection& collection)
+ : DocumentStyleSheetCollector(collection.m_styleSheetsForStyleSheetList, collection.m_activeAuthorStyleSheets, m_visitedDocuments)
+{
+}
+
+ImportedDocumentStyleSheetCollector::ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector& collector, WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetForList)
+ : DocumentStyleSheetCollector(sheetForList, collector.m_activeAuthorStyleSheets, collector.m_visitedDocuments)
+{
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
new file mode 100644
index 00000000000..fd74c839162
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DocumentStyleSheetCollector_h
+#define DocumentStyleSheetCollector_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/HashSet.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class Document;
+class StyleSheet;
+class StyleSheetCollection;
+
+class DocumentStyleSheetCollector {
+ // This class contains references to two on-heap collections, therefore
+ // it's unhealthy to have it anywhere but on the stack, where stack
+ // scanning will keep them alive.
+ STACK_ALLOCATED();
+public:
+ friend class ImportedDocumentStyleSheetCollector;
+
+ DocumentStyleSheetCollector(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetsForList, WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeList, WillBeHeapHashSet<RawPtrWillBeMember<Document> >&);
+ ~DocumentStyleSheetCollector();
+
+ void appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
+ void appendActiveStyleSheet(CSSStyleSheet*);
+ void appendSheetForList(StyleSheet*);
+
+ bool hasVisited(Document* document) const { return m_visitedDocuments.contains(document); }
+ void willVisit(Document* document) { m_visitedDocuments.add(document); }
+
+private:
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& m_styleSheetsForStyleSheetList;
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& m_activeAuthorStyleSheets;
+ WillBeHeapHashSet<RawPtrWillBeMember<Document> >& m_visitedDocuments;
+};
+
+class ActiveDocumentStyleSheetCollector FINAL : public DocumentStyleSheetCollector {
+public:
+ ActiveDocumentStyleSheetCollector(StyleSheetCollection&);
+private:
+ WillBeHeapHashSet<RawPtrWillBeMember<Document> > m_visitedDocuments;
+};
+
+class ImportedDocumentStyleSheetCollector FINAL : public DocumentStyleSheetCollector {
+public:
+ ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector&, WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >&);
+};
+
+} // namespace WebCore
+
+#endif // DocumentStyleSheetCollector_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h b/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h
index 9b5e7790af0..0156646cbbe 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h
@@ -34,8 +34,8 @@ namespace WebCore {
class Document;
-typedef Supplementable<Document> DocumentSupplementable;
-typedef Supplement<Document> DocumentSupplement;
+typedef WillBeHeapSupplementable<Document> DocumentSupplementable;
+typedef WillBeHeapSupplement<Document> DocumentSupplement;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp
new file mode 100644
index 00000000000..5867805f548
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/Document.h"
+
+#include "core/html/HTMLHeadElement.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class DocumentTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ Document& document() const { return m_dummyPageHolder->document(); }
+ Page& page() const { return m_dummyPageHolder->page(); }
+
+private:
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+};
+
+void DocumentTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+}
+
+class MockDocumentVisibilityObserver
+ : public NoBaseWillBeGarbageCollectedFinalized<MockDocumentVisibilityObserver>
+ , public DocumentVisibilityObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockDocumentVisibilityObserver);
+public:
+ static PassOwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> create(Document& document)
+ {
+ return adoptPtrWillBeNoop(new MockDocumentVisibilityObserver(document));
+ }
+
+ virtual void trace(Visitor*) { }
+
+ MOCK_METHOD1(didChangeVisibilityState, void(PageVisibilityState));
+
+private:
+ MockDocumentVisibilityObserver(Document& document) : DocumentVisibilityObserver(document) { }
+};
+
+TEST_F(DocumentTest, VisibilityOberver)
+{
+ page().setVisibilityState(PageVisibilityStateVisible, true); // initial state
+ OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer1 = MockDocumentVisibilityObserver::create(document());
+
+ {
+ OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer2 = MockDocumentVisibilityObserver::create(document());
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ page().setVisibilityState(PageVisibilityStateHidden, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ page().setVisibilityState(PageVisibilityStateHidden, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ OwnPtr<DummyPageHolder> alternatePage = DummyPageHolder::create(IntSize(800, 600));
+ Document& alternateDocument = alternatePage->document();
+ observer2->setObservedDocument(alternateDocument);
+ page().setVisibilityState(PageVisibilityStateVisible, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ observer2->setObservedDocument(document());
+ page().setVisibilityState(PageVisibilityStateHidden, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+ }
+
+ // observer2 destroyed
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1);
+ page().setVisibilityState(PageVisibilityStateVisible, false);
+}
+
+// This test checks that Documunt::linkManifest() returns a value conform to the specification.
+TEST_F(DocumentTest, LinkManifest)
+{
+ // Test the default result.
+ EXPECT_EQ(0, document().linkManifest());
+
+ // Check that we use the first manifest with <link rel=manifest>
+ RefPtrWillBeRawPtr<HTMLLinkElement> link = HTMLLinkElement::create(document(), false);
+ link->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "foo.json");
+ document().head()->appendChild(link);
+ EXPECT_EQ(link, document().linkManifest());
+
+ RefPtrWillBeRawPtr<HTMLLinkElement> link2 = HTMLLinkElement::create(document(), false);
+ link2->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
+ link2->setAttribute(WebCore::HTMLNames::hrefAttr, "bar.json");
+ document().head()->insertBefore(link2, link.get());
+ EXPECT_EQ(link2, document().linkManifest());
+ document().head()->appendChild(link2);
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that crazy URLs are accepted.
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http:foo.json");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that empty URLs are accepted.
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that URLs from different origins are accepted.
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://example.org/manifest.json");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://foo.example.org/manifest.json");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://foo.bar/manifest.json");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // More than one token in @rel is accepted.
+ link->setAttribute(WebCore::HTMLNames::relAttr, "foo bar manifest");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Such as spaces around the token.
+ link->setAttribute(WebCore::HTMLNames::relAttr, " manifest ");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that rel=manifest actually matters.
+ link->setAttribute(WebCore::HTMLNames::relAttr, "");
+ EXPECT_EQ(link2, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
+
+ // Check that link outside of the <head> are ignored.
+ document().head()->removeChild(link.get(), ASSERT_NO_EXCEPTION);
+ document().head()->removeChild(link2.get(), ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(0, document().linkManifest());
+ document().body()->appendChild(link);
+ EXPECT_EQ(0, document().linkManifest());
+ document().head()->appendChild(link);
+ document().head()->appendChild(link2);
+
+ // Check that some attribute values do not have an effect.
+ link->setAttribute(WebCore::HTMLNames::crossoriginAttr, "use-credentials");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::hreflangAttr, "klingon");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::typeAttr, "image/gif");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::sizesAttr, "16x16");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::mediaAttr, "print");
+ EXPECT_EQ(link, document().linkManifest());
+}
+
+} // unnamed namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp
index 7c392a7035f..1859a617a7c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp
@@ -52,7 +52,7 @@ Node::NodeType DocumentType::nodeType() const
return DOCUMENT_TYPE_NODE;
}
-PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> DocumentType::cloneNode(bool /*deep*/)
{
return create(&document(), m_name, m_publicId, m_systemId);
}
@@ -71,7 +71,7 @@ Node::InsertionNotificationRequest DocumentType::insertedInto(ContainerNode* ins
void DocumentType::removedFrom(ContainerNode* insertionPoint)
{
- document().setDoctype(0);
+ document().setDoctype(nullptr);
Node::removedFrom(insertionPoint);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentType.h b/chromium/third_party/WebKit/Source/core/dom/DocumentType.h
index 6aa51fe4194..4976f299a4b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentType.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentType.h
@@ -32,20 +32,14 @@ class NamedNodeMap;
class DocumentType FINAL : public Node {
public:
- static PassRefPtr<DocumentType> create(Document* document, const String& name, const String& publicId, const String& systemId)
+ static PassRefPtrWillBeRawPtr<DocumentType> create(Document* document, const String& name, const String& publicId, const String& systemId)
{
- return adoptRef(new DocumentType(document, name, publicId, systemId));
+ return adoptRefWillBeNoop(new DocumentType(document, name, publicId, systemId));
}
- // FIXME: These wre removed from DOM4, we should add a UseCounter and see if
- // we can remove them since they never worked anyway.
- NamedNodeMap* entities() const { return 0; }
- NamedNodeMap* notations() const { return 0; }
-
const String& name() const { return m_name; }
const String& publicId() const { return m_publicId; }
const String& systemId() const { return m_systemId; }
- const String& internalSubset() const { return m_subset; }
private:
DocumentType(Document*, const String& name, const String& publicId, const String& systemId);
@@ -53,7 +47,7 @@ private:
virtual KURL baseURI() const OVERRIDE;
virtual String nodeName() const OVERRIDE;
virtual NodeType nodeType() const OVERRIDE;
- virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
@@ -61,10 +55,9 @@ private:
String m_name;
String m_publicId;
String m_systemId;
- String m_subset;
};
-DEFINE_NODE_TYPE_CASTS(DocumentType, nodeType() == Node::DOCUMENT_TYPE_NODE);
+DEFINE_NODE_TYPE_CASTS(DocumentType, isDocumentTypeNode());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl b/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl
index 510240a1362..680352bc1b6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl
@@ -22,14 +22,11 @@ interface DocumentType : Node {
// DOM Level 1
readonly attribute DOMString name;
- [MeasureAs=DocumentTypeEntities] readonly attribute NamedNodeMap entities; // Removed from DOM4.
- [MeasureAs=DocumentTypeNotations] readonly attribute NamedNodeMap notations; // Removed from DOM4.
// DOM Level 2
- [TreatReturnedNullStringAs=Null] readonly attribute DOMString publicId;
- [TreatReturnedNullStringAs=Null] readonly attribute DOMString systemId;
- [TreatReturnedNullStringAs=Null, MeasureAs=DocumentTypeInternalSubset] readonly attribute DOMString internalSubset; // Removed from DOM4.
+ readonly attribute DOMString publicId;
+ readonly attribute DOMString systemId;
};
DocumentType implements ChildNode;
diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.cpp b/chromium/third_party/WebKit/Source/core/dom/Element.cpp
index 8be9f406e93..a75add2f8ed 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Element.cpp
@@ -26,37 +26,41 @@
#include "config.h"
#include "core/dom/Element.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
-#include "XMLNames.h"
+#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSValueKeywords.h"
+#include "core/SVGNames.h"
+#include "core/XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/css/CSSAnimations.h"
-#include "core/css/CSSParser.h"
+#include "core/css/CSSImageValue.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSValuePool.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
#include "core/css/StylePropertySet.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/StyleResolver.h"
+#include "core/css/resolver/StyleResolverParentScope.h"
#include "core/dom/Attr.h"
#include "core/dom/CSSSelectorWatch.h"
#include "core/dom/ClientRect.h"
#include "core/dom/ClientRectList.h"
#include "core/dom/DatasetDOMStringMap.h"
-#include "core/dom/DocumentSharedObjectPool.h"
+#include "core/dom/ElementDataCache.h"
#include "core/dom/ElementRareData.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/MutationObserverInterestGroup.h"
#include "core/dom/MutationRecord.h"
#include "core/dom/NamedNodeMap.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/dom/NodeRenderingContext.h"
-#include "core/dom/PostAttachCallbacks.h"
#include "core/dom/PresentationAttributeStyle.h"
#include "core/dom/PseudoElement.h"
+#include "core/dom/RenderTreeBuilder.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/dom/SelectorQuery.h"
#include "core/dom/Text.h"
@@ -70,14 +74,17 @@
#include "core/editing/markup.h"
#include "core/events/EventDispatcher.h"
#include "core/events/FocusEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/ClassList.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFormControlsCollection.h"
+#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLOptionsCollection.h"
@@ -88,15 +95,17 @@
#include "core/page/FocusController.h"
#include "core/page/Page.h"
#include "core/page/PointerLockController.h"
-#include "core/rendering/FlowThreadController.h"
-#include "core/rendering/RenderNamedFlowFragment.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidget.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/scroll/ScrollableArea.h"
#include "wtf/BitVector.h"
#include "wtf/HashFunctions.h"
#include "wtf/text/CString.h"
+#include "wtf/text/StringBuilder.h"
#include "wtf/text/TextPosition.h"
namespace WebCore {
@@ -104,76 +113,7 @@ namespace WebCore {
using namespace HTMLNames;
using namespace XMLNames;
-class StyleResolverParentPusher {
-public:
- explicit StyleResolverParentPusher(Element& parent)
- : m_parent(parent)
- , m_pushedStyleResolver(0)
- {
- }
- void push()
- {
- if (m_pushedStyleResolver)
- return;
- m_pushedStyleResolver = &m_parent.document().ensureStyleResolver();
- m_pushedStyleResolver->pushParentElement(m_parent);
- }
- ~StyleResolverParentPusher()
- {
-
- if (!m_pushedStyleResolver)
- return;
-
- // This tells us that our pushed style selector is in a bad state,
- // so we should just bail out in that scenario.
- ASSERT(m_pushedStyleResolver == m_parent.document().styleResolver());
- if (m_pushedStyleResolver != m_parent.document().styleResolver())
- return;
-
- m_pushedStyleResolver->popParentElement(m_parent);
- }
-
-private:
- Element& m_parent;
- StyleResolver* m_pushedStyleResolver;
-};
-
-typedef Vector<RefPtr<Attr> > AttrNodeList;
-typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
-
-static AttrNodeListMap& attrNodeListMap()
-{
- DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
- return map;
-}
-
-static AttrNodeList* attrNodeListForElement(Element* element)
-{
- if (!element->hasSyntheticAttrChildNodes())
- return 0;
- ASSERT(attrNodeListMap().contains(element));
- return attrNodeListMap().get(element);
-}
-
-static AttrNodeList& ensureAttrNodeListForElement(Element* element)
-{
- if (element->hasSyntheticAttrChildNodes()) {
- ASSERT(attrNodeListMap().contains(element));
- return *attrNodeListMap().get(element);
- }
- ASSERT(!attrNodeListMap().contains(element));
- element->setHasSyntheticAttrChildNodes(true);
- AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
- return *result.iterator->value;
-}
-
-static void removeAttrNodeListForElement(Element* element)
-{
- ASSERT(element->hasSyntheticAttrChildNodes());
- ASSERT(attrNodeListMap().contains(element));
- attrNodeListMap().remove(element);
- element->setHasSyntheticAttrChildNodes(false);
-}
+typedef WillBeHeapVector<RefPtrWillBeMember<Attr> > AttrNodeList;
static Attr* findAttrNodeInList(const AttrNodeList& attrNodeList, const QualifiedName& name)
{
@@ -185,33 +125,25 @@ static Attr* findAttrNodeInList(const AttrNodeList& attrNodeList, const Qualifie
return 0;
}
-PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
+PassRefPtrWillBeRawPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
{
- return adoptRef(new Element(tagName, document, CreateElement));
+ return adoptRefWillBeNoop(new Element(tagName, document, CreateElement));
}
-Element::~Element()
+Element::Element(const QualifiedName& tagName, Document* document, ConstructionType type)
+ : ContainerNode(document, type)
+ , m_tagName(tagName)
{
- // When the document is not destroyed, an element that was part of a named flow
- // content nodes should have been removed from the content nodes collection
- // and the inNamedFlow flag reset.
- ASSERT(!document().renderView() || !inNamedFlow());
-
- if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
- cssomWrapper->clearParentElement();
+ ScriptWrappable::init(this);
+}
- if (hasRareData()) {
- ElementRareData* data = elementRareData();
- data->setPseudoElement(BEFORE, 0);
- data->setPseudoElement(AFTER, 0);
- data->setPseudoElement(BACKDROP, 0);
- data->clearShadow();
+Element::~Element()
+{
+ ASSERT(needsAttach());
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- if (ActiveAnimations* activeAnimations = data->activeAnimations())
- activeAnimations->cssAnimations().cancel();
- }
- }
+#if !ENABLE(OILPAN)
+ if (hasRareData())
+ elementRareData()->clearShadow();
if (isCustomElement())
CustomElement::wasDestroyed(this);
@@ -219,10 +151,16 @@ Element::~Element()
if (hasSyntheticAttrChildNodes())
detachAllAttrNodesFromElement();
+ // With Oilpan, either the Element has been removed from the Document
+ // or the Document is dead as well. If the Element has been removed from
+ // the Document the element has already been removed from the pending
+ // resources. If the document is also dead, there is no need to remove
+ // the element from the pending resources.
if (hasPendingResources()) {
- document().accessSVGExtensions()->removeElementFromPendingResources(this);
+ document().accessSVGExtensions().removeElementFromPendingResources(this);
ASSERT(!hasPendingResources());
}
+#endif
}
inline ElementRareData* Element::elementRareData() const
@@ -236,6 +174,25 @@ inline ElementRareData& Element::ensureElementRareData()
return static_cast<ElementRareData&>(ensureRareData());
}
+bool Element::hasElementFlagInternal(ElementFlags mask) const
+{
+ return elementRareData()->hasElementFlag(mask);
+}
+
+void Element::setElementFlag(ElementFlags mask, bool value)
+{
+ if (!hasRareData() && !value)
+ return;
+ ensureElementRareData().setElementFlag(mask, value);
+}
+
+void Element::clearElementFlag(ElementFlags mask)
+{
+ if (!hasRareData())
+ return;
+ elementRareData()->clearElementFlag(mask);
+}
+
void Element::clearTabIndexExplicitlyIfNeeded()
{
if (hasRareData())
@@ -247,9 +204,9 @@ void Element::setTabIndexExplicitly(short tabIndex)
ensureElementRareData().setTabIndexExplicitly(tabIndex);
}
-bool Element::supportsFocus() const
+void Element::setTabIndex(int value)
{
- return hasRareData() && elementRareData()->tabIndexSetExplicitly();
+ setIntegralAttribute(tabindexAttr, value);
}
short Element::tabIndex() const
@@ -272,9 +229,7 @@ bool Element::rendererIsFocusable() const
// FIXME: These asserts should be in Node::isFocusable, but there are some
// callsites like Document::setFocusedElement that would currently fail on
// them. See crbug.com/251163
- if (renderer()) {
- ASSERT(!renderer()->needsLayout());
- } else {
+ if (!renderer()) {
// We can't just use needsStyleRecalc() because if the node is in a
// display:none tree it might say it needs style recalc but the whole
// document is actually up to date.
@@ -289,21 +244,21 @@ bool Element::rendererIsFocusable() const
return true;
}
-PassRefPtr<Node> Element::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> Element::cloneNode(bool deep)
{
return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
}
-PassRefPtr<Element> Element::cloneElementWithChildren()
+PassRefPtrWillBeRawPtr<Element> Element::cloneElementWithChildren()
{
- RefPtr<Element> clone = cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> clone = cloneElementWithoutChildren();
cloneChildNodes(clone.get());
return clone.release();
}
-PassRefPtr<Element> Element::cloneElementWithoutChildren()
+PassRefPtrWillBeRawPtr<Element> Element::cloneElementWithoutChildren()
{
- RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
+ RefPtrWillBeRawPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
// This will catch HTML elements in the wrong namespace that are not correctly copied.
// This is a sanity check as HTML overloads some of the DOM methods.
ASSERT(isHTMLElement() == clone->isHTMLElement());
@@ -312,20 +267,20 @@ PassRefPtr<Element> Element::cloneElementWithoutChildren()
return clone.release();
}
-PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
{
return document().createElement(tagQName(), false);
}
-PassRefPtr<Attr> Element::detachAttribute(size_t index)
+PassRefPtrWillBeRawPtr<Attr> Element::detachAttribute(size_t index)
{
ASSERT(elementData());
- const Attribute* attribute = elementData()->attributeItem(index);
- RefPtr<Attr> attrNode = attrIfExists(attribute->name());
+ const Attribute& attribute = elementData()->attributeAt(index);
+ RefPtrWillBeRawPtr<Attr> attrNode = attrIfExists(attribute.name());
if (attrNode)
detachAttrNodeAtIndex(attrNode.get(), index);
else {
- attrNode = Attr::create(document(), attribute->name(), attribute->value());
+ attrNode = Attr::create(document(), attribute.name(), attribute.value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
}
return attrNode.release();
@@ -336,10 +291,9 @@ void Element::detachAttrNodeAtIndex(Attr* attr, size_t index)
ASSERT(attr);
ASSERT(elementData());
- const Attribute* attribute = elementData()->attributeItem(index);
- ASSERT(attribute);
- ASSERT(attribute->name() == attr->qualifiedName());
- detachAttrNodeFromElementWithValue(attr, attribute->value());
+ const Attribute& attribute = elementData()->attributeAt(index);
+ ASSERT(attribute.name() == attr->qualifiedName());
+ detachAttrNodeFromElementWithValue(attr, attribute.value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
}
@@ -348,7 +302,7 @@ void Element::removeAttribute(const QualifiedName& name)
if (!elementData())
return;
- size_t index = elementData()->getAttributeItemIndex(name);
+ size_t index = elementData()->findAttributeIndexByName(name);
if (index == kNotFound)
return;
@@ -363,7 +317,7 @@ void Element::setBooleanAttribute(const QualifiedName& name, bool value)
removeAttribute(name);
}
-NamedNodeMap* Element::attributes() const
+NamedNodeMap* Element::attributesForBindings() const
{
ElementRareData& rareData = const_cast<Element*>(this)->ensureElementRareData();
if (NamedNodeMap* attributeMap = rareData.attributeMap())
@@ -380,19 +334,16 @@ ActiveAnimations* Element::activeAnimations() const
return 0;
}
-ActiveAnimations* Element::ensureActiveAnimations()
+ActiveAnimations& Element::ensureActiveAnimations()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.activeAnimations())
- rareData.setActiveAnimations(adoptPtr(new ActiveAnimations()));
- return rareData.activeAnimations();
+ rareData.setActiveAnimations(adoptPtrWillBeNoop(new ActiveAnimations()));
+ return *rareData.activeAnimations();
}
bool Element::hasActiveAnimations() const
{
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return false;
-
if (!hasRareData())
return false;
@@ -414,6 +365,9 @@ void Element::synchronizeAllAttributes() const
{
if (!elementData())
return;
+ // NOTE: anyAttributeMatches in SelectorChecker.cpp
+ // currently assumes that all lazy attributes have a null namespace.
+ // If that ever changes we'll need to fix that code.
if (elementData()->m_styleAttributeIsDirty) {
ASSERT(isStyledElement());
synchronizeStyleAttributeInternal();
@@ -435,6 +389,8 @@ inline void Element::synchronizeAttribute(const QualifiedName& name) const
}
if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty)) {
ASSERT(isSVGElement());
+ // See comment in the AtomicString version of synchronizeAttribute()
+ // also.
toSVGElement(this)->synchronizeAnimatedSVGAttribute(name);
}
}
@@ -452,6 +408,16 @@ void Element::synchronizeAttribute(const AtomicString& localName) const
}
if (elementData()->m_animatedSVGAttributesAreDirty) {
// We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
+
+ // FIXME: this code is called regardless of whether name is an
+ // animated SVG Attribute. It would seem we should only call this method
+ // if SVGElement::isAnimatableAttribute is true, but the list of
+ // animatable attributes in isAnimatableAttribute does not suffice to
+ // pass all layout tests. Also, m_animatedSVGAttributesAreDirty stays
+ // dirty unless synchronizeAnimatedSVGAttribute is called with
+ // anyQName(). This means that even if Element::synchronizeAttribute()
+ // is called on all attributes, m_animatedSVGAttributesAreDirty remains
+ // true.
toSVGElement(this)->synchronizeAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
}
}
@@ -461,11 +427,16 @@ const AtomicString& Element::getAttribute(const QualifiedName& name) const
if (!elementData())
return nullAtom;
synchronizeAttribute(name);
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
return attribute->value();
return nullAtom;
}
+bool Element::shouldIgnoreAttributeCase() const
+{
+ return isHTMLElement() && document().isHTMLDocument();
+}
+
void Element::scrollIntoView(bool alignToTop)
{
document().updateLayoutIgnorePendingStylesheets();
@@ -546,40 +517,33 @@ static float localZoomForRenderer(RenderObject& renderer)
return zoomFactor;
}
-static int adjustForLocalZoom(LayoutUnit value, RenderObject& renderer)
+static double adjustForLocalZoom(LayoutUnit value, RenderObject& renderer)
{
float zoomFactor = localZoomForRenderer(renderer);
if (zoomFactor == 1)
- return value;
- return lroundf(value / zoomFactor);
+ return value.toDouble();
+ return value.toDouble() / zoomFactor;
}
int Element::offsetLeft()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
- return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), *renderer);
+ return lroundf(adjustForLocalZoom(renderer->offsetLeft(), *renderer));
return 0;
}
int Element::offsetTop()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
- return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer);
+ return lroundf(adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer));
return 0;
}
int Element::offsetWidth()
{
- document().updateStyleForNodeIfNeeded(this);
-
- if (RenderBox* renderer = renderBox()) {
- if (renderer->canDetermineWidthWithoutLayout())
- return adjustLayoutUnitForAbsoluteZoom(renderer->fixedOffsetWidth(), *renderer).round();
- }
-
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), *renderer).round();
return 0;
@@ -587,13 +551,13 @@ int Element::offsetWidth()
int Element::offsetHeight()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), *renderer).round();
return 0;
}
-Element* Element::bindingsOffsetParent()
+Element* Element::offsetParentForBindings()
{
Element* element = offsetParent();
if (!element || !element->isInShadowTree())
@@ -614,7 +578,7 @@ int Element::clientLeft()
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* renderer = renderBox())
- return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
+ return adjustLayoutUnitForAbsoluteZoom(roundToInt(renderer->clientLeft()), *renderer);
return 0;
}
@@ -623,7 +587,7 @@ int Element::clientTop()
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* renderer = renderBox())
- return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
+ return adjustLayoutUnitForAbsoluteZoom(roundToInt(renderer->clientTop()), *renderer);
return 0;
}
@@ -638,7 +602,7 @@ int Element::clientWidth()
|| (inQuirksMode && isHTMLElement() && document().body() == this)) {
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->layoutSize().width(), renderView);
+ return adjustLayoutUnitForAbsoluteZoom(view->layoutSize().width(), *renderView);
}
}
@@ -659,7 +623,7 @@ int Element::clientHeight()
|| (inQuirksMode && isHTMLElement() && document().body() == this)) {
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->layoutSize().height(), renderView);
+ return adjustLayoutUnitForAbsoluteZoom(view->layoutSize().height(), *renderView);
}
}
@@ -674,7 +638,7 @@ int Element::scrollLeft()
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
+ return adjustDoubleForAbsoluteZoom(rend->scrollLeft(), *rend);
return 0;
}
@@ -684,7 +648,7 @@ int Element::scrollLeft()
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->scrollX(), renderView);
+ return adjustDoubleForAbsoluteZoom(view->scrollX(), *renderView);
}
}
@@ -697,7 +661,7 @@ int Element::scrollTop()
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollTop(), rend);
+ return adjustLayoutUnitForAbsoluteZoom(rend->scrollTop(), *rend);
return 0;
}
@@ -707,7 +671,7 @@ int Element::scrollTop()
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->scrollY(), renderView);
+ return adjustDoubleForAbsoluteZoom(view->scrollY(), *renderView);
}
}
@@ -720,7 +684,7 @@ void Element::setScrollLeft(int newLeft)
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
+ rend->setScrollLeft(LayoutUnit::fromFloatRound(newLeft * rend->style()->effectiveZoom()));
return;
}
@@ -728,15 +692,36 @@ void Element::setScrollLeft(int newLeft)
if (document().inQuirksMode())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameView* view = frame->view();
if (!view)
return;
- view->setScrollPosition(IntPoint(static_cast<int>(newLeft * frame->pageZoomFactor()), view->scrollY()));
+ view->setScrollPosition(IntPoint(roundf(newLeft * frame->pageZoomFactor()), view->scrollY()));
+ }
+}
+
+void Element::setScrollLeft(const Dictionary& scrollOptionsHorizontal, ExceptionState& exceptionState)
+{
+ String scrollBehaviorString;
+ ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
+ if (scrollOptionsHorizontal.get("behavior", scrollBehaviorString)) {
+ if (!ScrollableArea::scrollBehaviorFromString(scrollBehaviorString, scrollBehavior)) {
+ exceptionState.throwTypeError("The ScrollBehavior provided is invalid.");
+ return;
+ }
+ }
+
+ int position;
+ if (!scrollOptionsHorizontal.get("x", position)) {
+ exceptionState.throwTypeError("ScrollOptionsHorizontal must include an 'x' member.");
+ return;
}
+
+ // FIXME: Use scrollBehavior to decide whether to scroll smoothly or instantly.
+ setScrollLeft(position);
}
void Element::setScrollTop(int newTop)
@@ -745,7 +730,7 @@ void Element::setScrollTop(int newTop)
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
+ rend->setScrollTop(LayoutUnit::fromFloatRound(newTop * rend->style()->effectiveZoom()));
return;
}
@@ -753,22 +738,43 @@ void Element::setScrollTop(int newTop)
if (document().inQuirksMode())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameView* view = frame->view();
if (!view)
return;
- view->setScrollPosition(IntPoint(view->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor())));
+ view->setScrollPosition(IntPoint(view->scrollX(), roundf(newTop * frame->pageZoomFactor())));
}
}
+void Element::setScrollTop(const Dictionary& scrollOptionsVertical, ExceptionState& exceptionState)
+{
+ String scrollBehaviorString;
+ ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
+ if (scrollOptionsVertical.get("behavior", scrollBehaviorString)) {
+ if (!ScrollableArea::scrollBehaviorFromString(scrollBehaviorString, scrollBehavior)) {
+ exceptionState.throwTypeError("The ScrollBehavior provided is invalid.");
+ return;
+ }
+ }
+
+ int position;
+ if (!scrollOptionsVertical.get("y", position)) {
+ exceptionState.throwTypeError("ScrollOptionsVertical must include a 'y' member.");
+ return;
+ }
+
+ // FIXME: Use scrollBehavior to decide whether to scroll smoothly or instantly.
+ setScrollTop(position);
+}
+
int Element::scrollWidth()
{
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
+ return adjustLayoutUnitForAbsoluteZoom(rend->scrollWidth(), *rend).toDouble();
return 0;
}
@@ -776,7 +782,7 @@ int Element::scrollHeight()
{
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
+ return adjustLayoutUnitForAbsoluteZoom(rend->scrollHeight(), *rend).toDouble();
return 0;
}
@@ -812,7 +818,7 @@ IntRect Element::boundsInRootViewSpace()
return result;
}
-PassRefPtr<ClientRectList> Element::getClientRects()
+PassRefPtrWillBeRawPtr<ClientRectList> Element::getClientRects()
{
document().updateLayoutIgnorePendingStylesheets();
@@ -829,7 +835,7 @@ PassRefPtr<ClientRectList> Element::getClientRects()
return ClientRectList::create(quads);
}
-PassRefPtr<ClientRect> Element::getBoundingClientRect()
+PassRefPtrWillBeRawPtr<ClientRect> Element::getBoundingClientRect()
{
document().updateLayoutIgnorePendingStylesheets();
@@ -871,7 +877,7 @@ const AtomicString& Element::getAttribute(const AtomicString& localName) const
if (!elementData())
return nullAtom;
synchronizeAttribute(localName);
- if (const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase()))
+ if (const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase()))
return attribute->value();
return nullAtom;
}
@@ -884,28 +890,28 @@ const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, co
void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionState& exceptionState)
{
if (!Document::isValidName(localName)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ exceptionState.throwDOMException(InvalidCharacterError, "'" + localName + "' is not a valid attribute name.");
return;
}
synchronizeAttribute(localName);
const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase() ? localName.lower() : localName;
- size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : kNotFound;
- const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
+ size_t index = elementData() ? elementData()->findAttributeIndexByName(caseAdjustedLocalName, false) : kNotFound;
+ const QualifiedName& qName = index != kNotFound ? attributeAt(index).name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
}
void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
{
synchronizeAttribute(name);
- size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : kNotFound;
+ size_t index = elementData() ? elementData()->findAttributeIndexByName(name) : kNotFound;
setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
}
void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
{
- size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : kNotFound;
+ size_t index = elementData() ? elementData()->findAttributeIndexByName(name) : kNotFound;
setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
}
@@ -918,24 +924,24 @@ ALWAYS_INLINE void Element::setAttributeInternal(size_t index, const QualifiedNa
}
if (index == kNotFound) {
- addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
+ appendAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
return;
}
- const Attribute* existingAttribute = attributeItem(index);
- QualifiedName existingAttributeName = existingAttribute->name();
+ const Attribute& existingAttribute = attributeAt(index);
+ QualifiedName existingAttributeName = existingAttribute.name();
if (!inSynchronizationOfLazyAttribute)
- willModifyAttribute(existingAttributeName, existingAttribute->value(), newValue);
+ willModifyAttribute(existingAttributeName, existingAttribute.value(), newValue);
- if (newValue != existingAttribute->value()) {
+ if (newValue != existingAttribute.value()) {
// If there is an Attr node hooked to this attribute, the Attr::setValue() call below
// will write into the ElementData.
// FIXME: Refactor this so it makes some sense.
- if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(existingAttributeName))
+ if (RefPtrWillBeRawPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? nullptr : attrIfExists(existingAttributeName))
attrNode->setValue(newValue);
else
- ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
+ ensureUniqueElementData().attributeAt(index).setValue(newValue);
}
if (!inSynchronizationOfLazyAttribute)
@@ -949,16 +955,6 @@ static inline AtomicString makeIdForStyleResolution(const AtomicString& value, b
return value;
}
-static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, const RuleFeatureSet& features)
-{
- ASSERT(newId != oldId);
- if (!oldId.isEmpty() && features.hasSelectorForId(oldId))
- return true;
- if (!newId.isEmpty() && features.hasSelectorForId(newId))
- return true;
- return false;
-}
-
void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
{
if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*this)) {
@@ -972,7 +968,6 @@ void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
StyleResolver* styleResolver = document().styleResolver();
bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
- bool shouldInvalidateStyle = false;
if (isStyledElement() && name == styleAttr) {
styleAttributeChanged(newValue, reason);
@@ -986,28 +981,35 @@ void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
if (newId != oldId) {
elementData()->setIdForStyleResolution(newId);
- shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureRuleFeatureSet());
+ if (testShouldInvalidateStyle)
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForIdChange(oldId, newId, *this);
}
} else if (name == classAttr) {
classAttributeChanged(newValue);
} else if (name == HTMLNames::nameAttr) {
setHasName(!newValue.isNull());
- } else if (name == HTMLNames::pseudoAttr) {
- shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
}
invalidateNodeListCachesInAncestors(&name, this);
// If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
- shouldInvalidateStyle |= !styleResolver;
-
- if (shouldInvalidateStyle)
- setNeedsStyleRecalc();
+ if (!styleResolver)
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (AXObjectCache* cache = document().existingAXObjectCache())
cache->handleAttributeChanged(name, this);
}
+bool Element::hasLegalLinkAttribute(const QualifiedName&) const
+{
+ return false;
+}
+
+const QualifiedName& Element::subResourceAttributeName() const
+{
+ return QualifiedName::null();
+}
+
inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
{
if (name == isAttr)
@@ -1042,77 +1044,28 @@ static inline bool classStringHasClassName(const AtomicString& newClassString)
return classStringHasClassName(newClassString.characters16(), length);
}
-template<typename Checker>
-static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker)
-{
- unsigned changedSize = changedClasses.size();
- for (unsigned i = 0; i < changedSize; ++i) {
- if (checker.hasSelectorForClass(changedClasses[i]))
- return true;
- }
- return false;
-}
-
-template<typename Checker>
-static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker)
-{
- if (!oldClasses.size())
- return checkSelectorForClassChange(newClasses, checker);
-
- // Class vectors tend to be very short. This is faster than using a hash table.
- BitVector remainingClassBits;
- remainingClassBits.ensureSize(oldClasses.size());
-
- for (unsigned i = 0; i < newClasses.size(); ++i) {
- bool found = false;
- for (unsigned j = 0; j < oldClasses.size(); ++j) {
- if (newClasses[i] == oldClasses[j]) {
- // Mark each class that is still in the newClasses so we can skip doing
- // an n^2 search below when looking for removals. We can't break from
- // this loop early since a class can appear more than once.
- remainingClassBits.quickSet(j);
- found = true;
- }
- }
- // Class was added.
- if (!found && checker.hasSelectorForClass(newClasses[i]))
- return true;
- }
-
- for (unsigned i = 0; i < oldClasses.size(); ++i) {
- if (remainingClassBits.quickGet(i))
- continue;
- // Class was removed.
- if (checker.hasSelectorForClass(oldClasses[i]))
- return true;
- }
-
- return false;
-}
-
void Element::classAttributeChanged(const AtomicString& newClassString)
{
StyleResolver* styleResolver = document().styleResolver();
bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
- bool shouldInvalidateStyle = false;
+ ASSERT(elementData());
if (classStringHasClassName(newClassString)) {
const bool shouldFoldCase = document().inQuirksMode();
const SpaceSplitString oldClasses = elementData()->classNames();
elementData()->setClass(newClassString, shouldFoldCase);
const SpaceSplitString& newClasses = elementData()->classNames();
- shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, styleResolver->ensureRuleFeatureSet());
+ if (testShouldInvalidateStyle)
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, newClasses, *this);
} else {
const SpaceSplitString& oldClasses = elementData()->classNames();
- shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, styleResolver->ensureRuleFeatureSet());
+ if (testShouldInvalidateStyle)
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, *this);
elementData()->clearClass();
}
if (hasRareData())
elementRareData()->clearClassListValueForQuirksMode();
-
- if (shouldInvalidateStyle)
- setNeedsStyleRecalc();
}
bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* elementShadow, const QualifiedName& name, const AtomicString& newValue)
@@ -1137,11 +1090,11 @@ bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el
const bool shouldFoldCase = document().inQuirksMode();
const SpaceSplitString& oldClasses = elementData()->classNames();
const SpaceSplitString newClasses(newClassString, shouldFoldCase);
- if (checkSelectorForClassChange(oldClasses, newClasses, featureSet))
+ if (featureSet.checkSelectorsForClassChange(oldClasses, newClasses))
return true;
} else {
const SpaceSplitString& oldClasses = elementData()->classNames();
- if (checkSelectorForClassChange(oldClasses, featureSet))
+ if (featureSet.checkSelectorsForClassChange(oldClasses))
return true;
}
}
@@ -1190,8 +1143,8 @@ void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
if (attributeVector.isEmpty())
return;
- if (document().sharedObjectPool())
- m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
+ if (document().elementDataCache())
+ m_elementData = document().elementDataCache()->cachedShareableElementDataWithAttributes(attributeVector);
else
m_elementData = ShareableElementData::createWithAttributes(attributeVector);
@@ -1203,7 +1156,7 @@ void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
bool Element::hasAttributes() const
{
synchronizeAllAttributes();
- return elementData() && elementData()->length();
+ return elementData() && elementData()->hasAttributes();
}
bool Element::hasEquivalentAttributes(const Element* other) const
@@ -1224,23 +1177,57 @@ String Element::nodeName() const
return m_tagName.toString();
}
-String Element::nodeNamePreservingCase() const
-{
- return m_tagName.toString();
-}
-
void Element::setPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
{
- checkSetPrefix(prefix, exceptionState);
+ UseCounter::countDeprecation(document(), UseCounter::ElementSetPrefix);
+
+ if (!prefix.isEmpty() && !Document::isValidName(prefix)) {
+ exceptionState.throwDOMException(InvalidCharacterError, "The prefix '" + prefix + "' is not a valid name.");
+ return;
+ }
+
+ // FIXME: Raise NamespaceError if prefix is malformed per the Namespaces in XML specification.
+
+ const AtomicString& nodeNamespaceURI = namespaceURI();
+ if (nodeNamespaceURI.isEmpty() && !prefix.isEmpty()) {
+ exceptionState.throwDOMException(NamespaceError, "No namespace is set, so a namespace prefix may not be set.");
+ return;
+ }
+
+ if (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI) {
+ exceptionState.throwDOMException(NamespaceError, "The prefix '" + xmlAtom + "' may not be set on namespace '" + nodeNamespaceURI + "'.");
+ return;
+ }
+
if (exceptionState.hadException())
return;
m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
}
+const AtomicString& Element::locateNamespacePrefix(const AtomicString& namespaceToLocate) const
+{
+ if (!prefix().isNull() && namespaceURI() == namespaceToLocate)
+ return prefix();
+
+ if (hasAttributes()) {
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->prefix() == xmlnsAtom && it->value() == namespaceToLocate)
+ return it->localName();
+ }
+ }
+
+ if (Element* parent = parentElement())
+ return parent->locateNamespacePrefix(namespaceToLocate);
+
+ return nullAtom;
+}
+
KURL Element::baseURI() const
{
- const AtomicString& baseAttribute = getAttribute(baseAttr);
+ const AtomicString& baseAttribute = fastGetAttribute(baseAttr);
KURL base(KURL(), baseAttribute);
if (!base.protocol().isEmpty())
return base;
@@ -1303,7 +1290,7 @@ Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertio
if (!nameValue.isNull())
updateName(nullAtom, nameValue);
- if (hasTagName(labelTag)) {
+ if (isHTMLLabelElement(*this)) {
if (scope.shouldCacheLabelsByForAttribute())
updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
}
@@ -1337,7 +1324,7 @@ void Element::removedFrom(ContainerNode* insertionPoint)
if (!nameValue.isNull())
updateName(nameValue, nullAtom);
- if (hasTagName(labelTag)) {
+ if (isHTMLLabelElement(*this)) {
TreeScope& treeScope = insertionPoint->treeScope();
if (treeScope.shouldCacheLabelsByForAttribute())
updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
@@ -1347,7 +1334,7 @@ void Element::removedFrom(ContainerNode* insertionPoint)
ContainerNode::removedFrom(insertionPoint);
if (wasInDocument) {
if (hasPendingResources())
- document().accessSVGExtensions()->removeElementFromPendingResources(this);
+ document().accessSVGExtensions().removeElementFromPendingResources(this);
if (isUpgradedCustomElement())
CustomElement::didLeaveDocument(this, insertionPoint->document());
@@ -1355,101 +1342,85 @@ void Element::removedFrom(ContainerNode* insertionPoint)
document().removeFromTopLayer(this);
+ clearElementFlag(IsInCanvasSubtree);
+
if (hasRareData())
- elementRareData()->setIsInCanvasSubtree(false);
+ elementRareData()->clearRestyleFlags();
}
void Element::attach(const AttachContext& context)
{
ASSERT(document().inStyleRecalc());
- StyleResolverParentPusher parentPusher(*this);
-
// We've already been through detach when doing an attach, but we might
// need to clear any state that's been added since then.
if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) {
ElementRareData* data = elementRareData();
data->clearComputedStyle();
- data->resetDynamicRestyleObservations();
// Only clear the style state if we're not going to reuse the style from recalcStyle.
if (!context.resolvedStyle)
data->resetStyleState();
}
- NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIfNeeded();
+ RenderTreeBuilder(this, context.resolvedStyle).createRendererForElementIfNeeded();
addCallbackSelectors();
+ StyleResolverParentScope parentScope(*this);
+
createPseudoElementIfNeeded(BEFORE);
// When a shadow root exists, it does the work of attaching the children.
- if (ElementShadow* shadow = this->shadow()) {
- parentPusher.push();
+ if (ElementShadow* shadow = this->shadow())
shadow->attach(context);
- } else if (firstChild()) {
- parentPusher.push();
- }
ContainerNode::attach(context);
createPseudoElementIfNeeded(AFTER);
createPseudoElementIfNeeded(BACKDROP);
- if (hasRareData()) {
- ElementRareData* data = elementRareData();
- if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
- if (isFocusable() && document().focusedElement() == this)
- document().updateFocusAppearanceSoon(false /* don't restore selection */);
- data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
- }
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() && !renderer()) {
- if (ActiveAnimations* activeAnimations = data->activeAnimations())
- activeAnimations->cssAnimations().cancel();
+ if (hasRareData() && !renderer()) {
+ if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimations()) {
+ activeAnimations->cssAnimations().cancel();
+ activeAnimations->setAnimationStyleChange(false);
}
}
-
- InspectorInstrumentation::didRecalculateStyleForElement(this);
-}
-
-void Element::unregisterNamedFlowContentNode()
-{
- if (RuntimeEnabledFeatures::cssRegionsEnabled() && inNamedFlow() && document().renderView())
- document().renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
}
void Element::detach(const AttachContext& context)
{
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
- unregisterNamedFlowContentNode();
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
cancelFocusAppearanceUpdate();
removeCallbackSelectors();
+ if (svgFilterNeedsLayerUpdate())
+ document().unscheduleSVGFilterLayerUpdateHack(*this);
if (hasRareData()) {
ElementRareData* data = elementRareData();
- data->setPseudoElement(BEFORE, 0);
- data->setPseudoElement(AFTER, 0);
- data->setPseudoElement(BACKDROP, 0);
- data->setIsInsideRegion(false);
+ data->clearPseudoElements();
// attach() will perform the below steps for us when inside recalcStyle.
if (!document().inStyleRecalc()) {
data->resetStyleState();
data->clearComputedStyle();
- data->resetDynamicRestyleObservations();
}
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- if (ActiveAnimations* activeAnimations = data->activeAnimations()) {
- if (context.performingReattach) {
- // FIXME: restart compositor animations rather than pull back to the main thread
- activeAnimations->cancelAnimationOnCompositor();
- } else {
- activeAnimations->cssAnimations().cancel();
- }
+ if (ActiveAnimations* activeAnimations = data->activeAnimations()) {
+ if (context.performingReattach) {
+ // FIXME: We call detach from within style recalc, so compositingState is not up to date.
+ // https://code.google.com/p/chromium/issues/detail?id=339847
+ DisableCompositingQueryAsserts disabler;
+
+ // FIXME: restart compositor animations rather than pull back to the main thread
+ activeAnimations->cancelAnimationOnCompositor();
+ } else {
+ activeAnimations->cssAnimations().cancel();
+ activeAnimations->setAnimationStyleChange(false);
}
}
+
+ if (ElementShadow* shadow = data->shadow())
+ shadow->detach(context);
}
- if (ElementShadow* shadow = this->shadow())
- shadow->detach(context);
ContainerNode::detach(context);
}
@@ -1483,7 +1454,7 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
// FIXME: We should do an actual diff to determine whether a repaint vs. layout
// is needed, but for now just assume a layout will be required. The diff code
// in RenderObject::setStyle would need to be factored out so that it could be reused.
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
return true;
}
@@ -1506,12 +1477,15 @@ PassRefPtr<RenderStyle> Element::styleForRenderer()
style = customStyleForRenderer();
if (!style)
style = originalStyleForRenderer();
+ ASSERT(style);
// styleForElement() might add active animations so we need to get it again.
- if (ActiveAnimations* activeAnimations = this->activeAnimations())
+ if (ActiveAnimations* activeAnimations = this->activeAnimations()) {
activeAnimations->cssAnimations().maybeApplyPendingUpdate(this);
+ activeAnimations->updateAnimationFlags(*style);
+ }
- ASSERT(style);
+ document().didRecalculateStyleForElement();
return style.release();
}
@@ -1546,9 +1520,10 @@ void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling)
}
// If we reattached we don't need to recalc the style of our descendants anymore.
- if ((change >= Inherit && change < Reattach) || childNeedsStyleRecalc())
+ if ((change >= UpdatePseudoElements && change < Reattach) || childNeedsStyleRecalc()) {
recalcChildStyle(change);
- clearChildNeedsStyleRecalc();
+ clearChildNeedsStyleRecalc();
+ }
if (hasCustomStyleCallbacks())
didRecalcStyle(change);
@@ -1566,27 +1541,28 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change)
RefPtr<RenderStyle> oldStyle = renderStyle();
RefPtr<RenderStyle> newStyle = styleForRenderer();
- StyleRecalcChange localChange = RenderStyle::compare(oldStyle.get(), newStyle.get());
+ StyleRecalcChange localChange = RenderStyle::stylePropagationDiff(oldStyle.get(), newStyle.get());
ASSERT(newStyle);
if (localChange == Reattach) {
AttachContext reattachContext;
reattachContext.resolvedStyle = newStyle.get();
+ bool rendererWillChange = needsAttach() || renderer();
reattach(reattachContext);
- return Reattach;
+ if (rendererWillChange || renderer())
+ return Reattach;
+ return ReattachNoRenderer;
}
ASSERT(oldStyle);
- InspectorInstrumentation::didRecalculateStyleForElement(this);
-
if (localChange != NoChange)
updateCallbackSelectors(oldStyle.get(), newStyle.get());
if (RenderObject* renderer = this->renderer()) {
- if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || shouldNotifyRendererWithIdenticalStyles()) {
- renderer->setAnimatableStyle(newStyle.get());
+ if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || svgFilterNeedsLayerUpdate()) {
+ renderer->setStyle(newStyle.get());
} else {
// Although no change occurred, we use the new style so that the cousin style sharing code won't get
// fooled into believing this style is the same.
@@ -1596,98 +1572,63 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change)
}
}
- // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
- // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
- if (document().styleEngine()->usesRemUnits() && document().documentElement() == this && oldStyle->fontSize() != newStyle->fontSize()) {
- // Cached RenderStyles may depend on the re units.
- document().ensureStyleResolver().invalidateMatchedPropertiesCache();
- return Force;
- }
-
if (styleChangeType() >= SubtreeStyleChange)
return Force;
- return max(localChange, change);
+ if (change > Inherit || localChange > Inherit)
+ return max(localChange, change);
+
+ if (localChange < Inherit && (oldStyle->hasPseudoElementStyle() || newStyle->hasPseudoElementStyle()))
+ return UpdatePseudoElements;
+
+ return localChange;
}
void Element::recalcChildStyle(StyleRecalcChange change)
{
ASSERT(document().inStyleRecalc());
- ASSERT(change >= Inherit || childNeedsStyleRecalc());
+ ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc());
ASSERT(!needsStyleRecalc());
- StyleResolverParentPusher parentPusher(*this);
+ StyleResolverParentScope parentScope(*this);
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- if (shouldRecalcStyle(change, root)) {
- parentPusher.push();
- root->recalcStyle(change);
+ updatePseudoElement(BEFORE, change);
+
+ if (change > UpdatePseudoElements || childNeedsStyleRecalc()) {
+ for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ if (root->shouldCallRecalcStyle(change))
+ root->recalcStyle(change);
}
}
- if (shouldRecalcStyle(change, this))
- updatePseudoElement(BEFORE, change);
-
if (change < Force && hasRareData() && childNeedsStyleRecalc())
checkForChildrenAdjacentRuleChanges();
- // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
- // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
- // child and work our way back means in the common case, we'll find the insertion point in O(1) time.
- // See crbug.com/288225
- StyleResolver& styleResolver = document().ensureStyleResolver();
- Text* lastTextNode = 0;
- for (Node* child = lastChild(); child; child = child->previousSibling()) {
- if (child->isTextNode()) {
- toText(child)->recalcTextStyle(change, lastTextNode);
- lastTextNode = toText(child);
- } else if (child->isElementNode()) {
- Element* element = toElement(child);
- if (shouldRecalcStyle(change, element)) {
- parentPusher.push();
- element->recalcStyle(change, lastTextNode);
- } else if (element->supportsStyleSharing()) {
- styleResolver.addToStyleSharingList(*element);
+ if (change > UpdatePseudoElements || childNeedsStyleRecalc()) {
+ // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
+ // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
+ // child and work our way back means in the common case, we'll find the insertion point in O(1) time.
+ // See crbug.com/288225
+ StyleResolver& styleResolver = document().ensureStyleResolver();
+ Text* lastTextNode = 0;
+ for (Node* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->isTextNode()) {
+ toText(child)->recalcTextStyle(change, lastTextNode);
+ lastTextNode = toText(child);
+ } else if (child->isElementNode()) {
+ Element* element = toElement(child);
+ if (element->shouldCallRecalcStyle(change))
+ element->recalcStyle(change, lastTextNode);
+ else if (element->supportsStyleSharing())
+ styleResolver.addToStyleSharingList(*element);
+ if (element->renderer())
+ lastTextNode = 0;
}
- if (element->renderer())
- lastTextNode = 0;
}
}
- if (shouldRecalcStyle(change, this)) {
- updatePseudoElement(AFTER, change);
- updatePseudoElement(BACKDROP, change);
- }
-}
-
-void Element::checkForChildrenAdjacentRuleChanges()
-{
- bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
- bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
- if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
- return;
-
- unsigned forceCheckOfNextElementCount = 0;
- bool forceCheckOfAnyElementSibling = false;
-
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->isElementNode())
- continue;
- Element* element = toElement(child);
- bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
-
- if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
- element->setNeedsStyleRecalc();
-
- if (forceCheckOfNextElementCount)
- forceCheckOfNextElementCount--;
-
- if (childRulesChanged && hasDirectAdjacentRules)
- forceCheckOfNextElementCount = document().styleEngine()->maxDirectAdjacentSelectors();
-
- forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
- }
+ updatePseudoElement(AFTER, change);
+ updatePseudoElement(BACKDROP, change);
}
void Element::updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle)
@@ -1723,42 +1664,70 @@ ElementShadow& Element::ensureShadow()
void Element::didAffectSelector(AffectedSelectorMask mask)
{
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (ElementShadow* elementShadow = shadowWhereNodeCanBeDistributed(*this))
elementShadow->didAffectSelector(mask);
}
void Element::setAnimationStyleChange(bool animationStyleChange)
{
+ if (animationStyleChange && document().inStyleRecalc())
+ return;
if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimations())
activeAnimations->setAnimationStyleChange(animationStyleChange);
}
void Element::setNeedsAnimationStyleRecalc()
{
- bool recalcPending = styleChangeType() != NoStyleChange;
- setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ if (styleChangeType() != NoStyleChange)
+ return;
- if (!recalcPending)
- setAnimationStyleChange(true);
+ setNeedsStyleRecalc(LocalStyleChange);
+ setAnimationStyleChange(true);
+}
+
+void Element::setNeedsCompositingUpdate()
+{
+ if (!document().isActive())
+ return;
+ RenderBoxModelObject* renderer = renderBoxModelObject();
+ if (!renderer)
+ return;
+ if (!renderer->hasLayer())
+ return;
+ renderer->layer()->setNeedsCompositingInputsUpdate();
+ document().renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
}
-PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
+void Element::setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition)
+{
+ if (!hasRareData() && !definition)
+ return;
+ ASSERT(!customElementDefinition());
+ ensureElementRareData().setCustomElementDefinition(definition);
+}
+
+CustomElementDefinition* Element::customElementDefinition() const
+{
+ if (hasRareData())
+ return elementRareData()->customElementDefinition();
+ return 0;
+}
+
+PassRefPtrWillBeRawPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
{
if (alwaysCreateUserAgentShadowRoot())
ensureUserAgentShadowRoot();
- if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
- return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
-
- // Since some elements recreates shadow root dynamically, multiple shadow
- // subtrees won't work well in that element. Until they are fixed, we disable
- // adding author shadow root for them.
- if (!areAuthorShadowsAllowed()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ // Some elements make assumptions about what kind of renderers they allow
+ // as children so we can't allow author shadows on them for now. An override
+ // flag is provided for testing how author shadows interact on these elements.
+ if (!areAuthorShadowsAllowed() && !RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) {
+ exceptionState.throwDOMException(HierarchyRequestError, "Author-created shadow roots are disabled for this element.");
+ return nullptr;
}
- return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
+
+ return PassRefPtrWillBeRawPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
}
ShadowRoot* Element::shadowRoot() const
@@ -1772,10 +1741,6 @@ ShadowRoot* Element::shadowRoot() const
return 0;
}
-void Element::didAddShadowRoot(ShadowRoot&)
-{
-}
-
ShadowRoot* Element::userAgentShadowRoot() const
{
if (ElementShadow* elementShadow = shadow()) {
@@ -1812,117 +1777,34 @@ bool Element::childTypeAllowed(NodeType type) const
return false;
}
-void Element::checkForEmptyStyleChange(RenderStyle* style)
+void Element::checkForEmptyStyleChange()
{
- if (!style && !styleAffectedByEmpty())
- return;
-
- if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildNodes())))
- setNeedsStyleRecalc();
-}
-
-void Element::checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta)
-{
- if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || styleChangeType() >= SubtreeStyleChange)
- return;
-
RenderStyle* style = renderStyle();
- // :empty selector.
- checkForEmptyStyleChange(style);
-
- if (!style || (needsStyleRecalc() && childrenAffectedByPositionalRules()))
- return;
-
- // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
- // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
- // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
- // backward case.
- // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
- // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
- // here. recalcStyle will then force a walk of the children when it sees that this has happened.
- if ((childrenAffectedByForwardPositionalRules() && afterChange) || (childrenAffectedByBackwardPositionalRules() && beforeChange)) {
- setNeedsStyleRecalc();
+ if (!style && !styleAffectedByEmpty())
return;
- }
-
- // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
- if (childrenAffectedByFirstChildRules() && afterChange) {
- // Find our new first child.
- Node* newFirstChild = firstElementChild();
- RenderStyle* newFirstChildStyle = newFirstChild ? newFirstChild->renderStyle() : 0;
-
- // Find the first element node following |afterChange|
- Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling();
- RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertion ? firstElementAfterInsertion->renderStyle() : 0;
-
- // This is the insert/append case.
- if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertionStyle && firstElementAfterInsertionStyle->firstChildState())
- firstElementAfterInsertion->setNeedsStyleRecalc();
-
- // We also have to handle node removal.
- if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState()))
- newFirstChild->setNeedsStyleRecalc();
- }
-
- // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- if (childrenAffectedByLastChildRules() && beforeChange) {
- // Find our new last child.
- Node* newLastChild = lastElementChild();
- RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyle() : 0;
- // Find the last element node going backwards from |beforeChange|
- Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? beforeChange : beforeChange->previousElementSibling();
- RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertion ? lastElementBeforeInsertion->renderStyle() : 0;
-
- if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertionStyle && lastElementBeforeInsertionStyle->lastChildState())
- lastElementBeforeInsertion->setNeedsStyleRecalc();
-
- // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
- // to match now.
- if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChildStyle->lastChildState()))
- newLastChild->setNeedsStyleRecalc();
- }
-
- // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
- // that could be affected by this DOM change.
- if (childrenAffectedByDirectAdjacentRules() && afterChange) {
- if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling())
- firstElementAfterInsertion->setNeedsStyleRecalc();
- }
+ if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren())))
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (changedByParser)
- checkForEmptyStyleChange(renderStyle());
- else
+
+ checkForEmptyStyleChange();
+ if (!changedByParser)
checkForSiblingStyleChanges(false, beforeChange, afterChange, childCountDelta);
if (ElementShadow* shadow = this->shadow())
shadow->setNeedsDistributionRecalc();
}
-void Element::removeAllEventListeners()
-{
- ContainerNode::removeAllEventListeners();
- if (ElementShadow* shadow = this->shadow())
- shadow->removeAllEventListeners();
-}
-
-void Element::beginParsingChildren()
-{
- clearIsParsingChildrenFinished();
-}
-
void Element::finishParsingChildren()
{
- setIsParsingChildrenFinished();
- checkForSiblingStyleChanges(this, lastChild(), 0, 0);
+ setIsFinishedParsingChildren(true);
+ checkForEmptyStyleChange();
+ checkForSiblingStyleChanges(true, lastChild(), 0, 0);
}
#ifndef NDEBUG
@@ -1953,81 +1835,127 @@ void Element::formatForDebugger(char* buffer, unsigned length) const
}
#endif
-const Vector<RefPtr<Attr> >& Element::attrNodeList()
+WillBeHeapVector<RefPtrWillBeMember<Attr> >* Element::attrNodeList()
+{
+ return hasRareData() ? elementRareData()->attrNodeList() : 0;
+}
+
+WillBeHeapVector<RefPtrWillBeMember<Attr> >& Element::ensureAttrNodeList()
+{
+ setHasSyntheticAttrChildNodes(true);
+ return ensureElementRareData().ensureAttrNodeList();
+}
+
+void Element::removeAttrNodeList()
{
ASSERT(hasSyntheticAttrChildNodes());
- return *attrNodeListForElement(this);
+ if (hasRareData())
+ elementRareData()->removeAttrNodeList();
+ setHasSyntheticAttrChildNodes(false);
}
-PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
{
if (!attrNode) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+ return nullptr;
}
- RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
+ RefPtrWillBeRawPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
if (oldAttrNode.get() == attrNode)
return attrNode; // This Attr is already attached to the element.
// InUseAttributeError: Raised if node is an Attr that is already an attribute of another Element object.
// The DOM user must explicitly clone Attr nodes to re-use them in other elements.
if (attrNode->ownerElement()) {
- exceptionState.throwUninformativeAndGenericDOMException(InUseAttributeError);
- return 0;
+ exceptionState.throwDOMException(InUseAttributeError, "The node provided is an attribute node that is already an attribute of another Element; attribute nodes must be explicitly cloned.");
+ return nullptr;
}
synchronizeAllAttributes();
- UniqueElementData* elementData = ensureUniqueElementData();
+ UniqueElementData& elementData = ensureUniqueElementData();
- size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
+ size_t index = elementData.findAttributeIndexByName(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
+ AtomicString localName;
if (index != kNotFound) {
- if (oldAttrNode)
- detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
- else
- oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
+ const Attribute& attr = elementData.attributeAt(index);
+
+ // If the name of the ElementData attribute doesn't
+ // (case-sensitively) match that of the Attr node, record it
+ // on the Attr so that it can correctly resolve the value on
+ // the Element.
+ if (!attr.name().matches(attrNode->qualifiedName()))
+ localName = attr.localName();
+
+ if (oldAttrNode) {
+ detachAttrNodeFromElementWithValue(oldAttrNode.get(), attr.value());
+ } else {
+ // FIXME: using attrNode's name rather than the
+ // Attribute's for the replaced Attr is compatible with
+ // all but Gecko (and, arguably, the DOM Level1 spec text.)
+ // Consider switching.
+ oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), attr.value());
+ }
}
setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
- attrNode->attachToElement(this);
+ attrNode->attachToElement(this, localName);
treeScope().adoptIfNeeded(*attrNode);
- ensureAttrNodeListForElement(this).append(attrNode);
+ ensureAttrNodeList().append(attrNode);
return oldAttrNode.release();
}
-PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionState& exceptionState)
{
return setAttributeNode(attr, exceptionState);
}
-PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
{
if (!attr) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+ return nullptr;
}
if (attr->ownerElement() != this) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "The node provided is owned by another element.");
+ return nullptr;
}
ASSERT(document() == attr->document());
synchronizeAttribute(attr->qualifiedName());
- size_t index = elementData()->getAttrIndex(attr);
+ size_t index = elementData()->findAttrNodeIndex(attr);
if (index == kNotFound) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "The attribute was not found on this element.");
+ return nullptr;
}
- RefPtr<Attr> guard(attr);
+ RefPtrWillBeRawPtr<Attr> guard(attr);
detachAttrNodeAtIndex(attr, index);
return guard.release();
}
+void Element::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+ if (name == tabindexAttr) {
+ int tabindex = 0;
+ if (value.isEmpty()) {
+ clearTabIndexExplicitlyIfNeeded();
+ if (treeScope().adjustedFocusedElement() == this) {
+ // We might want to call blur(), but it's dangerous to dispatch
+ // events here.
+ document().setNeedsFocusedElementCheck();
+ }
+ } else if (parseHTMLInteger(value, tabindex)) {
+ // Clamp tabindex to the range of 'short' to match Firefox's behavior.
+ setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+ }
+ }
+}
+
bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
{
AtomicString prefix, localName;
@@ -2038,7 +1966,7 @@ bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespa
QualifiedName qName(prefix, localName, namespaceURI);
if (!Document::hasValidNamespaceForAttributes(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "'" + namespaceURI + "' is an invalid namespace for attributes.");
return false;
}
@@ -2058,30 +1986,30 @@ void Element::removeAttributeInternal(size_t index, SynchronizationOfLazyAttribu
{
ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
- UniqueElementData* elementData = ensureUniqueElementData();
+ UniqueElementData& elementData = ensureUniqueElementData();
- QualifiedName name = elementData->attributeItem(index)->name();
- AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
+ QualifiedName name = elementData.attributeAt(index).name();
+ AtomicString valueBeingRemoved = elementData.attributeAt(index).value();
if (!inSynchronizationOfLazyAttribute) {
if (!valueBeingRemoved.isNull())
willModifyAttribute(name, valueBeingRemoved, nullAtom);
}
- if (RefPtr<Attr> attrNode = attrIfExists(name))
- detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
+ if (RefPtrWillBeRawPtr<Attr> attrNode = attrIfExists(name))
+ detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
- elementData->removeAttribute(index);
+ elementData.removeAttributeAt(index);
if (!inSynchronizationOfLazyAttribute)
didRemoveAttribute(name);
}
-void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
+void Element::appendAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
{
if (!inSynchronizationOfLazyAttribute)
willModifyAttribute(name, nullAtom, value);
- ensureUniqueElementData()->addAttribute(name, value);
+ ensureUniqueElementData().appendAttribute(name, value);
if (!inSynchronizationOfLazyAttribute)
didAddAttribute(name, value);
}
@@ -2092,7 +2020,7 @@ void Element::removeAttribute(const AtomicString& name)
return;
AtomicString localName = shouldIgnoreAttributeCase() ? name.lower() : name;
- size_t index = elementData()->getAttributeItemIndex(localName, false);
+ size_t index = elementData()->findAttributeIndexByName(localName, false);
if (index == kNotFound) {
if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
removeAllInlineStyleProperties();
@@ -2107,26 +2035,26 @@ void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicSt
removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
}
-PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
+PassRefPtrWillBeRawPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
{
if (!elementData())
- return 0;
+ return nullptr;
synchronizeAttribute(localName);
- const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase());
+ const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase());
if (!attribute)
- return 0;
+ return nullptr;
return ensureAttr(attribute->name());
}
-PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
+PassRefPtrWillBeRawPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
{
if (!elementData())
- return 0;
+ return nullptr;
QualifiedName qName(nullAtom, localName, namespaceURI);
synchronizeAttribute(qName);
- const Attribute* attribute = elementData()->getAttributeItem(qName);
+ const Attribute* attribute = elementData()->findAttributeByName(qName);
if (!attribute)
- return 0;
+ return nullptr;
return ensureAttr(attribute->name());
}
@@ -2135,7 +2063,7 @@ bool Element::hasAttribute(const AtomicString& localName) const
if (!elementData())
return false;
synchronizeAttribute(localName);
- return elementData()->getAttributeItem(shouldIgnoreAttributeCase() ? localName.lower() : localName, false);
+ return elementData()->findAttributeByName(shouldIgnoreAttributeCase() ? localName.lower() : localName, false);
}
bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
@@ -2144,47 +2072,32 @@ bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
return false;
QualifiedName qName(nullAtom, localName, namespaceURI);
synchronizeAttribute(qName);
- return elementData()->getAttributeItem(qName);
+ return elementData()->findAttributeByName(qName);
}
-void Element::focus(bool restorePreviousSelection, FocusDirection direction)
+void Element::focus(bool restorePreviousSelection, FocusType type)
{
if (!inDocument())
return;
- Document& doc = document();
- if (doc.focusedElement() == this)
+ if (document().focusedElement() == this)
return;
- // If the stylesheets have already been loaded we can reliably check isFocusable.
- // If not, we continue and set the focused node on the focus controller below so
- // that it can be updated soon after attach.
- if (doc.haveStylesheetsLoaded()) {
- doc.updateLayoutIgnorePendingStylesheets();
- if (!isFocusable())
- return;
- }
+ if (!document().isActive())
+ return;
- if (!supportsFocus())
+ document().updateLayoutIgnorePendingStylesheets();
+ if (!isFocusable())
return;
- RefPtr<Node> protect;
- if (Page* page = doc.page()) {
- // Focus and change event handlers can cause us to lose our last ref.
- // If a focus event handler changes the focus to a different node it
- // does not make sense to continue and update appearence.
- protect = this;
- if (!page->focusController().setFocusedElement(this, doc.frame(), direction))
- return;
- }
+ RefPtrWillBeRawPtr<Node> protect(this);
+ if (!document().page()->focusController().setFocusedElement(this, document().frame(), type))
+ return;
// Setting the focused node above might have invalidated the layout due to scripts.
- doc.updateLayoutIgnorePendingStylesheets();
-
- if (!isFocusable()) {
- ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
+ document().updateLayoutIgnorePendingStylesheets();
+ if (!isFocusable())
return;
- }
cancelFocusAppearanceUpdate();
updateFocusAppearance(restorePreviousSelection);
@@ -2193,7 +2106,8 @@ void Element::focus(bool restorePreviousSelection, FocusDirection direction)
void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
{
if (isRootEditableElement()) {
- Frame* frame = document().frame();
+ // Taking the ownership since setSelection() may release the last reference to |frame|.
+ RefPtr<LocalFrame> frame(document().frame());
if (!frame)
return;
@@ -2203,7 +2117,9 @@ void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
// FIXME: We should restore the previous selection if there is one.
VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
- frame->selection().setSelection(newSelection);
+ // Passing DoNotSetFocus as this function is called after FocusController::setFocusedElement()
+ // and we don't want to change the focus to a new Element.
+ frame->selection().setSelection(newSelection, FrameSelection::DoNotSetFocus);
frame->selection().revealSelection();
} else if (renderer() && !renderer()->isWidget())
renderer()->scrollRectToVisible(boundingBox());
@@ -2217,10 +2133,37 @@ void Element::blur()
if (doc.page())
doc.page()->focusController().setFocusedElement(0, doc.frame());
else
- doc.setFocusedElement(0);
+ doc.setFocusedElement(nullptr);
}
}
+bool Element::supportsFocus() const
+{
+ // FIXME: supportsFocus() can be called when layout is not up to date.
+ // Logic that deals with the renderer should be moved to rendererIsFocusable().
+ // But supportsFocus must return true when the element is editable, or else
+ // it won't be focusable. Furthermore, supportsFocus cannot just return true
+ // always or else tabIndex() will change for all HTML elements.
+ return hasElementFlag(TabIndexWasSetExplicitly) || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable())
+ || supportsSpatialNavigationFocus();
+}
+
+bool Element::supportsSpatialNavigationFocus() const
+{
+ // This function checks whether the element satisfies the extended criteria
+ // for the element to be focusable, introduced by spatial navigation feature,
+ // i.e. checks if click or keyboard event handler is specified.
+ // This is the way to make it possible to navigate to (focus) elements
+ // which web designer meant for being active (made them respond to click events).
+
+ if (!document().settings() || !document().settings()->spatialNavigationEnabled())
+ return false;
+ return hasEventListeners(EventTypeNames::click)
+ || hasEventListeners(EventTypeNames::keydown)
+ || hasEventListeners(EventTypeNames::keypress)
+ || hasEventListeners(EventTypeNames::keyup);
+}
+
bool Element::isFocusable() const
{
return inDocument() && supportsFocus() && !isInert() && rendererIsFocusable();
@@ -2236,15 +2179,15 @@ bool Element::isMouseFocusable() const
return isFocusable();
}
-void Element::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection)
+void Element::dispatchFocusEvent(Element* oldFocusedElement, FocusType)
{
- RefPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::focus, false, false, document().domWindow(), 0, oldFocusedElement);
+ RefPtrWillBeRawPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::focus, false, false, document().domWindow(), 0, oldFocusedElement);
EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
}
void Element::dispatchBlurEvent(Element* newFocusedElement)
{
- RefPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::blur, false, false, document().domWindow(), 0, newFocusedElement);
+ RefPtrWillBeRawPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::blur, false, false, document().domWindow(), 0, newFocusedElement);
EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
}
@@ -2274,9 +2217,9 @@ String Element::outerHTML() const
void Element::setInnerHTML(const String& html, ExceptionState& exceptionState)
{
- if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
+ if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
ContainerNode* container = this;
- if (hasTagName(templateTag))
+ if (isHTMLTemplateElement(*this))
container = toHTMLTemplateElement(this)->content();
replaceChildrenWithFragment(container, fragment.release(), exceptionState);
}
@@ -2285,20 +2228,25 @@ void Element::setInnerHTML(const String& html, ExceptionState& exceptionState)
void Element::setOuterHTML(const String& html, ExceptionState& exceptionState)
{
Node* p = parentNode();
- if (!p || !p->isElementNode()) {
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ if (!p) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "This element has no parent node.");
+ return;
+ }
+ if (!p->isElementNode()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "This element's parent is of type '" + p->nodeName() + "', which is not an element node.");
return;
}
- RefPtr<Element> parent = toElement(p);
- RefPtr<Node> prev = previousSibling();
- RefPtr<Node> next = nextSibling();
- RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", exceptionState);
+ RefPtrWillBeRawPtr<Element> parent = toElement(p);
+ RefPtrWillBeRawPtr<Node> prev = previousSibling();
+ RefPtrWillBeRawPtr<Node> next = nextSibling();
+
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", exceptionState);
if (exceptionState.hadException())
return;
parent->replaceChild(fragment.release(), this, exceptionState);
- RefPtr<Node> node = next ? next->previousSibling() : 0;
+ RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : 0;
if (!exceptionState.hadException() && node && node->isTextNode())
mergeWithNextTextNode(node.release(), exceptionState);
@@ -2357,13 +2305,30 @@ static Element* contextElementForInsertion(const String& where, Element* element
return 0;
}
+Element* Element::insertAdjacentElement(const String& where, Element* newChild, ExceptionState& exceptionState)
+{
+ if (!newChild) {
+ // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative.
+ exceptionState.throwTypeError("The node provided is null.");
+ return 0;
+ }
+
+ Node* returnValue = insertAdjacent(where, newChild, exceptionState);
+ return toElement(returnValue);
+}
+
+void Element::insertAdjacentText(const String& where, const String& text, ExceptionState& exceptionState)
+{
+ insertAdjacent(where, document().createTextNode(text).get(), exceptionState);
+}
+
void Element::insertAdjacentHTML(const String& where, const String& markup, ExceptionState& exceptionState)
{
- RefPtr<Element> contextElement = contextElementForInsertion(where, this, exceptionState);
+ RefPtrWillBeRawPtr<Element> contextElement = contextElementForInsertion(where, this, exceptionState);
if (!contextElement)
return;
- RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionState);
if (!fragment)
return;
insertAdjacent(where, fragment.get(), exceptionState);
@@ -2430,15 +2395,19 @@ String Element::textFromChildren()
return content.toString();
}
-// pseudo is used via shadowPseudoId.
-const AtomicString& Element::pseudo() const
+const AtomicString& Element::shadowPseudoId() const
{
- return getAttribute(pseudoAttr);
+ if (ShadowRoot* root = containingShadowRoot()) {
+ if (root->type() == ShadowRoot::UserAgentShadowRoot)
+ return fastGetAttribute(pseudoAttr);
+ }
+ return nullAtom;
}
-void Element::setPseudo(const AtomicString& value)
+void Element::setShadowPseudoId(const AtomicString& id)
{
- setAttribute(pseudoAttr, value);
+ ASSERT(CSSSelector::parsePseudoType(id) == CSSSelector::PseudoWebKitCustomElement || CSSSelector::parsePseudoType(id) == CSSSelector::PseudoUserAgentCustomElement);
+ setAttribute(pseudoAttr, id);
}
bool Element::isInDescendantTreeOf(const Element* shadowHost) const
@@ -2495,178 +2464,6 @@ RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
return pseudoElementSpecifier ? rareData.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : rareData.computedStyle();
}
-void Element::setStyleAffectedByEmpty()
-{
- ensureElementRareData().setStyleAffectedByEmpty(true);
-}
-
-void Element::setChildrenAffectedByFocus()
-{
- ensureElementRareData().setChildrenAffectedByFocus(true);
-}
-
-void Element::setChildrenAffectedByHover()
-{
- ensureElementRareData().setChildrenAffectedByHover(true);
-}
-
-void Element::setChildrenAffectedByActive()
-{
- ensureElementRareData().setChildrenAffectedByActive(true);
-}
-
-void Element::setChildrenAffectedByDrag()
-{
- ensureElementRareData().setChildrenAffectedByDrag(true);
-}
-
-void Element::setChildrenAffectedByFirstChildRules()
-{
- ensureElementRareData().setChildrenAffectedByFirstChildRules(true);
-}
-
-void Element::setChildrenAffectedByLastChildRules()
-{
- ensureElementRareData().setChildrenAffectedByLastChildRules(true);
-}
-
-void Element::setChildrenAffectedByDirectAdjacentRules()
-{
- ensureElementRareData().setChildrenAffectedByDirectAdjacentRules(true);
-}
-
-void Element::setChildrenAffectedByForwardPositionalRules()
-{
- ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
-}
-
-void Element::setChildrenAffectedByBackwardPositionalRules()
-{
- ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
-}
-
-void Element::setChildIndex(unsigned index)
-{
- ElementRareData& rareData = ensureElementRareData();
- if (RenderStyle* style = renderStyle())
- style->setUnique();
- rareData.setChildIndex(index);
-}
-
-bool Element::childrenSupportStyleSharing() const
-{
- if (!hasRareData())
- return true;
- return !rareDataChildrenAffectedByFocus()
- && !rareDataChildrenAffectedByHover()
- && !rareDataChildrenAffectedByActive()
- && !rareDataChildrenAffectedByDrag()
- && !rareDataChildrenAffectedByFirstChildRules()
- && !rareDataChildrenAffectedByLastChildRules()
- && !rareDataChildrenAffectedByDirectAdjacentRules()
- && !rareDataChildrenAffectedByForwardPositionalRules()
- && !rareDataChildrenAffectedByBackwardPositionalRules();
-}
-
-bool Element::rareDataStyleAffectedByEmpty() const
-{
- ASSERT(hasRareData());
- return elementRareData()->styleAffectedByEmpty();
-}
-
-bool Element::rareDataChildrenAffectedByFocus() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByFocus();
-}
-
-bool Element::rareDataChildrenAffectedByHover() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByHover();
-}
-
-bool Element::rareDataChildrenAffectedByActive() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByActive();
-}
-
-bool Element::rareDataChildrenAffectedByDrag() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByDrag();
-}
-
-bool Element::rareDataChildrenAffectedByFirstChildRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByFirstChildRules();
-}
-
-bool Element::rareDataChildrenAffectedByLastChildRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByLastChildRules();
-}
-
-bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByDirectAdjacentRules();
-}
-
-bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByForwardPositionalRules();
-}
-
-bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByBackwardPositionalRules();
-}
-
-unsigned Element::rareDataChildIndex() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childIndex();
-}
-
-void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
-{
- ensureElementRareData().setIsInCanvasSubtree(isInCanvasSubtree);
-}
-
-bool Element::isInCanvasSubtree() const
-{
- return hasRareData() && elementRareData()->isInCanvasSubtree();
-}
-
-void Element::setIsInsideRegion(bool value)
-{
- if (value == isInsideRegion())
- return;
-
- ensureElementRareData().setIsInsideRegion(value);
-}
-
-bool Element::isInsideRegion() const
-{
- return hasRareData() ? elementRareData()->isInsideRegion() : false;
-}
-
-void Element::setRegionOversetState(RegionOversetState state)
-{
- ensureElementRareData().setRegionOversetState(state);
-}
-
-RegionOversetState Element::regionOversetState() const
-{
- return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
-}
-
AtomicString Element::computeInheritedLanguage() const
{
const Node* n = this;
@@ -2676,9 +2473,9 @@ AtomicString Element::computeInheritedLanguage() const
if (n->isElementNode()) {
if (const ElementData* elementData = toElement(n)->elementData()) {
// Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
- if (const Attribute* attribute = elementData->getAttributeItem(XMLNames::langAttr))
+ if (const Attribute* attribute = elementData->findAttributeByName(XMLNames::langAttr))
value = attribute->value();
- else if (const Attribute* attribute = elementData->getAttributeItem(HTMLNames::langAttr))
+ else if (const Attribute* attribute = elementData->findAttributeByName(HTMLNames::langAttr))
value = attribute->value();
}
} else if (n->isDocumentNode()) {
@@ -2699,8 +2496,6 @@ Locale& Element::locale() const
void Element::cancelFocusAppearanceUpdate()
{
- if (hasRareData())
- elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
if (document().focusedElement() == this)
document().cancelFocusAppearanceUpdate();
}
@@ -2709,16 +2504,20 @@ void Element::normalizeAttributes()
{
if (!hasAttributes())
return;
+ // attributeCount() cannot be cached before the loop because the attributes
+ // list is altered while iterating.
for (unsigned i = 0; i < attributeCount(); ++i) {
- if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
+ if (RefPtrWillBeRawPtr<Attr> attr = attrIfExists(attributeAt(i).name()))
attr->normalize();
}
}
void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
{
+ ASSERT(!needsStyleRecalc());
PseudoElement* element = pseudoElement(pseudoId);
- if (element && (needsStyleRecalc() || shouldRecalcStyle(change, element))) {
+ if (element && (change == UpdatePseudoElements || element->shouldCallRecalcStyle(change))) {
+
// Need to clear the cached style if the PseudoElement wants a recalc so it
// computes a new style.
if (element->needsStyleRecalc())
@@ -2727,27 +2526,17 @@ void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
// PseudoElement styles hang off their parent element's style so if we needed
// a style recalc we should Force one on the pseudo.
// FIXME: We should figure out the right text sibling to pass.
- element->recalcStyle(needsStyleRecalc() ? Force : change);
+ element->recalcStyle(change == UpdatePseudoElements ? Force : change);
// Wait until our parent is not displayed or pseudoElementRendererIsNeeded
// is false, otherwise we could continously create and destroy PseudoElements
// when RenderObject::isChildAllowed on our parent returns false for the
// PseudoElement's renderer for each style recalc.
if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
- elementRareData()->setPseudoElement(pseudoId, 0);
- } else if (change >= Inherit || needsStyleRecalc())
+ elementRareData()->setPseudoElement(pseudoId, nullptr);
+ } else if (change >= UpdatePseudoElements) {
createPseudoElementIfNeeded(pseudoId);
-}
-
-bool Element::needsPseudoElement(PseudoId pseudoId, const RenderStyle& style) const
-{
- if (pseudoId == BACKDROP && !isInTopLayer())
- return false;
- if (!renderer() || !pseudoElementRendererIsNeeded(&style))
- return false;
- if (!renderer()->canHaveGeneratedChildren())
- return false;
- return true;
+ }
}
void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
@@ -2755,7 +2544,9 @@ void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
if (isPseudoElement())
return;
- RefPtr<PseudoElement> element = document().ensureStyleResolver().createPseudoElementIfNeeded(*this, pseudoId);
+ // Document::ensureStyleResolver is not inlined and shows up on profiles, avoid it here.
+ StyleEngine* engine = document().styleEngine();
+ RefPtrWillBeRawPtr<PseudoElement> element = engine->ensureResolver().createPseudoElementIfNeeded(*this, pseudoId);
if (!element)
return;
@@ -2781,40 +2572,35 @@ RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const
return 0;
}
-bool Element::webkitMatchesSelector(const String& selector, ExceptionState& exceptionState)
+bool Element::matches(const String& selectors, ExceptionState& exceptionState)
{
- if (selector.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return false;
- }
-
- SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), exceptionState);
+ SelectorQuery* selectorQuery = document().selectorQueryCache().add(AtomicString(selectors), document(), exceptionState);
if (!selectorQuery)
return false;
return selectorQuery->matches(*this);
}
-DOMTokenList* Element::classList()
+DOMTokenList& Element::classList()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.classList())
rareData.setClassList(ClassList::create(this));
- return rareData.classList();
+ return *rareData.classList();
}
-DOMStringMap* Element::dataset()
+DOMStringMap& Element::dataset()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.dataset())
rareData.setDataset(DatasetDOMStringMap::create(this));
- return rareData.dataset();
+ return *rareData.dataset();
}
KURL Element::getURLAttribute(const QualifiedName& name) const
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
ASSERT(isURLAttribute(*attribute));
}
#endif
@@ -2823,9 +2609,9 @@ KURL Element::getURLAttribute(const QualifiedName& name) const
KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
ASSERT(isURLAttribute(*attribute));
}
#endif
@@ -2870,33 +2656,19 @@ void Element::setFloatingPointAttribute(const QualifiedName& attributeName, doub
setAttribute(attributeName, AtomicString::number(value));
}
-bool Element::childShouldCreateRenderer(const Node& child) const
-{
- // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
- if (child.isSVGElement())
- return child.hasTagName(SVGNames::svgTag) || isSVGElement();
-
- return ContainerNode::childShouldCreateRenderer(child);
-}
-
void Element::webkitRequestFullscreen()
{
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
}
void Element::webkitRequestFullScreen(unsigned short flags)
{
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
-}
-
-bool Element::containsFullScreenElement() const
-{
- return hasRareData() && elementRareData()->containsFullScreenElement();
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
}
void Element::setContainsFullScreenElement(bool flag)
{
- ensureElementRareData().setContainsFullScreenElement(flag);
+ setElementFlag(ContainsFullScreenElement, flag);
setNeedsStyleRecalc(SubtreeStyleChange);
}
@@ -2913,16 +2685,11 @@ void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(boo
element->setContainsFullScreenElement(flag);
}
-bool Element::isInTopLayer() const
-{
- return hasRareData() && elementRareData()->isInTopLayer();
-}
-
void Element::setIsInTopLayer(bool inTopLayer)
{
if (isInTopLayer() == inTopLayer)
return;
- ensureElementRareData().setIsInTopLayer(inTopLayer);
+ setElementFlag(IsInTopLayer, inTopLayer);
// We must ensure a reattach occurs so the renderer is inserted in the correct sibling order under RenderView according to its
// top layer position, or in its usual place if not in the top layer.
@@ -2935,9 +2702,15 @@ void Element::webkitRequestPointerLock()
document().page()->pointerLockController().requestPointerLock(this);
}
+void Element::requestPointerLock()
+{
+ if (document().page())
+ document().page()->pointerLockController().requestPointerLock(this);
+}
+
SpellcheckAttributeState Element::spellcheckAttributeState() const
{
- const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
+ const AtomicString& value = fastGetAttribute(spellcheckAttr);
if (value == nullAtom)
return SpellcheckAttributeDefault;
if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
@@ -2964,79 +2737,6 @@ bool Element::isSpellCheckingEnabled() const
return true;
}
-RenderRegion* Element::renderRegion() const
-{
- if (renderer() && renderer()->isRenderNamedFlowFragmentContainer())
- return toRenderBlockFlow(renderer())->renderNamedFlowFragment();
-
- return 0;
-}
-
-bool Element::shouldMoveToFlowThread(RenderStyle* styleToUse) const
-{
- ASSERT(styleToUse);
-
- if (FullscreenElementStack::isActiveFullScreenElement(this))
- return false;
-
- if (isInShadowTree())
- return false;
-
- if (styleToUse->flowThread().isEmpty())
- return false;
-
- return !isRegisteredWithNamedFlow();
-}
-
-const AtomicString& Element::webkitRegionOverset() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return undefinedState;
-
- document().updateLayoutIgnorePendingStylesheets();
-
- if (!renderRegion())
- return undefinedState;
-
- switch (renderRegion()->regionOversetState()) {
- case RegionFit: {
- DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
- return fitState;
- }
- case RegionEmpty: {
- DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
- return emptyState;
- }
- case RegionOverset: {
- DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
- return overflowState;
- }
- case RegionUndefined:
- return undefinedState;
- }
-
- ASSERT_NOT_REACHED();
- return undefinedState;
-}
-
-Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
-{
- Vector<RefPtr<Range> > rangeObjects;
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return rangeObjects;
-
- document().updateLayoutIgnorePendingStylesheets();
-
- if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) {
- RenderNamedFlowFragment* region = toRenderBlockFlow(renderer())->renderNamedFlowFragment();
- if (region->isValid())
- region->getRanges(rangeObjects);
- }
-
- return rangeObjects;
-}
-
#ifndef NDEBUG
bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
{
@@ -3096,7 +2796,7 @@ inline void Element::updateId(TreeScope& scope, const AtomicString& oldId, const
void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
{
- ASSERT(hasTagName(labelTag));
+ ASSERT(isHTMLLabelElement(this));
if (!inDocument())
return;
@@ -3110,32 +2810,27 @@ void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeV
scope.addLabel(newForAttributeValue, toHTMLLabelElement(this));
}
-static bool hasSelectorForAttribute(Document* document, const AtomicString& localName)
-{
- return document->ensureStyleResolver().ensureRuleFeatureSet().hasSelectorForAttribute(localName);
-}
-
void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
{
- if (isIdAttributeName(name))
+ if (isIdAttributeName(name)) {
updateId(oldValue, newValue);
- else if (name == HTMLNames::nameAttr)
+ } else if (name == HTMLNames::nameAttr) {
updateName(oldValue, newValue);
- else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
+ } else if (name == HTMLNames::forAttr && isHTMLLabelElement(*this)) {
TreeScope& scope = treeScope();
if (scope.shouldCacheLabelsByForAttribute())
updateLabel(scope, oldValue, newValue);
}
if (oldValue != newValue) {
- if (inActiveDocument() && hasSelectorForAttribute(&document(), name.localName()))
- setNeedsStyleRecalc();
+ if (inActiveDocument() && document().styleResolver() && styleChangeType() < SubtreeStyleChange)
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForAttributeChange(name, *this);
if (isUpgradedCustomElement())
CustomElement::attributeDidChange(this, name.localName(), oldValue, newValue);
}
- if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
+ if (OwnPtrWillBeRawPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
InspectorInstrumentation::willModifyDOMAttr(this, oldValue, newValue);
@@ -3162,6 +2857,33 @@ void Element::didRemoveAttribute(const QualifiedName& name)
dispatchSubtreeModifiedEvent();
}
+static bool needsURLResolutionForInlineStyle(const Element& element, const Document& oldDocument, const Document& newDocument)
+{
+ if (oldDocument == newDocument)
+ return false;
+ if (oldDocument.baseURL() == newDocument.baseURL())
+ return false;
+ const StylePropertySet* style = element.inlineStyle();
+ if (!style)
+ return false;
+ for (unsigned i = 0; i < style->propertyCount(); ++i) {
+ // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+ if (style->propertyAt(i).value()->isImageValue())
+ return true;
+ }
+ return false;
+}
+
+static void reResolveURLsInInlineStyle(const Document& document, MutableStylePropertySet& style)
+{
+ for (unsigned i = 0; i < style.propertyCount(); ++i) {
+ StylePropertySet::PropertyReference property = style.propertyAt(i);
+ // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+ if (property.value()->isImageValue())
+ toCSSImageValue(property.value())->reResolveURL(document);
+ }
+}
+
void Element::didMoveToNewDocument(Document& oldDocument)
{
Node::didMoveToNewDocument(oldDocument);
@@ -3175,6 +2897,9 @@ void Element::didMoveToNewDocument(Document& oldDocument)
if (hasClass())
setAttribute(HTMLNames::classAttr, getClassAttribute());
}
+
+ if (needsURLResolutionForInlineStyle(*this, oldDocument, document()))
+ reResolveURLsInInlineStyle(document(), ensureMutableInlineStyle());
}
void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
@@ -3201,43 +2926,32 @@ void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const
toHTMLDocument(document()).addExtraNamedItem(newId);
}
-PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
{
if (HTMLCollection* collection = cachedHTMLCollection(type))
return collection;
- RefPtr<HTMLCollection> collection;
if (type == TableRows) {
- ASSERT(hasTagName(tableTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
+ ASSERT(isHTMLTableElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLTableRowsCollection>(*this, type);
} else if (type == SelectOptions) {
- ASSERT(hasTagName(selectTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
+ ASSERT(isHTMLSelectElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLOptionsCollection>(*this, type);
} else if (type == FormControls) {
- ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
+ ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLFormControlsCollection>(*this, type);
}
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
-}
-
-static void scheduleLayerUpdateCallback(Node* node)
-{
- // Notify the renderer even is the styles are identical since it may need to
- // create or destroy a RenderLayer.
- node->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
}
-void Element::scheduleLayerUpdate()
+void Element::scheduleSVGFilterLayerUpdateHack()
{
- if (document().inStyleRecalc())
- PostAttachCallbacks::queueCallback(scheduleLayerUpdateCallback, this);
- else
- scheduleLayerUpdateCallback(this);
+ document().scheduleSVGFilterLayerUpdateHack(*this);
}
HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
{
- return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
+ return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cached<HTMLCollection>(type) : 0;
}
IntSize Element::savedLayerScrollOffset() const
@@ -3252,17 +2966,17 @@ void Element::setSavedLayerScrollOffset(const IntSize& size)
ensureElementRareData().setSavedLayerScrollOffset(size);
}
-PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
+PassRefPtrWillBeRawPtr<Attr> Element::attrIfExists(const QualifiedName& name)
{
- if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
+ if (AttrNodeList* attrNodeList = this->attrNodeList())
return findAttrNodeInList(*attrNodeList, name);
- return 0;
+ return nullptr;
}
-PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
+PassRefPtrWillBeRawPtr<Attr> Element::ensureAttr(const QualifiedName& name)
{
- AttrNodeList& attrNodeList = ensureAttrNodeListForElement(this);
- RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
+ AttrNodeList& attrNodeList = ensureAttrNodeList();
+ RefPtrWillBeRawPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
if (!attrNode) {
attrNode = Attr::create(*this, name);
treeScope().adoptIfNeeded(*attrNode);
@@ -3276,12 +2990,12 @@ void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicStr
ASSERT(hasSyntheticAttrChildNodes());
attrNode->detachFromElementWithValue(value);
- AttrNodeList* attrNodeList = attrNodeListForElement(this);
- for (unsigned i = 0; i < attrNodeList->size(); ++i) {
- if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
- attrNodeList->remove(i);
- if (attrNodeList->isEmpty())
- removeAttrNodeListForElement(this);
+ AttrNodeList* list = attrNodeList();
+ for (unsigned i = 0; i < list->size(); ++i) {
+ if (list->at(i)->qualifiedName() == attrNode->qualifiedName()) {
+ list->remove(i);
+ if (list->isEmpty())
+ removeAttrNodeList();
return;
}
}
@@ -3290,16 +3004,17 @@ void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicStr
void Element::detachAllAttrNodesFromElement()
{
- AttrNodeList* attrNodeList = attrNodeListForElement(this);
- ASSERT(attrNodeList);
+ AttrNodeList* list = this->attrNodeList();
+ ASSERT(list);
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute->name()))
- attrNode->detachFromElementWithValue(attribute->value());
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (RefPtrWillBeRawPtr<Attr> attrNode = findAttrNodeInList(*list, it->name()))
+ attrNode->detachFromElementWithValue(it->value());
}
- removeAttrNodeListForElement(this);
+ removeAttrNodeList();
}
void Element::willRecalcStyle(StyleRecalcChange)
@@ -3316,7 +3031,7 @@ void Element::didRecalcStyle(StyleRecalcChange)
PassRefPtr<RenderStyle> Element::customStyleForRenderer()
{
ASSERT(hasCustomStyleCallbacks());
- return 0;
+ return nullptr;
}
void Element::cloneAttributesFromElement(const Element& other)
@@ -3349,23 +3064,21 @@ void Element::cloneAttributesFromElement(const Element& other)
ownerDocumentsHaveDifferentCaseSensitivity = other.document().inQuirksMode() != document().inQuirksMode();
// If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
- // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes,
- // and sharing the data won't result in different case sensitivity of class or id.
+ // We can only do this if there are no presentation attributes and sharing the data won't result in different case sensitivity of class or id.
if (other.m_elementData->isUnique()
&& !ownerDocumentsHaveDifferentCaseSensitivity
- && !other.m_elementData->presentationAttributeStyle()
- && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
+ && !other.m_elementData->presentationAttributeStyle())
const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
- if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity)
+ if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity && !needsURLResolutionForInlineStyle(other, other.document(), document()))
m_elementData = other.m_elementData;
else
m_elementData = other.m_elementData->makeUniqueCopy();
- for (unsigned i = 0; i < m_elementData->length(); ++i) {
- const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
- attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
- }
+ AttributeCollection attributes = m_elementData->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it)
+ attributeChangedFromParserOrByCloning(it->name(), it->value(), ModifiedByCloning);
}
void Element::cloneDataFromElement(const Element& other)
@@ -3384,7 +3097,7 @@ void Element::createUniqueElementData()
}
}
-InputMethodContext* Element::inputMethodContext()
+InputMethodContext& Element::inputMethodContext()
{
return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
}
@@ -3394,58 +3107,42 @@ bool Element::hasInputMethodContext() const
return hasRareData() && elementRareData()->hasInputMethodContext();
}
-bool Element::hasPendingResources() const
-{
- return hasRareData() && elementRareData()->hasPendingResources();
-}
-
-void Element::setHasPendingResources()
-{
- ensureElementRareData().setHasPendingResources(true);
-}
-
-void Element::clearHasPendingResources()
-{
- ensureElementRareData().setHasPendingResources(false);
-}
-
void Element::synchronizeStyleAttributeInternal() const
{
ASSERT(isStyledElement());
ASSERT(elementData());
ASSERT(elementData()->m_styleAttributeIsDirty);
elementData()->m_styleAttributeIsDirty = false;
- if (const StylePropertySet* inlineStyle = this->inlineStyle())
- const_cast<Element*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle->asText());
+ const StylePropertySet* inlineStyle = this->inlineStyle();
+ const_cast<Element*>(this)->setSynchronizedLazyAttribute(styleAttr,
+ inlineStyle ? AtomicString(inlineStyle->asText()) : nullAtom);
}
CSSStyleDeclaration* Element::style()
{
if (!isStyledElement())
return 0;
- return ensureMutableInlineStyle()->ensureInlineCSSStyleDeclaration(this);
+ return &ensureElementRareData().ensureInlineCSSStyleDeclaration(this);
}
-MutableStylePropertySet* Element::ensureMutableInlineStyle()
+MutableStylePropertySet& Element::ensureMutableInlineStyle()
{
ASSERT(isStyledElement());
- RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
+ RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData().m_inlineStyle;
if (!inlineStyle) {
CSSParserMode mode = (!isHTMLElement() || document().inQuirksMode()) ? HTMLQuirksMode : HTMLStandardMode;
inlineStyle = MutableStylePropertySet::create(mode);
} else if (!inlineStyle->isMutable()) {
inlineStyle = inlineStyle->mutableCopy();
}
- return toMutableStylePropertySet(inlineStyle);
+ return *toMutableStylePropertySet(inlineStyle);
}
-PropertySetCSSStyleDeclaration* Element::inlineStyleCSSOMWrapper()
+void Element::clearMutableInlineStyleIfEmpty()
{
- if (!inlineStyle() || !inlineStyle()->hasCSSOMWrapper())
- return 0;
- PropertySetCSSStyleDeclaration* cssomWrapper = ensureMutableInlineStyle()->cssStyleDeclaration();
- ASSERT(cssomWrapper && cssomWrapper->parentElement() == this);
- return cssomWrapper;
+ if (ensureMutableInlineStyle().isEmpty()) {
+ ensureUniqueElementData().m_inlineStyle.clear();
+ }
}
inline void Element::setInlineStyleFromString(const AtomicString& newStyleString)
@@ -3463,10 +3160,10 @@ inline void Element::setInlineStyleFromString(const AtomicString& newStyleString
inlineStyle.clear();
if (!inlineStyle) {
- inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this);
+ inlineStyle = BisonCSSParser::parseInlineStyleDeclaration(newStyleString, this);
} else {
ASSERT(inlineStyle->isMutable());
- static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet()->contents());
+ static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet().contents());
}
}
@@ -3478,9 +3175,7 @@ void Element::styleAttributeChanged(const AtomicString& newStyleString, Attribut
startLineNumber = document().scriptableDocumentParser()->lineNumber();
if (newStyleString.isNull()) {
- if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
- cssomWrapper->clearParentElement();
- ensureUniqueElementData()->m_inlineStyle.clear();
+ ensureUniqueElementData().m_inlineStyle.clear();
} else if (modificationReason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber)) {
setInlineStyleFromString(newStyleString);
}
@@ -3503,7 +3198,7 @@ void Element::inlineStyleChanged()
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
inlineStyleChanged();
return true;
}
@@ -3511,15 +3206,15 @@ bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identi
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
inlineStyleChanged();
return true;
}
-bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important)
+bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitType unit, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createValue(value, unit), important);
inlineStyleChanged();
return true;
}
@@ -3527,7 +3222,7 @@ bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSS
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important)
{
ASSERT(isStyledElement());
- bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document().elementSheet()->contents());
+ bool changes = ensureMutableInlineStyle().setProperty(propertyID, value, important, document().elementSheet().contents());
if (changes)
inlineStyleChanged();
return changes;
@@ -3538,7 +3233,7 @@ bool Element::removeInlineStyleProperty(CSSPropertyID propertyID)
ASSERT(isStyledElement());
if (!inlineStyle())
return false;
- bool changes = ensureMutableInlineStyle()->removeProperty(propertyID);
+ bool changes = ensureMutableInlineStyle().removeProperty(propertyID);
if (changes)
inlineStyleChanged();
return changes;
@@ -3547,25 +3242,19 @@ bool Element::removeInlineStyleProperty(CSSPropertyID propertyID)
void Element::removeAllInlineStyleProperties()
{
ASSERT(isStyledElement());
- if (!inlineStyle() || inlineStyle()->isEmpty())
+ if (!inlineStyle())
return;
- ensureMutableInlineStyle()->clear();
+ ensureMutableInlineStyle().clear();
inlineStyleChanged();
}
-void Element::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- ASSERT(isStyledElement());
- if (const StylePropertySet* inlineStyle = elementData() ? elementData()->inlineStyle() : 0)
- inlineStyle->addSubresourceStyleURLs(urls, document().elementSheet()->contents());
-}
-
void Element::updatePresentationAttributeStyle()
{
+ synchronizeAllAttributes();
// ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData.
- UniqueElementData* elementData = ensureUniqueElementData();
- elementData->m_presentationAttributeStyleIsDirty = false;
- elementData->m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
+ UniqueElementData& elementData = ensureUniqueElementData();
+ elementData.m_presentationAttributeStyleIsDirty = false;
+ elementData.m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
}
void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, CSSValueID identifier)
@@ -3574,7 +3263,7 @@ void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* s
style->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier));
}
-void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit)
+void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitType unit)
{
ASSERT(isStyledElement());
style->setProperty(propertyID, cssValuePool().createValue(value, unit));
@@ -3588,7 +3277,7 @@ void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* s
bool Element::supportsStyleSharing() const
{
- if (!isStyledElement() || !parentElement())
+ if (!isStyledElement() || !parentOrShadowHostElement())
return false;
// If the element has inline style it is probably unique.
if (inlineStyle())
@@ -3598,17 +3287,12 @@ bool Element::supportsStyleSharing() const
// Ids stop style sharing if they show up in the stylesheets.
if (hasID() && document().ensureStyleResolver().hasRulesForId(idForStyleResolution()))
return false;
- // Active and hovered elements always make a chain towards the document node
- // and no siblings or cousins will have the same state.
- if (hovered())
- return false;
- if (active())
- return false;
- if (focused())
+ // :active and :hover elements always make a chain towards the document node
+ // and no siblings or cousins will have the same state. There's also only one
+ // :focus element per scope so we don't need to attempt to share.
+ if (isUserActionElement())
return false;
- if (!parentElement()->childrenSupportStyleSharing())
- return false;
- if (hasScopedHTMLStyleChild())
+ if (!parentOrShadowHostElement()->childrenSupportStyleSharing())
return false;
if (this == document().cssTarget())
return false;
@@ -3616,26 +3300,26 @@ bool Element::supportsStyleSharing() const
return false;
if (hasActiveAnimations())
return false;
- if (shadow() && shadow()->containsActiveStyles())
- return false;
// Turn off style sharing for elements that can gain layers for reasons outside of the style system.
// See comments in RenderObject::setStyle().
// FIXME: Why does gaining a layer from outside the style system require disabling sharing?
- if (hasTagName(iframeTag)
- || hasTagName(frameTag)
- || hasTagName(embedTag)
- || hasTagName(objectTag)
- || hasTagName(appletTag)
- || hasTagName(canvasTag))
- return false;
- // FIXME: We should share style for option and optgroup whenever possible.
- // Before doing so, we need to resolve issues in HTMLSelectElement::recalcListItems
- // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cgi?id=88405
- if (hasTagName(optionTag) || hasTagName(optgroupTag))
+ if (isHTMLFrameElementBase(*this)
+ || isHTMLEmbedElement(*this)
+ || isHTMLObjectElement(*this)
+ || isHTMLAppletElement(*this)
+ || isHTMLCanvasElement(*this))
return false;
if (FullscreenElementStack::isActiveFullScreenElement(this))
return false;
return true;
}
+void Element::trace(Visitor* visitor)
+{
+ if (hasRareData())
+ visitor->trace(elementRareData());
+
+ ContainerNode::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.h b/chromium/third_party/WebKit/Source/core/dom/Element.h
index 370d7d6a5ed..b3972e8a490 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Element.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Element.h
@@ -25,16 +25,16 @@
#ifndef Element_h
#define Element_h
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/dom/Attribute.h"
-#include "core/dom/Document.h"
+#include "core/dom/ContainerNode.h"
#include "core/dom/ElementData.h"
#include "core/dom/SpaceSplitString.h"
#include "core/html/CollectionType.h"
-#include "core/page/FocusDirection.h"
-#include "core/rendering/RegionOversetState.h"
+#include "core/page/FocusType.h"
+#include "platform/heap/Handle.h"
#include "platform/scroll/ScrollTypes.h"
namespace WebCore {
@@ -42,10 +42,13 @@ namespace WebCore {
class ActiveAnimations;
class Attr;
class Attribute;
+class CSSStyleDeclaration;
class ClientRect;
class ClientRectList;
+class CustomElementDefinition;
class DOMStringMap;
class DOMTokenList;
+class Document;
class ElementRareData;
class ElementShadow;
class ExceptionState;
@@ -56,7 +59,6 @@ class Locale;
class MutableStylePropertySet;
class PropertySetCSSStyleDeclaration;
class PseudoElement;
-class RenderRegion;
class ShadowRoot;
class StylePropertySet;
@@ -77,9 +79,20 @@ enum SpellcheckAttributeState {
SpellcheckAttributeDefault
};
+enum ElementFlags {
+ TabIndexWasSetExplicitly = 1 << 0,
+ StyleAffectedByEmpty = 1 << 1,
+ IsInCanvasSubtree = 1 << 2,
+ ContainsFullScreenElement = 1 << 3,
+ IsInTopLayer = 1 << 4,
+ HasPendingResources = 1 << 5,
+
+ NumberOfElementFlags = 6, // Required size of bitfield used to store the flags.
+};
+
class Element : public ContainerNode {
public:
- static PassRefPtr<Element> create(const QualifiedName&, Document*);
+ static PassRefPtrWillBeRawPtr<Element> create(const QualifiedName&, Document*);
virtual ~Element();
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
@@ -100,8 +113,11 @@ public:
bool hasAttribute(const QualifiedName&) const;
const AtomicString& getAttribute(const QualifiedName&) const;
+
+ // Passing nullAtom as the second parameter removes the attribute when calling either of these set methods.
void setAttribute(const QualifiedName&, const AtomicString& value);
void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value);
+
void removeAttribute(const QualifiedName&);
// Typed getters and setters for language bindings.
@@ -153,12 +169,14 @@ public:
const AtomicString& idForStyleResolution() const;
// Internal methods that assume the existence of attribute storage, one should use hasAttributes()
- // before calling them.
+ // before calling them. This is not a trivial getter and its return value should be cached for
+ // performance.
+ AttributeCollection attributes() const { return elementData()->attributes(); }
size_t attributeCount() const;
- const Attribute* attributeItem(unsigned index) const;
- const Attribute* getAttributeItem(const QualifiedName&) const;
- size_t getAttributeItemIndex(const QualifiedName& name) const { return elementData()->getAttributeItemIndex(name); }
- size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
+ const Attribute& attributeAt(unsigned index) const;
+ const Attribute* findAttributeByName(const QualifiedName&) const;
+ size_t findAttributeIndexByName(const QualifiedName& name) const { return elementData()->findAttributeIndexByName(name); }
+ size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->findAttributeIndexByName(name, shouldIgnoreAttributeCase); }
void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
@@ -172,8 +190,8 @@ public:
int offsetHeight();
// FIXME: Replace uses of offsetParent in the platform with calls
- // to the render layer and merge bindingsOffsetParent and offsetParent.
- Element* bindingsOffsetParent();
+ // to the render layer and merge offsetParentForBindings and offsetParent.
+ Element* offsetParentForBindings();
Element* offsetParent();
int clientLeft();
@@ -183,14 +201,16 @@ public:
virtual int scrollLeft();
virtual int scrollTop();
virtual void setScrollLeft(int);
+ virtual void setScrollLeft(const Dictionary& scrollOptionsHorizontal, ExceptionState&);
virtual void setScrollTop(int);
+ virtual void setScrollTop(const Dictionary& scrollOptionsVertical, ExceptionState&);
virtual int scrollWidth();
virtual int scrollHeight();
IntRect boundsInRootViewSpace();
- PassRefPtr<ClientRectList> getClientRects();
- PassRefPtr<ClientRect> getBoundingClientRect();
+ PassRefPtrWillBeRawPtr<ClientRectList> getClientRects();
+ PassRefPtrWillBeRawPtr<ClientRect> getBoundingClientRect();
// Returns the absolute bounding box translated into screen coordinates:
IntRect screenRect() const;
@@ -200,18 +220,18 @@ public:
void removeAttribute(const AtomicString& name);
void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<Attr> detachAttribute(size_t index);
+ PassRefPtrWillBeRawPtr<Attr> detachAttribute(size_t index);
- PassRefPtr<Attr> getAttributeNode(const AtomicString& name);
- PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
- PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
- PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> getAttributeNode(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
+ PassRefPtrWillBeRawPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
- PassRefPtr<Attr> attrIfExists(const QualifiedName&);
- PassRefPtr<Attr> ensureAttr(const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Attr> attrIfExists(const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Attr> ensureAttr(const QualifiedName&);
- const Vector<RefPtr<Attr> >& attrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList();
CSSStyleDeclaration* style();
@@ -226,21 +246,22 @@ public:
bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
- virtual const AtomicString& localName() const OVERRIDE { return m_tagName.localName(); }
- virtual const AtomicString& prefix() const OVERRIDE { return m_tagName.prefix(); }
- virtual const AtomicString& namespaceURI() const OVERRIDE { return m_tagName.namespaceURI(); }
+ virtual const AtomicString& localName() const OVERRIDE FINAL { return m_tagName.localName(); }
+ const AtomicString& prefix() const { return m_tagName.prefix(); }
+ virtual const AtomicString& namespaceURI() const OVERRIDE FINAL { return m_tagName.namespaceURI(); }
+
+ const AtomicString& locateNamespacePrefix(const AtomicString& namespaceURI) const;
virtual KURL baseURI() const OVERRIDE FINAL;
- virtual String nodeName() const;
+ virtual String nodeName() const OVERRIDE;
- PassRefPtr<Element> cloneElementWithChildren();
- PassRefPtr<Element> cloneElementWithoutChildren();
+ PassRefPtrWillBeRawPtr<Element> cloneElementWithChildren();
+ PassRefPtrWillBeRawPtr<Element> cloneElementWithoutChildren();
- void scheduleLayerUpdate();
+ void scheduleSVGFilterLayerUpdateHack();
void normalizeAttributes();
- String nodeNamePreservingCase() const;
void setBooleanAttribute(const QualifiedName& name, bool);
@@ -251,7 +272,7 @@ public:
bool setInlineStyleProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
bool setInlineStyleProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
- bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitTypes, bool important = false);
+ bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitType, bool important = false);
bool setInlineStyleProperty(CSSPropertyID, const String& value, bool important = false);
bool removeInlineStyleProperty(CSSPropertyID);
void removeAllInlineStyleProperties();
@@ -263,7 +284,7 @@ public:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) { }
// For exposing to DOM only.
- NamedNodeMap* attributes() const;
+ NamedNodeMap* attributesForBindings() const;
enum AttributeModificationReason {
ModifiedDirectly,
@@ -272,7 +293,10 @@ public:
// This method is called whenever an attribute is added, changed or removed.
virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&);
+
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const;
+ virtual const QualifiedName& subResourceAttributeName() const;
// Only called by the parser immediately after element construction.
void parserSetAttributes(const Vector<Attribute>&);
@@ -281,7 +305,7 @@ public:
void stripScriptingAttributes(Vector<Attribute>&) const;
const ElementData* elementData() const { return m_elementData.get(); }
- UniqueElementData* ensureUniqueElementData();
+ UniqueElementData& ensureUniqueElementData();
void synchronizeAllAttributes() const;
@@ -304,63 +328,35 @@ public:
void setAnimationStyleChange(bool);
void setNeedsAnimationStyleRecalc();
+ void setNeedsCompositingUpdate();
+
bool supportsStyleSharing() const;
ElementShadow* shadow() const;
ElementShadow& ensureShadow();
- PassRefPtr<ShadowRoot> createShadowRoot(ExceptionState&);
+ PassRefPtrWillBeRawPtr<ShadowRoot> createShadowRoot(ExceptionState&);
ShadowRoot* shadowRoot() const;
ShadowRoot* youngestShadowRoot() const;
bool hasAuthorShadowRoot() const { return shadowRoot(); }
- virtual void didAddShadowRoot(ShadowRoot&);
ShadowRoot* userAgentShadowRoot() const;
ShadowRoot& ensureUserAgentShadowRoot();
- const AtomicString& shadowPseudoId() const;
+ virtual void willAddFirstAuthorShadowRoot() { }
+
bool isInDescendantTreeOf(const Element* shadowHost) const;
RenderStyle* computedStyle(PseudoId = NOPSEUDO);
// Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
- bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); }
- bool childrenAffectedByFocus() const { return hasRareData() && rareDataChildrenAffectedByFocus(); }
- bool childrenAffectedByHover() const { return hasRareData() && rareDataChildrenAffectedByHover(); }
- bool childrenAffectedByActive() const { return hasRareData() && rareDataChildrenAffectedByActive(); }
- bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
- bool childrenAffectedByPositionalRules() const { return hasRareData() && (rareDataChildrenAffectedByForwardPositionalRules() || rareDataChildrenAffectedByBackwardPositionalRules()); }
- bool childrenAffectedByFirstChildRules() const { return hasRareData() && rareDataChildrenAffectedByFirstChildRules(); }
- bool childrenAffectedByLastChildRules() const { return hasRareData() && rareDataChildrenAffectedByLastChildRules(); }
- bool childrenAffectedByDirectAdjacentRules() const { return hasRareData() && rareDataChildrenAffectedByDirectAdjacentRules(); }
- bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); }
- bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
- unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; }
-
- bool childrenSupportStyleSharing() const;
-
- void setStyleAffectedByEmpty();
- void setChildrenAffectedByFocus();
- void setChildrenAffectedByHover();
- void setChildrenAffectedByActive();
- void setChildrenAffectedByDrag();
- void setChildrenAffectedByFirstChildRules();
- void setChildrenAffectedByLastChildRules();
- void setChildrenAffectedByDirectAdjacentRules();
- void setChildrenAffectedByForwardPositionalRules();
- void setChildrenAffectedByBackwardPositionalRules();
- void setChildIndex(unsigned);
-
- void setIsInCanvasSubtree(bool);
- bool isInCanvasSubtree() const;
+ bool styleAffectedByEmpty() const { return hasElementFlag(StyleAffectedByEmpty); }
+ void setStyleAffectedByEmpty() { setElementFlag(StyleAffectedByEmpty); }
+
+ void setIsInCanvasSubtree(bool value) { setElementFlag(IsInCanvasSubtree, value); }
+ bool isInCanvasSubtree() const { return hasElementFlag(IsInCanvasSubtree); }
bool isUpgradedCustomElement() { return customElementState() == Upgraded; }
bool isUnresolvedCustomElement() { return customElementState() == WaitingForUpgrade; }
- void setIsInsideRegion(bool);
- bool isInsideRegion() const;
-
- void setRegionOversetState(RegionOversetState);
- RegionOversetState regionOversetState() const;
-
AtomicString computeInheritedLanguage() const;
Locale& locale() const;
@@ -373,10 +369,9 @@ public:
KURL getNonEmptyURLAttribute(const QualifiedName&) const;
virtual const AtomicString imageSourceURL() const;
- virtual String target() const { return String(); }
virtual Image* imageContents() { return 0; }
- virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone);
+ virtual void focus(bool restorePreviousSelection = true, FocusType = FocusTypeNone);
virtual void updateFocusAppearance(bool restorePreviousSelection);
virtual void blur();
// Whether this element can receive focus at all. Most elements are not
@@ -388,7 +383,7 @@ public:
bool isFocusable() const;
virtual bool isKeyboardFocusable() const;
virtual bool isMouseFocusable() const;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection);
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType);
virtual void dispatchBlurEvent(Element* newFocusedElement);
void dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement);
void dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement);
@@ -399,14 +394,17 @@ public:
String outerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
void setOuterHTML(const String&, ExceptionState&);
+
+ Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionState&);
+ void insertAdjacentText(const String& where, const String& text, ExceptionState&);
void insertAdjacentHTML(const String& where, const String& html, ExceptionState&);
String textFromChildren();
virtual String title() const { return String(); }
- virtual const AtomicString& pseudo() const;
- void setPseudo(const AtomicString&);
+ virtual const AtomicString& shadowPseudoId() const;
+ void setShadowPseudoId(const AtomicString&);
LayoutSize minimumSizeForResizing() const;
void setMinimumSizeForResizing(const LayoutSize&);
@@ -414,27 +412,28 @@ public:
virtual void didBecomeFullscreenElement() { }
virtual void willStopBeingFullscreenElement() { }
- bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
+ // Called by the parser when this element's close tag is reached,
+ // signaling that all child tags have been parsed and added.
+ // This is needed for <applet> and <object> elements, which can't lay themselves out
+ // until they know all of their nested <param>s. [Radar 3603191, 4040848].
+ // Also used for script elements and some SVG elements for similar purposes,
+ // but making parsing a special case in this respect should be avoided if possible.
virtual void finishParsingChildren();
- virtual void beginParsingChildren() OVERRIDE FINAL;
+
+ void beginParsingChildren() { setIsFinishedParsingChildren(false); }
PseudoElement* pseudoElement(PseudoId) const;
RenderObject* pseudoElementRenderer(PseudoId) const;
virtual bool matchesReadOnlyPseudoClass() const { return false; }
virtual bool matchesReadWritePseudoClass() const { return false; }
- bool webkitMatchesSelector(const String& selectors, ExceptionState&);
+ bool matches(const String& selectors, ExceptionState&);
virtual bool shouldAppearIndeterminate() const { return false; }
- DOMTokenList* classList();
+ DOMTokenList& classList();
- DOMStringMap* dataset();
+ DOMStringMap& dataset();
- virtual bool isMediaElement() const { return false; }
-
-#if ENABLE(INPUT_SPEECH)
- virtual bool isInputFieldSpeechButtonElement() const { return false; }
-#endif
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
virtual bool isDateTimeEditElement() const { return false; }
virtual bool isDateTimeFieldElement() const { return false; }
@@ -451,59 +450,46 @@ public:
virtual bool isValidFormControlElement() { return false; }
virtual bool isInRange() const { return false; }
virtual bool isOutOfRange() const { return false; }
- virtual bool isFrameElementBase() const { return false; }
- virtual bool isPasswordGeneratorButtonElement() const { return false; }
virtual bool isClearButtonElement() const { return false; }
- virtual bool canContainRangeEndPoint() const { return true; }
-
- virtual const AtomicString& formControlType() const { return nullAtom; }
-
- // FIXME: Only HTMLInputElement uses these, they don't need to be virtual.
- virtual bool wasChangedSinceLastFormControlChangeEvent() const { return false; }
- virtual void setChangedSinceLastFormControlChangeEvent(bool) { }
- virtual void dispatchFormControlChangeEvent() { }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
// Used for disabled form elements; if true, prevents mouse events from being dispatched
// to event listeners, and prevents DOMActivate events from being sent at all.
virtual bool isDisabledFormControl() const { return false; }
- virtual bool shouldBeReparentedUnderRenderView(const RenderStyle*) const { return isInTopLayer(); }
-
- virtual bool childShouldCreateRenderer(const Node& child) const;
- bool hasPendingResources() const;
- void setHasPendingResources();
- void clearHasPendingResources();
+ bool hasPendingResources() const { return hasElementFlag(HasPendingResources); }
+ void setHasPendingResources() { setElementFlag(HasPendingResources); }
+ void clearHasPendingResources() { clearElementFlag(HasPendingResources); }
virtual void buildPendingResource() { };
+ void setCustomElementDefinition(PassRefPtr<CustomElementDefinition>);
+ CustomElementDefinition* customElementDefinition() const;
+
enum {
ALLOW_KEYBOARD_INPUT = 1 << 0,
LEGACY_MOZILLA_REQUEST = 1 << 1,
};
void webkitRequestFullScreen(unsigned short flags);
- bool containsFullScreenElement() const;
+ bool containsFullScreenElement() const { return hasElementFlag(ContainsFullScreenElement); }
void setContainsFullScreenElement(bool);
void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool);
// W3C API
void webkitRequestFullscreen();
- bool isInTopLayer() const;
+ bool isInTopLayer() const { return hasElementFlag(IsInTopLayer); }
void setIsInTopLayer(bool);
void webkitRequestPointerLock();
+ void requestPointerLock();
bool isSpellCheckingEnabled() const;
- // FIXME: public for NodeRenderingContext, we shouldn't expose this though.
+ // FIXME: public for RenderTreeBuilder, we shouldn't expose this though.
PassRefPtr<RenderStyle> styleForRenderer();
- RenderRegion* renderRegion() const;
- virtual bool shouldMoveToFlowThread(RenderStyle*) const;
- const AtomicString& webkitRegionOverset() const;
- Vector<RefPtr<Range> > webkitGetRegionFlowRanges() const;
-
bool hasID() const;
bool hasClass() const;
const SpaceSplitString& classNames() const;
@@ -512,36 +498,34 @@ public:
void setSavedLayerScrollOffset(const IntSize&);
ActiveAnimations* activeAnimations() const;
- ActiveAnimations* ensureActiveAnimations();
+ ActiveAnimations& ensureActiveAnimations();
bool hasActiveAnimations() const;
- InputMethodContext* inputMethodContext();
+ InputMethodContext& inputMethodContext();
bool hasInputMethodContext() const;
- virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE FINAL;
+ void setPrefix(const AtomicString&, ExceptionState&);
void synchronizeAttribute(const AtomicString& localName) const;
- bool needsPseudoElement(PseudoId, const RenderStyle&) const;
+ MutableStylePropertySet& ensureMutableInlineStyle();
+ void clearMutableInlineStyleIfEmpty();
+
+ void setTabIndex(int);
+ virtual short tabIndex() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
- Element(const QualifiedName& tagName, Document* document, ConstructionType type)
- : ContainerNode(document, type)
- , m_tagName(tagName)
- {
- ScriptWrappable::init(this);
- }
+ Element(const QualifiedName& tagName, Document*, ConstructionType);
void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, CSSValueID identifier);
- void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitTypes);
+ void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitType);
void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, const String& value);
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void removeAllEventListeners() OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange);
virtual void didRecalcStyle(StyleRecalcChange);
@@ -550,16 +534,17 @@ protected:
virtual bool shouldRegisterAsNamedItem() const { return false; }
virtual bool shouldRegisterAsExtraNamedItem() const { return false; }
+ virtual bool supportsSpatialNavigationFocus() const;
+
void clearTabIndexExplicitlyIfNeeded();
void setTabIndexExplicitly(short);
- virtual short tabIndex() const OVERRIDE;
// Subclasses may override this method to affect focusability. Unlike
// supportsFocus, this method must be called on an up-to-date layout, so it
// may use the renderer to reason about focusability. This method cannot be
// moved to RenderObject because some focusable nodes don't have renderers,
// e.g., HTMLOptionElement.
virtual bool rendererIsFocusable() const;
- PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
+ PassRefPtrWillBeRawPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
HTMLCollection* cachedHTMLCollection(CollectionType);
// classAttributeChanged() exists to share code between
@@ -572,6 +557,11 @@ protected:
Node* insertAdjacent(const String& where, Node* newChild, ExceptionState&);
private:
+ bool hasElementFlag(ElementFlags mask) const { return hasRareData() && hasElementFlagInternal(mask); }
+ void setElementFlag(ElementFlags, bool value = true);
+ void clearElementFlag(ElementFlags);
+ bool hasElementFlagInternal(ElementFlags) const;
+
void styleAttributeChanged(const AtomicString& newStyleString, AttributeModificationReason);
void updatePresentationAttributeStyle();
@@ -579,16 +569,11 @@ private:
void inlineStyleChanged();
PropertySetCSSStyleDeclaration* inlineStyleCSSOMWrapper();
void setInlineStyleFromString(const AtomicString&);
- MutableStylePropertySet* ensureMutableInlineStyle();
StyleRecalcChange recalcOwnStyle(StyleRecalcChange);
void recalcChildStyle(StyleRecalcChange);
- // FIXME: These methods should all be renamed to something better than "check",
- // since it's not clear that they alter the style bits of siblings and children.
- void checkForChildrenAdjacentRuleChanges();
- void checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta);
- inline void checkForEmptyStyleChange(RenderStyle*);
+ inline void checkForEmptyStyleChange();
void updatePseudoElement(PseudoId, StyleRecalcChange);
@@ -622,19 +607,19 @@ private:
virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
void setAttributeInternal(size_t index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
- void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
+ void appendAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
void removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute);
void attributeChangedFromParserOrByCloning(const QualifiedName&, const AtomicString&, AttributeModificationReason);
#ifndef NDEBUG
- virtual void formatForDebugger(char* buffer, unsigned length) const;
+ virtual void formatForDebugger(char* buffer, unsigned length) const OVERRIDE;
#endif
bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
void cancelFocusAppearanceUpdate();
- virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return computedStyle(pseudoElementSpecifier); }
+ virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE { return computedStyle(pseudoElementSpecifier); }
inline void updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle);
inline void removeCallbackSelectors();
@@ -642,29 +627,16 @@ private:
// cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
// are used instead.
- virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren();
QualifiedName m_tagName;
- bool rareDataStyleAffectedByEmpty() const;
- bool rareDataChildrenAffectedByFocus() const;
- bool rareDataChildrenAffectedByHover() const;
- bool rareDataChildrenAffectedByActive() const;
- bool rareDataChildrenAffectedByDrag() const;
- bool rareDataChildrenAffectedByFirstChildRules() const;
- bool rareDataChildrenAffectedByLastChildRules() const;
- bool rareDataChildrenAffectedByDirectAdjacentRules() const;
- bool rareDataChildrenAffectedByForwardPositionalRules() const;
- bool rareDataChildrenAffectedByBackwardPositionalRules() const;
- unsigned rareDataChildIndex() const;
SpellcheckAttributeState spellcheckAttributeState() const;
void updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
void updateExtraNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
- void unregisterNamedFlowContentNode();
-
void createUniqueElementData();
bool shouldInvalidateDistributionWhenAttributeChanged(ElementShadow*, const QualifiedName&, const AtomicString&);
@@ -672,6 +644,8 @@ private:
ElementRareData* elementRareData() const;
ElementRareData& ensureElementRareData();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList();
+ void removeAttrNodeList();
void detachAllAttrNodesFromElement();
void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
void detachAttrNodeAtIndex(Attr*, size_t index);
@@ -682,6 +656,32 @@ private:
};
DEFINE_NODE_TYPE_CASTS(Element, isElementNode());
+template <typename T> bool isElementOfType(const Element&);
+template <typename T> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const T>(toElement(node)); }
+template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
+
+// Type casting.
+template<typename T> inline T& toElement(Node& node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+ return static_cast<T&>(node);
+}
+template<typename T> inline T* toElement(Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+ return static_cast<T*>(node);
+}
+template<typename T> inline const T& toElement(const Node& node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+ return static_cast<const T&>(node);
+}
+template<typename T> inline const T* toElement(const Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+ return static_cast<const T*>(node);
+}
+template<typename T, typename U> inline T* toElement(const RefPtr<U>& node) { return toElement<T>(node.get()); }
inline bool isDisabledFormControl(const Node* node)
{
@@ -699,33 +699,17 @@ inline Element* Node::parentElement() const
return parent && parent->isElementNode() ? toElement(parent) : 0;
}
-inline Element* Node::previousElementSibling() const
-{
- Node* n = previousSibling();
- while (n && !n->isElementNode())
- n = n->previousSibling();
- return toElement(n);
-}
-
-inline Element* Node::nextElementSibling() const
-{
- Node* n = nextSibling();
- while (n && !n->isElementNode())
- n = n->nextSibling();
- return toElement(n);
-}
-
inline bool Element::fastHasAttribute(const QualifiedName& name) const
{
ASSERT(fastAttributeLookupAllowed(name));
- return elementData() && getAttributeItem(name);
+ return elementData() && findAttributeByName(name);
}
inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const
{
ASSERT(fastAttributeLookupAllowed(name));
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
return attribute->value();
}
return nullAtom;
@@ -733,7 +717,7 @@ inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name)
inline bool Element::hasAttributesWithoutUpdate() const
{
- return elementData() && !elementData()->isEmpty();
+ return elementData() && elementData()->hasAttributes();
}
inline const AtomicString& Element::idForStyleResolution() const
@@ -742,23 +726,18 @@ inline const AtomicString& Element::idForStyleResolution() const
return elementData()->idForStyleResolution();
}
-inline const AtomicString& Element::shadowPseudoId() const
-{
- return pseudo();
-}
-
inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const
{
// FIXME: This check is probably not correct for the case where the document has an id attribute
// with a non-null namespace, because it will return false, a false negative, if the prefixes
// don't match but the local name and namespace both do. However, since this has been like this
// for a while and the code paths may be hot, we'll have to measure performance if we fix it.
- return attributeName == document().idAttributeName();
+ return attributeName == HTMLNames::idAttr;
}
inline const AtomicString& Element::getIdAttribute() const
{
- return hasID() ? fastGetAttribute(document().idAttributeName()) : nullAtom;
+ return hasID() ? fastGetAttribute(HTMLNames::idAttr) : nullAtom;
}
inline const AtomicString& Element::getNameAttribute() const
@@ -775,14 +754,9 @@ inline const AtomicString& Element::getClassAttribute() const
return fastGetAttribute(HTMLNames::classAttr);
}
-inline bool Element::shouldIgnoreAttributeCase() const
-{
- return isHTMLElement() && document().isHTMLDocument();
-}
-
inline void Element::setIdAttribute(const AtomicString& value)
{
- setAttribute(document().idAttributeName(), value);
+ setAttribute(HTMLNames::idAttr, value);
}
inline const SpaceSplitString& Element::classNames() const
@@ -795,19 +769,19 @@ inline const SpaceSplitString& Element::classNames() const
inline size_t Element::attributeCount() const
{
ASSERT(elementData());
- return elementData()->length();
+ return elementData()->attributeCount();
}
-inline const Attribute* Element::attributeItem(unsigned index) const
+inline const Attribute& Element::attributeAt(unsigned index) const
{
ASSERT(elementData());
- return elementData()->attributeItem(index);
+ return elementData()->attributeAt(index);
}
-inline const Attribute* Element::getAttributeItem(const QualifiedName& name) const
+inline const Attribute* Element::findAttributeByName(const QualifiedName& name) const
{
ASSERT(elementData());
- return elementData()->getAttributeItem(name);
+ return elementData()->findAttributeByName(name);
}
inline bool Element::hasID() const
@@ -820,11 +794,11 @@ inline bool Element::hasClass() const
return elementData() && elementData()->hasClass();
}
-inline UniqueElementData* Element::ensureUniqueElementData()
+inline UniqueElementData& Element::ensureUniqueElementData()
{
if (!elementData() || !elementData()->isUnique())
createUniqueElementData();
- return static_cast<UniqueElementData*>(m_elementData.get());
+ return static_cast<UniqueElementData&>(*m_elementData);
}
// Put here to make them inline.
@@ -840,6 +814,8 @@ inline bool Node::hasClass() const
inline Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* insertionPoint)
{
+ ASSERT(!childNeedsStyleInvalidation());
+ ASSERT(!needsStyleInvalidation());
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
setFlag(InDocumentFlag);
@@ -855,7 +831,7 @@ inline void Node::removedFrom(ContainerNode* insertionPoint)
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
clearFlag(InDocumentFlag);
- if (isInShadowTree() && !treeScope().rootNode()->isShadowRoot())
+ if (isInShadowTree() && !treeScope().rootNode().isShadowRoot())
clearFlag(IsInShadowTreeFlag);
}
@@ -894,6 +870,24 @@ inline bool isShadowHost(const Element* element)
return element && element->shadow();
}
+// These macros do the same as their NODE equivalents but additionally provide a template specialization
+// for isElementOfType<>() so that the Traversal<> API works for these Element types.
+#define DEFINE_ELEMENT_TYPE_CASTS(thisType, predicate) \
+ template <> inline bool isElementOfType<const thisType>(const Element& element) { return element.predicate; } \
+ DEFINE_NODE_TYPE_CASTS(thisType, predicate)
+
+#define DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
+ template <> inline bool isElementOfType<const thisType>(const Element& element) { return is##thisType(element); } \
+ DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType)
+
+#define DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
+ static PassRefPtrWillBeRawPtr<T> create(const QualifiedName&, Document&)
+#define DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
+ PassRefPtrWillBeRawPtr<T> T::create(const QualifiedName& tagName, Document& document) \
+ { \
+ return adoptRefWillBeNoop(new T(tagName, document)); \
+ }
+
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.idl b/chromium/third_party/WebKit/Source/core/dom/Element.idl
index ac5003883ee..b4f745d34bf 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Element.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Element.idl
@@ -19,33 +19,33 @@
*/
[
- SpecialWrapFor=HTMLElement|SVGElement
+ SpecialWrapFor=HTMLElement|SVGElement,
] interface Element : Node {
// DOM Level 1 Core
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString tagName;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString tagName;
[TreatReturnedNullStringAs=Null] DOMString getAttribute(DOMString name);
[RaisesException, CustomElementCallbacks] void setAttribute(DOMString name, DOMString value);
[CustomElementCallbacks] void removeAttribute(DOMString name);
[MeasureAs=ElementGetAttributeNode] Attr getAttributeNode([Default=Undefined] optional DOMString name); // Removed from DOM4.
- [RaisesException, CustomElementCallbacks, MeasureAs=ElementSetAttributeNode] Attr setAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr newAttr); // Removed from DOM4.
- [RaisesException, CustomElementCallbacks, MeasureAs=ElementRemoveAttributeNode] Attr removeAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr oldAttr); // Removed from DOM4.
- [PerWorldBindings] NodeList getElementsByTagName(DOMString name);
+ [RaisesException, CustomElementCallbacks, MeasureAs=ElementSetAttributeNode] Attr setAttributeNode([Default=Undefined, TypeChecking=Nullable] optional Attr newAttr); // Removed from DOM4.
+ [RaisesException, CustomElementCallbacks, MeasureAs=ElementRemoveAttributeNode] Attr removeAttributeNode([Default=Undefined, TypeChecking=Nullable] optional Attr oldAttr); // Removed from DOM4.
+ HTMLCollection getElementsByTagName(DOMString name);
- [PerWorldBindings] readonly attribute NamedNodeMap attributes;
+ [PerWorldBindings, ImplementedAs=attributesForBindings] readonly attribute NamedNodeMap attributes;
[MeasureAs=HasAttributes] boolean hasAttributes();
// DOM Level 2 Core
- DOMString getAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
+ [TreatReturnedNullStringAs=Null] DOMString getAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
[RaisesException, CustomElementCallbacks] void setAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName, DOMString value);
[CustomElementCallbacks] void removeAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
- NodeList getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
- [MeasureAs=ElementGetAttributeNodeNS] Attr getAttributeNodeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+ HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
+ [MeasureAs=ElementGetAttributeNodeNS] Attr getAttributeNodeNS([TreatNullAs=NullString, Default=Undefined] optional DOMString namespaceURI,
[Default=Undefined] optional DOMString localName); // Removed from DOM4.
- [RaisesException, CustomElementCallbacks, MeasureAs=ElementSetAttributeNodeNS] Attr setAttributeNodeNS([Default=Undefined, StrictTypeChecking] optional Attr newAttr); // Removed from DOM4.
+ [RaisesException, CustomElementCallbacks, DeprecateAs=ElementSetAttributeNodeNS] Attr setAttributeNodeNS([Default=Undefined, TypeChecking=Nullable] optional Attr newAttr); // Removed from DOM4.
boolean hasAttribute(DOMString name);
boolean hasAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
@@ -53,25 +53,32 @@
// DOM4
[Reflect] attribute DOMString id;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString namespaceURI;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, RaisesException=Setter] attribute DOMString prefix;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString localName;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString namespaceURI;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, RaisesException=Setter] attribute DOMString prefix;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString localName;
+
+ [RaisesException] boolean matches(DOMString selectors);
// Common extensions
- [PerWorldBindings] readonly attribute long offsetLeft;
- [PerWorldBindings] readonly attribute long offsetTop;
- [PerWorldBindings] readonly attribute long offsetWidth;
- [PerWorldBindings] readonly attribute long offsetHeight;
- [ImplementedAs=bindingsOffsetParent, PerWorldBindings] readonly attribute Element offsetParent;
- [PerWorldBindings] readonly attribute long clientLeft;
- [PerWorldBindings] readonly attribute long clientTop;
- [PerWorldBindings] readonly attribute long clientWidth;
- [PerWorldBindings] readonly attribute long clientHeight;
- [PerWorldBindings] attribute long scrollLeft;
- [PerWorldBindings] attribute long scrollTop;
- [PerWorldBindings] readonly attribute long scrollWidth;
- [PerWorldBindings] readonly attribute long scrollHeight;
+ readonly attribute long offsetLeft;
+ readonly attribute long offsetTop;
+ readonly attribute long offsetWidth;
+ readonly attribute long offsetHeight;
+ [ImplementedAs=offsetParentForBindings, PerWorldBindings] readonly attribute Element offsetParent;
+ readonly attribute long clientLeft;
+ readonly attribute long clientTop;
+ readonly attribute long clientWidth;
+ readonly attribute long clientHeight;
+
+ // FIXME: should be:
+ // attribute (Dictionary or double) scrollLeft;
+ // attribute (Dictionary or double) scrollTop;
+ // http://crbug.com/240176
+ [Custom=Setter] attribute long scrollLeft;
+ [Custom=Setter] attribute long scrollTop;
+ readonly attribute long scrollWidth;
+ readonly attribute long scrollHeight;
void focus();
void blur();
@@ -79,38 +86,31 @@
// WebKit extensions
- void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
- void scrollByLines([Default=Undefined] optional long lines);
- void scrollByPages([Default=Undefined] optional long pages);
+ [MeasureAs=ElementScrollIntoViewIfNeeded] void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
+ [MeasureAs=ElementScrollByLines] void scrollByLines([Default=Undefined] optional long lines);
+ [MeasureAs=ElementScrollByPages] void scrollByPages([Default=Undefined] optional long pages);
// HTML 5
- NodeList getElementsByClassName(DOMString classNames);
- [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, RaisesException=Setter] attribute DOMString innerHTML;
+ HTMLCollection getElementsByClassName(DOMString classNames);
+ [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, LogActivity=SetterOnly, RaisesException=Setter] attribute DOMString innerHTML;
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter] attribute DOMString outerHTML;
- [CustomElementCallbacks, RaisesException] void insertAdjacentHTML(DOMString where, DOMString html);
- [Reflect=class, PerWorldBindings] attribute DOMString className;
+ [RaisesException, CustomElementCallbacks, MeasureAs=InsertAdjacentElement] Element insertAdjacentElement(DOMString where, Element element);
+ [RaisesException, MeasureAs=InsertAdjacentText] void insertAdjacentText(DOMString where, DOMString text);
+ [CustomElementCallbacks, RaisesException, MeasureAs=InsertAdjacentHTML] void insertAdjacentHTML(DOMString where, DOMString html);
+
+ [Reflect=class] attribute DOMString className;
[PerWorldBindings] readonly attribute DOMTokenList classList;
[PerWorldBindings] readonly attribute DOMStringMap dataset;
- // NodeSelector - Selector API
- [RaisesException] Element querySelector(DOMString selectors);
- [RaisesException] NodeList querySelectorAll(DOMString selectors);
-
// WebKit extension
- [RaisesException, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector([Default=Undefined] optional DOMString selectors);
+ [RaisesException, ImplementedAs=matches, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector(DOMString selectors);
// Shadow DOM API
- [RuntimeEnabled=ShadowDOM, Reflect, TreatNullAs=NullString, PerWorldBindings] attribute DOMString pseudo;
- [RuntimeEnabled=ShadowDOM, RaisesException] ShadowRoot createShadowRoot();
- [RuntimeEnabled=ShadowDOM, PerWorldBindings] readonly attribute ShadowRoot shadowRoot;
- [RuntimeEnabled=ShadowDOM, PerWorldBindings] NodeList getDestinationInsertionPoints();
-
- // To-be-deprecated prefixed Shadow DOM API
- [Reflect=pseudo, TreatNullAs=NullString, ImplementedAs=pseudo, PerWorldBindings, MeasureAs=ShadowDOMPrefixedPseudo] attribute DOMString webkitPseudo;
- [ImplementedAs=createShadowRoot, RaisesException, MeasureAs=ShadowDOMPrefixedCreateShadowRoot] ShadowRoot webkitCreateShadowRoot();
- [ImplementedAs=shadowRoot, PerWorldBindings, MeasureAs=ShadowDOMPrefixedShadowRoot] readonly attribute ShadowRoot webkitShadowRoot;
+ [RaisesException, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
+ [PerWorldBindings] readonly attribute ShadowRoot shadowRoot;
+ NodeList getDestinationInsertionPoints();
// CSSOM View Module API
ClientRectList getClientRects();
@@ -118,16 +118,13 @@
// Mozilla version
const unsigned short ALLOW_KEYBOARD_INPUT = 1;
- [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
+ [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
// W3C version
- [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
-
- void webkitRequestPointerLock();
+ [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
- // CSS Regions API
- [RuntimeEnabled=CSSRegions, PerWorldBindings] readonly attribute DOMString webkitRegionOverset;
- [RuntimeEnabled=CSSRegions] sequence<Range> webkitGetRegionFlowRanges();
+ [MeasureAs=PrefixedElementRequestPointerLock] void webkitRequestPointerLock();
+ [MeasureAs=ElementRequestPointerLock] void requestPointerLock();
// Event handler attributes
attribute EventHandler onbeforecopy;
@@ -144,7 +141,7 @@
[RuntimeEnabled=Touch] attribute EventHandler ontouchstart;
attribute EventHandler onwebkitfullscreenchange;
attribute EventHandler onwebkitfullscreenerror;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onwheel;
+ [LogActivity=SetterOnly] attribute EventHandler onwheel;
};
Element implements ParentNode;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp b/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp
index 2ce4aa0413a..77428a688ea 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp
@@ -70,7 +70,7 @@ ElementData::ElementData(unsigned arraySize)
ElementData::ElementData(const ElementData& other, bool isUnique)
: m_isUnique(isUnique)
- , m_arraySize(isUnique ? 0 : other.length())
+ , m_arraySize(isUnique ? 0 : other.attributeCount())
, m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
, m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
, m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
@@ -98,48 +98,52 @@ PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
bool ElementData::isEquivalent(const ElementData* other) const
{
if (!other)
- return isEmpty();
+ return !hasAttributes();
- unsigned len = length();
- if (len != other->length())
+ AttributeCollection attributes = this->attributes();
+ if (attributes.size() != other->attributeCount())
return false;
- for (unsigned i = 0; i < len; i++) {
- const Attribute* attribute = attributeItem(i);
- const Attribute* otherAttr = other->getAttributeItem(attribute->name());
- if (!otherAttr || attribute->value() != otherAttr->value())
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ const Attribute* otherAttr = other->findAttributeByName(it->name());
+ if (!otherAttr || it->value() != otherAttr->value())
return false;
}
-
return true;
}
-size_t ElementData::getAttrIndex(Attr* attr) const
+size_t ElementData::findAttrNodeIndex(Attr* attr) const
{
// This relies on the fact that Attr's QualifiedName == the Attribute's name.
- for (unsigned i = 0; i < length(); ++i) {
- if (attributeItem(i)->name() == attr->qualifiedName())
- return i;
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
+ if (it->name() == attr->qualifiedName())
+ return index;
}
return kNotFound;
}
-size_t ElementData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+size_t ElementData::findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
// Continue to checking case-insensitively and/or full namespaced names if necessary:
- for (unsigned i = 0; i < length(); ++i) {
- const Attribute* attribute = attributeItem(i);
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
// FIXME: Why check the prefix? Namespace is all that should matter
// and all HTML/SVG attributes have a null namespace!
- if (!attribute->name().hasPrefix()) {
- if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute->localName()))
- return i;
+ if (!it->name().hasPrefix()) {
+ if (shouldIgnoreAttributeCase && equalIgnoringCase(name, it->localName()))
+ return index;
} else {
// FIXME: Would be faster to do this comparison without calling toString, which
// generates a temporary string by concatenation. But this branch is only reached
// if the attribute name has a prefix, which is rare in HTML.
- if (equalPossiblyIgnoringCase(name, attribute->name().toString(), shouldIgnoreAttributeCase))
- return i;
+ if (equalPossiblyIgnoringCase(name, it->name().toString(), shouldIgnoreAttributeCase))
+ return index;
}
}
return kNotFound;
@@ -164,7 +168,6 @@ ShareableElementData::ShareableElementData(const UniqueElementData& other)
ASSERT(!other.m_presentationAttributeStyle);
if (other.m_inlineStyle) {
- ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
}
@@ -187,7 +190,7 @@ UniqueElementData::UniqueElementData(const UniqueElementData& other)
, m_presentationAttributeStyle(other.m_presentationAttributeStyle)
, m_attributeVector(other.m_attributeVector)
{
- m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
+ m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : nullptr;
}
UniqueElementData::UniqueElementData(const ShareableElementData& other)
@@ -197,8 +200,9 @@ UniqueElementData::UniqueElementData(const ShareableElementData& other)
ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
m_inlineStyle = other.m_inlineStyle;
- m_attributeVector.reserveCapacity(other.length());
- for (unsigned i = 0; i < other.length(); ++i)
+ unsigned length = other.attributeCount();
+ m_attributeVector.reserveCapacity(length);
+ for (unsigned i = 0; i < length; ++i)
m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
}
@@ -213,9 +217,10 @@ PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
return adoptRef(new (slot) ShareableElementData(*this));
}
-Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
+Attribute* UniqueElementData::findAttributeByName(const QualifiedName& name)
{
- for (unsigned i = 0; i < length(); ++i) {
+ unsigned length = m_attributeVector.size();
+ for (unsigned i = 0; i < length; ++i) {
if (m_attributeVector.at(i).name().matches(name))
return &m_attributeVector.at(i);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementData.h b/chromium/third_party/WebKit/Source/core/dom/ElementData.h
index 2426667d6c2..0a8cc6202a0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementData.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -42,6 +43,27 @@ class ShareableElementData;
class StylePropertySet;
class UniqueElementData;
+class AttributeCollection {
+public:
+ typedef const Attribute* const_iterator;
+
+ AttributeCollection(const Attribute* array, unsigned size)
+ : m_array(array)
+ , m_size(size)
+ { }
+
+ const_iterator begin() const { return m_array; }
+ const_iterator end() const { return m_array + m_size; }
+
+ unsigned size() const { return m_size; }
+
+private:
+ const Attribute* m_array;
+ unsigned m_size;
+};
+
+// ElementData represents very common, but not necessarily unique to an element,
+// data such as attributes, inline style, and parsed class names and ids.
class ElementData : public RefCounted<ElementData> {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -60,14 +82,17 @@ public:
const StylePropertySet* presentationAttributeStyle() const;
- size_t length() const;
- bool isEmpty() const { return !length(); }
+ // This is not a trivial getter and its return value should be cached for performance.
+ size_t attributeCount() const;
+ bool hasAttributes() const { return !!attributeCount(); }
+
+ AttributeCollection attributes() const;
- const Attribute* attributeItem(unsigned index) const;
- const Attribute* getAttributeItem(const QualifiedName&) const;
- size_t getAttributeItemIndex(const QualifiedName&, bool shouldIgnoreCase = false) const;
- size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
- size_t getAttrIndex(Attr*) const;
+ const Attribute& attributeAt(unsigned index) const;
+ const Attribute* findAttributeByName(const QualifiedName&) const;
+ size_t findAttributeIndexByName(const QualifiedName&, bool shouldIgnoreCase = false) const;
+ size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ size_t findAttrNodeIndex(Attr*) const;
bool hasID() const { return !m_idForStyleResolution.isNull(); }
bool hasClass() const { return !m_classNames.isNull(); }
@@ -81,6 +106,7 @@ protected:
explicit ElementData(unsigned arraySize);
ElementData(const ElementData&, bool isUnique);
+ // Keep the type in a bitfield instead of using virtual destructors to avoid adding a vtable.
unsigned m_isUnique : 1;
unsigned m_arraySize : 28;
mutable unsigned m_presentationAttributeStyleIsDirty : 1;
@@ -100,8 +126,8 @@ private:
void destroy();
const Attribute* attributeBase() const;
- const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
- size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ const Attribute* findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ size_t findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
PassRefPtr<UniqueElementData> makeUniqueCopy() const;
};
@@ -111,7 +137,11 @@ private:
#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
#endif
-class ShareableElementData : public ElementData {
+// SharableElementData is managed by ElementDataCache and is produced by
+// the parser during page load for elements that have identical attributes. This
+// is a memory optimization since it's very common for many elements to have
+// duplicate sets of attributes (ex. the same classes).
+class ShareableElementData FINAL : public ElementData {
public:
static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
@@ -126,22 +156,32 @@ public:
#pragma warning(pop)
#endif
-class UniqueElementData : public ElementData {
+// UniqueElementData is created when an element needs to mutate its attributes
+// or gains presentation attribute style (ex. width="10"). It does not need to
+// be created to fill in values in the ElementData that are derived from
+// attributes. For example populating the m_inlineStyle from the style attribute
+// doesn't require a UniqueElementData as all elements with the same style
+// attribute will have the same inline style.
+class UniqueElementData FINAL : public ElementData {
public:
static PassRefPtr<UniqueElementData> create();
PassRefPtr<ShareableElementData> makeShareableCopy() const;
// These functions do no error/duplicate checking.
- void addAttribute(const QualifiedName&, const AtomicString&);
- void removeAttribute(size_t index);
+ void appendAttribute(const QualifiedName&, const AtomicString&);
+ void removeAttributeAt(size_t index);
- Attribute* attributeItem(unsigned index);
- Attribute* getAttributeItem(const QualifiedName&);
+ Attribute& attributeAt(unsigned index);
+ Attribute* findAttributeByName(const QualifiedName&);
UniqueElementData();
explicit UniqueElementData(const ShareableElementData&);
explicit UniqueElementData(const UniqueElementData&);
+ // FIXME: We might want to support sharing element data for elements with
+ // presentation attribute style. Lots of table cells likely have the same
+ // attributes. Most modern pages don't use presentation attributes though
+ // so this might not make sense.
mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
Vector<Attribute, 4> m_attributeVector;
};
@@ -153,7 +193,7 @@ inline void ElementData::deref()
destroy();
}
-inline size_t ElementData::length() const
+inline size_t ElementData::attributeCount() const
{
if (isUnique())
return static_cast<const UniqueElementData*>(this)->m_attributeVector.size();
@@ -167,11 +207,11 @@ inline const StylePropertySet* ElementData::presentationAttributeStyle() const
return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get();
}
-inline const Attribute* ElementData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+inline const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
- size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
+ size_t index = findAttributeIndexByName(name, shouldIgnoreAttributeCase);
if (index != kNotFound)
- return attributeItem(index);
+ return &attributeAt(index);
return 0;
}
@@ -182,76 +222,84 @@ inline const Attribute* ElementData::attributeBase() const
return static_cast<const ShareableElementData*>(this)->m_attributeArray;
}
-inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool shouldIgnoreCase) const
+inline size_t ElementData::findAttributeIndexByName(const QualifiedName& name, bool shouldIgnoreCase) const
{
- const Attribute* begin = attributeBase();
- // Cache length for performance as ElementData::length() contains a conditional branch.
- unsigned len = length();
- for (unsigned i = 0; i < len; ++i) {
- const Attribute& attribute = begin[i];
- if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
- return i;
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
+ if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
+ return index;
}
return kNotFound;
}
// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
-inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+inline size_t ElementData::findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
- // Cache length for performance as ElementData::length() contains a conditional branch.
- unsigned len = length();
bool doSlowCheck = shouldIgnoreAttributeCase;
// Optimize for the case where the attribute exists and its name exactly matches.
- const Attribute* begin = attributeBase();
- for (unsigned i = 0; i < len; ++i) {
- const Attribute& attribute = begin[i];
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
// FIXME: Why check the prefix? Namespaces should be all that matter.
// Most attributes (all of HTML and CSS) have no namespace.
- if (!attribute.name().hasPrefix()) {
- if (name == attribute.localName())
- return i;
+ if (!it->name().hasPrefix()) {
+ if (name == it->localName())
+ return index;
} else {
doSlowCheck = true;
}
}
if (doSlowCheck)
- return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
+ return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase);
return kNotFound;
}
-inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
+inline AttributeCollection ElementData::attributes() const
+{
+ if (isUnique()) {
+ const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueElementData*>(this)->m_attributeVector;
+ return AttributeCollection(attributeVector.data(), attributeVector.size());
+ }
+ return AttributeCollection(static_cast<const ShareableElementData*>(this)->m_attributeArray, m_arraySize);
+}
+
+inline const Attribute* ElementData::findAttributeByName(const QualifiedName& name) const
{
- const Attribute* begin = attributeBase();
- for (unsigned i = 0; i < length(); ++i) {
- const Attribute& attribute = begin[i];
- if (attribute.name().matches(name))
- return &attribute;
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->name().matches(name))
+ return it;
}
return 0;
}
-inline const Attribute* ElementData::attributeItem(unsigned index) const
+inline const Attribute& ElementData::attributeAt(unsigned index) const
{
- RELEASE_ASSERT(index < length());
- return attributeBase() + index;
+ RELEASE_ASSERT(index < attributeCount());
+ ASSERT(attributeBase() + index);
+ return *(attributeBase() + index);
}
-inline void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
+inline void UniqueElementData::appendAttribute(const QualifiedName& attributeName, const AtomicString& value)
{
m_attributeVector.append(Attribute(attributeName, value));
}
-inline void UniqueElementData::removeAttribute(size_t index)
+inline void UniqueElementData::removeAttributeAt(size_t index)
{
m_attributeVector.remove(index);
}
-inline Attribute* UniqueElementData::attributeItem(unsigned index)
+inline Attribute& UniqueElementData::attributeAt(unsigned index)
{
- return &m_attributeVector.at(index);
+ return m_attributeVector.at(index);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp
new file mode 100644
index 00000000000..9d0cbdad6c2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/ElementDataCache.h"
+
+#include "core/dom/ElementData.h"
+
+namespace WebCore {
+
+inline unsigned attributeHash(const Vector<Attribute>& attributes)
+{
+ return StringHasher::hashMemory(attributes.data(), attributes.size() * sizeof(Attribute));
+}
+
+inline bool hasSameAttributes(const Vector<Attribute>& attributes, ShareableElementData& elementData)
+{
+ if (attributes.size() != elementData.attributeCount())
+ return false;
+ return !memcmp(attributes.data(), elementData.m_attributeArray, attributes.size() * sizeof(Attribute));
+}
+
+PassRefPtr<ShareableElementData> ElementDataCache::cachedShareableElementDataWithAttributes(const Vector<Attribute>& attributes)
+{
+ ASSERT(!attributes.isEmpty());
+
+ ShareableElementDataCache::ValueType* it = m_shareableElementDataCache.add(attributeHash(attributes), nullptr).storedValue;
+
+ // FIXME: This prevents sharing when there's a hash collision.
+ if (it->value && !hasSameAttributes(attributes, *it->value))
+ return ShareableElementData::createWithAttributes(attributes);
+
+ if (!it->value)
+ it->value = ShareableElementData::createWithAttributes(attributes);
+
+ return it->value.get();
+}
+
+ElementDataCache::ElementDataCache()
+{
+}
+
+ElementDataCache::~ElementDataCache()
+{
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h
index 2f827db60a0..d275f1edd37 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h
@@ -24,11 +24,14 @@
*
*/
-#ifndef DocumentSharedObjectPool_h
-#define DocumentSharedObjectPool_h
+#ifndef ElementDataCache_h
+#define ElementDataCache_h
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"
namespace WebCore {
@@ -37,17 +40,17 @@ class Attribute;
class ShareableElementData;
class ShareableElementDataCacheEntry;
-class DocumentSharedObjectPool {
+class ElementDataCache {
public:
- static PassOwnPtr<DocumentSharedObjectPool> create() { return adoptPtr(new DocumentSharedObjectPool); }
- ~DocumentSharedObjectPool();
+ static PassOwnPtr<ElementDataCache> create() { return adoptPtr(new ElementDataCache); }
+ ~ElementDataCache();
PassRefPtr<ShareableElementData> cachedShareableElementDataWithAttributes(const Vector<Attribute>&);
private:
- DocumentSharedObjectPool();
+ ElementDataCache();
- typedef HashMap<unsigned, OwnPtr<ShareableElementDataCacheEntry>, AlreadyHashed> ShareableElementDataCache;
+ typedef HashMap<unsigned, RefPtr<ShareableElementData>, AlreadyHashed> ShareableElementDataCache;
ShareableElementDataCache m_shareableElementDataCache;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp
index ef6d2c26fb7..30888559606 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp
@@ -31,20 +31,49 @@
#include "config.h"
#include "core/dom/ElementRareData.h"
-#include "core/rendering/RegionOversetState.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
struct SameSizeAsElementRareData : NodeRareData {
short indices[2];
- unsigned bitfields;
- RegionOversetState regionOversetState;
LayoutSize sizeForResizing;
IntSize scrollOffset;
- void* pointers[10];
+ void* pointers[13];
};
+CSSStyleDeclaration& ElementRareData::ensureInlineCSSStyleDeclaration(Element* ownerElement)
+{
+ if (!m_cssomWrapper)
+ m_cssomWrapper = adoptPtrWillBeNoop(new InlineCSSStyleDeclaration(ownerElement));
+ return *m_cssomWrapper;
+}
+
+WillBeHeapVector<RefPtrWillBeMember<Attr> >& ElementRareData::ensureAttrNodeList()
+{
+ if (!m_attrNodeList)
+ m_attrNodeList = adoptPtrWillBeNoop(new WillBeHeapVector<RefPtrWillBeMember<Attr> >());
+ return *m_attrNodeList;
+}
+
+void ElementRareData::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_dataset);
+ visitor->trace(m_classList);
+ visitor->trace(m_shadow);
+ visitor->trace(m_attributeMap);
+#if ENABLE(OILPAN)
+ visitor->trace(m_attrNodeList);
+#endif
+ visitor->trace(m_inputMethodContext);
+ visitor->trace(m_activeAnimations);
+ visitor->trace(m_cssomWrapper);
+ visitor->trace(m_generatedBefore);
+ visitor->trace(m_generatedAfter);
+ visitor->trace(m_backdrop);
+ NodeRareData::traceAfterDispatch(visitor);
+}
+
COMPILE_ASSERT(sizeof(ElementRareData) == sizeof(SameSizeAsElementRareData), ElementRareDataShouldStaySmall);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h
index a1879973aa5..ff28414a606 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h
@@ -23,14 +23,17 @@
#define ElementRareData_h
#include "core/animation/ActiveAnimations.h"
+#include "core/dom/Attr.h"
#include "core/dom/DatasetDOMStringMap.h"
#include "core/dom/NamedNodeMap.h"
#include "core/dom/NodeRareData.h"
#include "core/dom/PseudoElement.h"
+#include "core/dom/custom/CustomElementDefinition.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/html/ClassList.h"
#include "core/html/ime/InputMethodContext.h"
#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/heap/Handle.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -39,63 +42,33 @@ class HTMLElement;
class ElementRareData : public NodeRareData {
public:
- static PassOwnPtr<ElementRareData> create(RenderObject* renderer) { return adoptPtr(new ElementRareData(renderer)); }
+ static ElementRareData* create(RenderObject* renderer)
+ {
+ return new ElementRareData(renderer);
+ }
~ElementRareData();
- void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
+ void setPseudoElement(PseudoId, PassRefPtrWillBeRawPtr<PseudoElement>);
PseudoElement* pseudoElement(PseudoId) const;
void resetStyleState();
- void resetDynamicRestyleObservations();
-
- short tabIndex() const { return m_tabIndex; }
- void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; }
- bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; }
- void clearTabIndexExplicitly() { m_tabIndex = 0; m_tabIndexWasSetExplicitly = false; }
-
- bool needsFocusAppearanceUpdateSoonAfterAttach() const { return m_needsFocusAppearanceUpdateSoonAfterAttach; }
- void setNeedsFocusAppearanceUpdateSoonAfterAttach(bool needs) { m_needsFocusAppearanceUpdateSoonAfterAttach = needs; }
-
- bool styleAffectedByEmpty() const { return m_styleAffectedByEmpty; }
- void setStyleAffectedByEmpty(bool value) { m_styleAffectedByEmpty = value; }
-
- bool isInCanvasSubtree() const { return m_isInCanvasSubtree; }
- void setIsInCanvasSubtree(bool value) { m_isInCanvasSubtree = value; }
-
- bool isInsideRegion() const { return m_isInsideRegion; }
- void setIsInsideRegion(bool value) { m_isInsideRegion = value; }
-
- RegionOversetState regionOversetState() const { return m_regionOversetState; }
- void setRegionOversetState(RegionOversetState state) { m_regionOversetState = state; }
-
- bool containsFullScreenElement() { return m_containsFullScreenElement; }
- void setContainsFullScreenElement(bool value) { m_containsFullScreenElement = value; }
-
- bool isInTopLayer() const { return m_isInTopLayer; }
- void setIsInTopLayer(bool value) { m_isInTopLayer = value; }
-
- bool childrenAffectedByFocus() const { return m_childrenAffectedByFocus; }
- void setChildrenAffectedByFocus(bool value) { m_childrenAffectedByFocus = value; }
- bool childrenAffectedByHover() const { return m_childrenAffectedByHover; }
- void setChildrenAffectedByHover(bool value) { m_childrenAffectedByHover = value; }
- bool childrenAffectedByActive() const { return m_childrenAffectedByActive; }
- void setChildrenAffectedByActive(bool value) { m_childrenAffectedByActive = value; }
- bool childrenAffectedByDrag() const { return m_childrenAffectedByDrag; }
- void setChildrenAffectedByDrag(bool value) { m_childrenAffectedByDrag = value; }
-
- bool childrenAffectedByFirstChildRules() const { return m_childrenAffectedByFirstChildRules; }
- void setChildrenAffectedByFirstChildRules(bool value) { m_childrenAffectedByFirstChildRules = value; }
- bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; }
- void setChildrenAffectedByLastChildRules(bool value) { m_childrenAffectedByLastChildRules = value; }
- bool childrenAffectedByDirectAdjacentRules() const { return m_childrenAffectedByDirectAdjacentRules; }
- void setChildrenAffectedByDirectAdjacentRules(bool value) { m_childrenAffectedByDirectAdjacentRules = value; }
- bool childrenAffectedByForwardPositionalRules() const { return m_childrenAffectedByForwardPositionalRules; }
- void setChildrenAffectedByForwardPositionalRules(bool value) { m_childrenAffectedByForwardPositionalRules = value; }
- bool childrenAffectedByBackwardPositionalRules() const { return m_childrenAffectedByBackwardPositionalRules; }
- void setChildrenAffectedByBackwardPositionalRules(bool value) { m_childrenAffectedByBackwardPositionalRules = value; }
- unsigned childIndex() const { return m_childIndex; }
- void setChildIndex(unsigned index) { m_childIndex = index; }
+
+ short tabIndex() const { return m_tabindex; }
+
+ void setTabIndexExplicitly(short index)
+ {
+ m_tabindex = index;
+ setElementFlag(TabIndexWasSetExplicitly, true);
+ }
+
+ void clearTabIndexExplicitly()
+ {
+ m_tabindex = 0;
+ clearElementFlag(TabIndexWasSetExplicitly);
+ }
+
+ CSSStyleDeclaration& ensureInlineCSSStyleDeclaration(Element* ownerElement);
void clearShadow() { m_shadow = nullptr; }
ElementShadow* shadow() const { return m_shadow.get(); }
@@ -107,14 +80,14 @@ public:
}
NamedNodeMap* attributeMap() const { return m_attributeMap.get(); }
- void setAttributeMap(PassOwnPtr<NamedNodeMap> attributeMap) { m_attributeMap = attributeMap; }
+ void setAttributeMap(PassOwnPtrWillBeRawPtr<NamedNodeMap> attributeMap) { m_attributeMap = attributeMap; }
RenderStyle* computedStyle() const { return m_computedStyle.get(); }
void setComputedStyle(PassRefPtr<RenderStyle> computedStyle) { m_computedStyle = computedStyle; }
- void clearComputedStyle() { m_computedStyle = 0; }
+ void clearComputedStyle() { m_computedStyle = nullptr; }
ClassList* classList() const { return m_classList.get(); }
- void setClassList(PassOwnPtr<ClassList> classList) { m_classList = classList; }
+ void setClassList(PassOwnPtrWillBeRawPtr<ClassList> classList) { m_classList = classList; }
void clearClassListValueForQuirksMode()
{
if (!m_classList)
@@ -123,7 +96,7 @@ public:
}
DatasetDOMStringMap* dataset() const { return m_dataset.get(); }
- void setDataset(PassOwnPtr<DatasetDOMStringMap> dataset) { m_dataset = dataset; }
+ void setDataset(PassOwnPtrWillBeRawPtr<DatasetDOMStringMap> dataset) { m_dataset = dataset; }
LayoutSize minimumSizeForResizing() const { return m_minimumSizeForResizing; }
void setMinimumSizeForResizing(LayoutSize size) { m_minimumSizeForResizing = size; }
@@ -132,66 +105,54 @@ public:
void setSavedLayerScrollOffset(IntSize size) { m_savedLayerScrollOffset = size; }
ActiveAnimations* activeAnimations() { return m_activeAnimations.get(); }
- void setActiveAnimations(PassOwnPtr<ActiveAnimations> activeAnimations)
+ void setActiveAnimations(PassOwnPtrWillBeRawPtr<ActiveAnimations> activeAnimations)
{
m_activeAnimations = activeAnimations;
}
- bool hasPendingResources() const { return m_hasPendingResources; }
- void setHasPendingResources(bool has) { m_hasPendingResources = has; }
-
bool hasInputMethodContext() const { return m_inputMethodContext; }
- InputMethodContext* ensureInputMethodContext(HTMLElement* element)
+ InputMethodContext& ensureInputMethodContext(HTMLElement* element)
{
if (!m_inputMethodContext)
m_inputMethodContext = InputMethodContext::create(element);
- return m_inputMethodContext.get();
+ return *m_inputMethodContext;
}
bool hasPseudoElements() const;
+ void clearPseudoElements();
+
+ void setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition) { m_customElementDefinition = definition; }
+ CustomElementDefinition* customElementDefinition() const { return m_customElementDefinition.get(); }
+
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList() { return m_attrNodeList.get(); }
+ void removeAttrNodeList() { m_attrNodeList.clear(); }
+
+ void traceAfterDispatch(Visitor*);
private:
- short m_tabIndex;
- unsigned short m_childIndex;
- unsigned m_tabIndexWasSetExplicitly : 1;
- unsigned m_needsFocusAppearanceUpdateSoonAfterAttach : 1;
- unsigned m_styleAffectedByEmpty : 1;
- unsigned m_isInCanvasSubtree : 1;
- unsigned m_containsFullScreenElement : 1;
- unsigned m_isInTopLayer : 1;
- unsigned m_hasPendingResources : 1;
- unsigned m_childrenAffectedByFocus : 1;
- unsigned m_childrenAffectedByHover : 1;
- unsigned m_childrenAffectedByActive : 1;
- unsigned m_childrenAffectedByDrag : 1;
- // Bits for dynamic child matching.
- // We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
- // *-child-of-type, we will just give up and re-evaluate whenever children change at all.
- unsigned m_childrenAffectedByFirstChildRules : 1;
- unsigned m_childrenAffectedByLastChildRules : 1;
- unsigned m_childrenAffectedByDirectAdjacentRules : 1;
- unsigned m_childrenAffectedByForwardPositionalRules : 1;
- unsigned m_childrenAffectedByBackwardPositionalRules : 1;
-
- unsigned m_isInsideRegion : 1;
- RegionOversetState m_regionOversetState;
+ short m_tabindex;
LayoutSize m_minimumSizeForResizing;
IntSize m_savedLayerScrollOffset;
- RefPtr<RenderStyle> m_computedStyle;
- OwnPtr<DatasetDOMStringMap> m_dataset;
- OwnPtr<ClassList> m_classList;
- OwnPtr<ElementShadow> m_shadow;
- OwnPtr<NamedNodeMap> m_attributeMap;
- OwnPtr<InputMethodContext> m_inputMethodContext;
- OwnPtr<ActiveAnimations> m_activeAnimations;
+ OwnPtrWillBeMember<DatasetDOMStringMap> m_dataset;
+ OwnPtrWillBeMember<ClassList> m_classList;
+ OwnPtrWillBeMember<ElementShadow> m_shadow;
+ OwnPtrWillBeMember<NamedNodeMap> m_attributeMap;
+ OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<Attr> > > m_attrNodeList;
+ OwnPtrWillBeMember<InputMethodContext> m_inputMethodContext;
+ OwnPtrWillBeMember<ActiveAnimations> m_activeAnimations;
+ OwnPtrWillBeMember<InlineCSSStyleDeclaration> m_cssomWrapper;
- RefPtr<PseudoElement> m_generatedBefore;
- RefPtr<PseudoElement> m_generatedAfter;
- RefPtr<PseudoElement> m_backdrop;
+ RefPtr<RenderStyle> m_computedStyle;
+ RefPtr<CustomElementDefinition> m_customElementDefinition;
+
+ RefPtrWillBeMember<PseudoElement> m_generatedBefore;
+ RefPtrWillBeMember<PseudoElement> m_generatedAfter;
+ RefPtrWillBeMember<PseudoElement> m_backdrop;
- ElementRareData(RenderObject*);
+ explicit ElementRareData(RenderObject*);
};
inline IntSize defaultMinimumSizeForResizing()
@@ -201,33 +162,17 @@ inline IntSize defaultMinimumSizeForResizing()
inline ElementRareData::ElementRareData(RenderObject* renderer)
: NodeRareData(renderer)
- , m_tabIndex(0)
- , m_childIndex(0)
- , m_tabIndexWasSetExplicitly(false)
- , m_needsFocusAppearanceUpdateSoonAfterAttach(false)
- , m_styleAffectedByEmpty(false)
- , m_isInCanvasSubtree(false)
- , m_containsFullScreenElement(false)
- , m_isInTopLayer(false)
- , m_hasPendingResources(false)
- , m_childrenAffectedByFocus(false)
- , m_childrenAffectedByHover(false)
- , m_childrenAffectedByActive(false)
- , m_childrenAffectedByDrag(false)
- , m_childrenAffectedByFirstChildRules(false)
- , m_childrenAffectedByLastChildRules(false)
- , m_childrenAffectedByDirectAdjacentRules(false)
- , m_childrenAffectedByForwardPositionalRules(false)
- , m_childrenAffectedByBackwardPositionalRules(false)
- , m_isInsideRegion(false)
- , m_regionOversetState(RegionUndefined)
+ , m_tabindex(0)
, m_minimumSizeForResizing(defaultMinimumSizeForResizing())
{
+ m_isElementRareData = true;
}
inline ElementRareData::~ElementRareData()
{
+#if !ENABLE(OILPAN)
ASSERT(!m_shadow);
+#endif
ASSERT(!m_generatedBefore);
ASSERT(!m_generatedAfter);
ASSERT(!m_backdrop);
@@ -238,7 +183,14 @@ inline bool ElementRareData::hasPseudoElements() const
return m_generatedBefore || m_generatedAfter || m_backdrop;
}
-inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
+inline void ElementRareData::clearPseudoElements()
+{
+ setPseudoElement(BEFORE, nullptr);
+ setPseudoElement(AFTER, nullptr);
+ setPseudoElement(BACKDROP, nullptr);
+}
+
+inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtrWillBeRawPtr<PseudoElement> element)
{
switch (pseudoId) {
case BEFORE:
@@ -277,21 +229,7 @@ inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const
inline void ElementRareData::resetStyleState()
{
- setStyleAffectedByEmpty(false);
- setChildIndex(0);
-}
-
-inline void ElementRareData::resetDynamicRestyleObservations()
-{
- setChildrenAffectedByFocus(false);
- setChildrenAffectedByHover(false);
- setChildrenAffectedByActive(false);
- setChildrenAffectedByDrag(false);
- setChildrenAffectedByFirstChildRules(false);
- setChildrenAffectedByLastChildRules(false);
- setChildrenAffectedByDirectAdjacentRules(false);
- setChildrenAffectedByForwardPositionalRules(false);
- setChildrenAffectedByBackwardPositionalRules(false);
+ clearElementFlag(StyleAffectedByEmpty);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h b/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h
index 274725d57ee..e8241820b5e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h
@@ -2,8 +2,9 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,122 +31,313 @@
namespace WebCore {
-namespace ElementTraversal {
+template <class ElementType>
+class Traversal {
+public:
+ // First or last ElementType child of the node.
+ static ElementType* firstChild(const ContainerNode& current) { return firstChildTemplate(current); }
+ static ElementType* firstChild(const Node& current) { return firstChildTemplate(current); }
+ static ElementType* lastChild(const ContainerNode& current) { return lastChildTemplate(current); }
+ static ElementType* lastChild(const Node& current) { return lastChildTemplate(current); }
-// First element child of the node.
-Element* firstWithin(const Node&);
-Element* firstWithin(const ContainerNode&);
+ // First ElementType ancestor of the node.
+ static ElementType* firstAncestor(const Node& current);
+ static ElementType* firstAncestorOrSelf(Node& current) { return firstAncestorOrSelfTemplate(current); }
+ static ElementType* firstAncestorOrSelf(Element& current) { return firstAncestorOrSelfTemplate(current); }
-// Pre-order traversal skipping non-element nodes.
-Element* next(const Node&);
-Element* next(const Node&, const Node* stayWithin);
-Element* next(const ContainerNode&);
-Element* next(const ContainerNode&, const Node* stayWithin);
+ // First or last ElementType descendant of the node.
+ // For Elements firstWithin() is always the same as firstChild().
+ static ElementType* firstWithin(const ContainerNode& current) { return firstWithinTemplate(current); }
+ static ElementType* firstWithin(const Node& current) { return firstWithinTemplate(current); }
+ static ElementType* lastWithin(const ContainerNode& current) { return lastWithinTemplate(current); }
+ static ElementType* lastWithin(const Node& current) { return lastWithinTemplate(current); }
-// Like next, but skips children.
-Element* nextSkippingChildren(const Node&);
-Element* nextSkippingChildren(const Node&, const Node* stayWithin);
-Element* nextSkippingChildren(const ContainerNode&);
-Element* nextSkippingChildren(const ContainerNode&, const Node* stayWithin);
+ // Pre-order traversal skipping non-element nodes.
+ static ElementType* next(const ContainerNode& current) { return nextTemplate(current); }
+ static ElementType* next(const Node& current) { return nextTemplate(current); }
+ static ElementType* next(const ContainerNode& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+ static ElementType* next(const Node& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+ static ElementType* previous(const ContainerNode& current) { return previousTemplate(current); }
+ static ElementType* previous(const Node& current) { return previousTemplate(current); }
+ static ElementType* previous(const ContainerNode& current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
+ static ElementType* previous(const Node& current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
-// Pre-order traversal including the pseudo-elements.
-Element* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Element* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Element* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+ // Like next, but skips children.
+ static ElementType* nextSkippingChildren(const ContainerNode& current) { return nextSkippingChildrenTemplate(current); }
+ static ElementType* nextSkippingChildren(const Node& current) { return nextSkippingChildrenTemplate(current); }
+ static ElementType* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
+ static ElementType* nextSkippingChildren(const Node& current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
-// Utility function to traverse only the element and pseudo-element siblings of a node.
-Element* pseudoAwarePreviousSibling(const Node&);
+ // Pre-order traversal including the pseudo-elements.
+ static ElementType* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static ElementType* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static ElementType* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+ // Utility function to traverse only the element and pseudo-element siblings of a node.
+ static ElementType* pseudoAwarePreviousSibling(const Node&);
+
+ // Previous / Next sibling.
+ static ElementType* previousSibling(const Node&);
+ static ElementType* nextSibling(const Node&);
+
+private:
+ template <class NodeType>
+ static ElementType* firstChildTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* lastChildTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* firstAncestorOrSelfTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* firstWithinTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* lastWithinTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* nextTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* nextTemplate(NodeType&, const Node* stayWithin);
+ template <class NodeType>
+ static ElementType* previousTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* previousTemplate(NodeType&, const Node* stayWithin);
+ template <class NodeType>
+ static ElementType* nextSkippingChildrenTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* nextSkippingChildrenTemplate(NodeType&, const Node* stayWithin);
+};
+
+typedef Traversal<Element> ElementTraversal;
+
+// Specialized for pure Element to exploit the fact that Elements parent is always either another Element or the root.
+template <>
template <class NodeType>
-inline Element* firstElementWithinTemplate(NodeType& current)
+inline Element* Traversal<Element>::firstWithinTemplate(NodeType& current)
{
- // Except for the root containers, only elements can have element children.
- Node* node = current.firstChild();
+ return firstChildTemplate(current);
+}
+
+template <>
+template <class NodeType>
+inline Element* Traversal<Element>::lastWithinTemplate(NodeType& current)
+{
+ Node* node = NodeTraversal::lastWithin(current);
while (node && !node->isElementNode())
- node = node->nextSibling();
+ node = NodeTraversal::previous(*node, &current);
return toElement(node);
}
-inline Element* firstWithin(const ContainerNode& current) { return firstElementWithinTemplate(current); }
-inline Element* firstWithin(const Node& current) { return firstElementWithinTemplate(current); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementTemplate(NodeType& current)
+inline Element* Traversal<Element>::nextTemplate(NodeType& current)
{
Node* node = NodeTraversal::next(current);
while (node && !node->isElementNode())
node = NodeTraversal::nextSkippingChildren(*node);
return toElement(node);
}
-inline Element* next(const ContainerNode& current) { return traverseNextElementTemplate(current); }
-inline Element* next(const Node& current) { return traverseNextElementTemplate(current); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementTemplate(NodeType& current, const Node* stayWithin)
+inline Element* Traversal<Element>::nextTemplate(NodeType& current, const Node* stayWithin)
{
Node* node = NodeTraversal::next(current, stayWithin);
while (node && !node->isElementNode())
node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
return toElement(node);
}
-inline Element* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextElementTemplate(current, stayWithin); }
-inline Element* next(const Node& current, const Node* stayWithin) { return traverseNextElementTemplate(current, stayWithin); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementSkippingChildrenTemplate(NodeType& current)
+inline Element* Traversal<Element>::previousTemplate(NodeType& current)
{
- Node* node = NodeTraversal::nextSkippingChildren(current);
+ Node* node = NodeTraversal::previous(current);
while (node && !node->isElementNode())
- node = NodeTraversal::nextSkippingChildren(*node);
+ node = NodeTraversal::previous(*node);
return toElement(node);
}
-inline Element* nextSkippingChildren(const ContainerNode& current) { return traverseNextElementSkippingChildrenTemplate(current); }
-inline Element* nextSkippingChildren(const Node& current) { return traverseNextElementSkippingChildrenTemplate(current); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+inline Element* Traversal<Element>::previousTemplate(NodeType& current, const Node* stayWithin)
{
- Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
+ Node* node = NodeTraversal::previous(current, stayWithin);
while (node && !node->isElementNode())
- node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
+ node = NodeTraversal::previous(*node, stayWithin);
return toElement(node);
}
-inline Element* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); }
-inline Element* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); }
-inline Element* previousIncludingPseudo(const Node& current, const Node* stayWithin)
+// Generic versions.
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstChildTemplate(NodeType& current)
+{
+ Node* node = current.firstChild();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->nextSibling();
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::firstAncestor(const Node& current)
+{
+ ContainerNode* ancestor = current.parentNode();
+ while (ancestor && !isElementOfType<const ElementType>(*ancestor))
+ ancestor = ancestor->parentNode();
+ return toElement<ElementType>(ancestor);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstAncestorOrSelfTemplate(NodeType& current)
+{
+ if (isElementOfType<const ElementType>(current))
+ return &toElement<ElementType>(current);
+ return firstAncestor(current);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::lastChildTemplate(NodeType& current)
+{
+ Node* node = current.lastChild();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->previousSibling();
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstWithinTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::firstWithin(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::next(*element, &current);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::lastWithinTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::lastWithin(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::previous(element, &current);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::next(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::next(*element);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current, const Node* stayWithin)
+{
+ Element* element = Traversal<Element>::next(current, stayWithin);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::next(*element, stayWithin);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::previous(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::previous(*element);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current, const Node* stayWithin)
+{
+ Element* element = Traversal<Element>::previous(current, stayWithin);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::previous(*element, stayWithin);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current)
+{
+ Node* node = NodeTraversal::nextSkippingChildren(current);
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node);
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+{
+ Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::previousIncludingPseudo(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::previousIncludingPseudo(current, stayWithin);
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = NodeTraversal::previousIncludingPseudo(*node, stayWithin);
- return toElement(node);
+ return toElement<ElementType>(node);
}
-inline Element* nextIncludingPseudo(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextIncludingPseudo(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextIncludingPseudo(current, stayWithin);
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = NodeTraversal::nextIncludingPseudo(*node, stayWithin);
- return toElement(node);
+ return toElement<ElementType>(node);
}
-inline Element* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextIncludingPseudoSkippingChildren(current, stayWithin);
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = NodeTraversal::nextIncludingPseudoSkippingChildren(*node, stayWithin);
- return toElement(node);
+ return toElement<ElementType>(node);
}
-inline Element* pseudoAwarePreviousSibling(const Node& current)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::pseudoAwarePreviousSibling(const Node& current)
{
Node* node = current.pseudoAwarePreviousSibling();
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = node->pseudoAwarePreviousSibling();
- return toElement(node);
+ return toElement<ElementType>(node);
}
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::previousSibling(const Node& current)
+{
+ Node* node = current.previousSibling();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->previousSibling();
+ return toElement<ElementType>(node);
}
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextSibling(const Node& current)
+{
+ Node* node = current.nextSibling();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->nextSibling();
+ return toElement<ElementType>(node);
}
+} // namespace WebCore
+
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Promise.h b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp
index 2c842aa4c11..9a453d8fcfd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Promise.h
+++ b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,19 +29,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// FIXME: This file should be deleted.
-#ifndef Promise_h
-#define Promise_h
+#include "config.h"
+#include "core/dom/EmptyNodeList.h"
-#include "wtf/RefCounted.h"
+#include "core/dom/Node.h"
+#include "core/dom/NodeRareData.h"
namespace WebCore {
-// An empty class. This is here because a generated file use it.
-class Promise : public RefCounted<Promise> {
-};
+EmptyNodeList::~EmptyNodeList()
+{
+#if !ENABLE(OILPAN)
+ m_owner->nodeLists()->removeEmptyChildNodeList(this);
+#endif
+}
-} // namespace WebCore
+Node* EmptyNodeList::virtualOwnerNode() const
+{
+ return &ownerNode();
+}
+void EmptyNodeList::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
+ NodeList::trace(visitor);
+}
-#endif // Promise_h
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h
index b7e200cec9f..0857148db08 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h
+++ b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,44 +29,40 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DataTransferItem_h
-#define DataTransferItem_h
+#ifndef EmptyNodeList_h
+#define EmptyNodeList_h
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
+#include "core/dom/NodeList.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class Blob;
-class ChromiumDataObjectItem;
-class Clipboard;
-class File;
-class StringCallback;
-class ExecutionContext;
-
-class DataTransferItem : public RefCounted<DataTransferItem>, public ScriptWrappable {
+class EmptyNodeList FINAL : public NodeList {
public:
- static PassRefPtr<DataTransferItem> create(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObjectItem>);
- ~DataTransferItem();
-
- String kind() const;
- String type() const;
+ static PassRefPtrWillBeRawPtr<EmptyNodeList> create(Node& rootNode)
+ {
+ return adoptRefWillBeNoop(new EmptyNodeList(rootNode));
+ }
+ virtual ~EmptyNodeList();
- void getAsString(ExecutionContext*, PassOwnPtr<StringCallback>) const;
- PassRefPtr<Blob> getAsFile() const;
+ Node& ownerNode() const { return *m_owner; }
- Clipboard* clipboard() { return m_clipboard.get(); }
- ChromiumDataObjectItem* dataObjectItem() { return m_item.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
private:
- DataTransferItem(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObjectItem>);
+ explicit EmptyNodeList(Node& rootNode) : m_owner(rootNode) { }
+
+ virtual unsigned length() const OVERRIDE { return 0; }
+ virtual Node* item(unsigned) const OVERRIDE { return 0; }
- RefPtr<Clipboard> m_clipboard;
- RefPtr<ChromiumDataObjectItem> m_item;
+ virtual bool isEmptyNodeList() const OVERRIDE { return true; }
+ virtual Node* virtualOwnerNode() const OVERRIDE;
+
+ RefPtrWillBeMember<Node> m_owner;
};
+DEFINE_TYPE_CASTS(EmptyNodeList, NodeList, nodeList, nodeList->isEmptyNodeList(), nodeList.isEmptyNodeList());
+
} // namespace WebCore
-#endif // DataTransferItem_h
+#endif // EmptyNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Entity.h b/chromium/third_party/WebKit/Source/core/dom/Entity.h
deleted file mode 100644
index e1a7a002513..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Entity.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Entity_h
-#define Entity_h
-
-#include "core/dom/ContainerNode.h"
-
-namespace WebCore {
-
-class Entity : public ContainerNode {
-private:
- Entity(); // Left unimplemented on purpose.
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Entity.idl b/chromium/third_party/WebKit/Source/core/dom/Entity.idl
deleted file mode 100644
index 151572f4f26..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Entity.idl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-// FIXME: Remove Entity interface. We never create Entity objects. We have this
-// interface to provide window.Entity.
-interface Entity : Node {
- // We don't need to provide any attributes.
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h b/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h
index 4dc428a5a83..be3bf07856a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h
@@ -78,6 +78,9 @@ namespace WebCore {
// SQL
SQLDatabaseError, // Naming conflict with DatabaseError class.
+ // Web Crypto
+ OperationError,
+
// WebIDL exception types, handled by the binding layer.
// FIXME: Add GeneralError, EvalError, etc. when implemented in the bindings.
TypeError,
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index 1f62b74cfef..c8a61b7898f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -41,10 +41,10 @@
namespace WebCore {
-class ExecutionContext::PendingException {
+class ExecutionContext::PendingException : public NoBaseWillBeGarbageCollectedFinalized<ExecutionContext::PendingException> {
WTF_MAKE_NONCOPYABLE(PendingException);
public:
- PendingException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
+ PendingException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
: m_errorMessage(errorMessage)
, m_lineNumber(lineNumber)
, m_columnNumber(columnNumber)
@@ -52,11 +52,15 @@ public:
, m_callStack(callStack)
{
}
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_callStack);
+ }
String m_errorMessage;
int m_lineNumber;
int m_columnNumber;
String m_sourceURL;
- RefPtr<ScriptCallStack> m_callStack;
+ RefPtrWillBeMember<ScriptCallStack> m_callStack;
};
ExecutionContext::ExecutionContext()
@@ -96,6 +100,11 @@ void ExecutionContext::stopActiveDOMObjects()
lifecycleNotifier().notifyStoppingActiveDOMObjects();
}
+unsigned ExecutionContext::activeDOMObjectCount()
+{
+ return lifecycleNotifier().activeDOMObjects().size();
+}
+
void ExecutionContext::suspendScheduledTasks()
{
suspendActiveDOMObjects();
@@ -123,13 +132,13 @@ bool ExecutionContext::shouldSanitizeScriptError(const String& sourceURL, Access
return !(securityOrigin()->canRequest(completeURL(sourceURL)) || corsStatus == SharableCrossOrigin);
}
-void ExecutionContext::reportException(PassRefPtr<ErrorEvent> event, PassRefPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
+void ExecutionContext::reportException(PassRefPtrWillBeRawPtr<ErrorEvent> event, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
{
- RefPtr<ErrorEvent> errorEvent = event;
+ RefPtrWillBeRawPtr<ErrorEvent> errorEvent = event;
if (m_inDispatchErrorEvent) {
if (!m_pendingExceptions)
- m_pendingExceptions = adoptPtr(new Vector<OwnPtr<PendingException> >());
- m_pendingExceptions->append(adoptPtr(new PendingException(errorEvent->messageForConsole(), errorEvent->lineno(), errorEvent->colno(), errorEvent->filename(), callStack)));
+ m_pendingExceptions = adoptPtrWillBeNoop(new WillBeHeapVector<OwnPtrWillBeMember<PendingException> >());
+ m_pendingExceptions->append(adoptPtrWillBeNoop(new PendingException(errorEvent->messageForConsole(), errorEvent->lineno(), errorEvent->colno(), errorEvent->filename(), callStack)));
return;
}
@@ -155,14 +164,14 @@ void ExecutionContext::addConsoleMessage(MessageSource source, MessageLevel leve
m_client->addMessage(source, level, message, sourceURL, lineNumber, 0);
}
-void ExecutionContext::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* state)
+void ExecutionContext::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* scriptState)
{
if (!m_client)
return;
- m_client->addMessage(source, level, message, String(), 0, state);
+ m_client->addMessage(source, level, message, String(), 0, scriptState);
}
-bool ExecutionContext::dispatchErrorEvent(PassRefPtr<ErrorEvent> event, AccessControlStatus corsStatus)
+bool ExecutionContext::dispatchErrorEvent(PassRefPtrWillBeRawPtr<ErrorEvent> event, AccessControlStatus corsStatus)
{
if (!m_client)
return false;
@@ -170,7 +179,7 @@ bool ExecutionContext::dispatchErrorEvent(PassRefPtr<ErrorEvent> event, AccessCo
if (!target)
return false;
- RefPtr<ErrorEvent> errorEvent = event;
+ RefPtrWillBeRawPtr<ErrorEvent> errorEvent = event;
if (shouldSanitizeScriptError(errorEvent->filename(), corsStatus))
errorEvent = ErrorEvent::createSanitizedError(errorEvent->world());
@@ -199,7 +208,7 @@ int ExecutionContext::installNewTimeout(PassOwnPtr<ScheduledAction> action, int
}
TimeoutMap::AddResult result = m_timeouts.add(timeoutID, DOMTimer::create(this, action, timeout, singleShot, timeoutID));
ASSERT(result.isNewEntry);
- DOMTimer* timer = result.iterator->value.get();
+ DOMTimer* timer = result.storedValue->value.get();
timer->suspendIfNeeded();
@@ -245,7 +254,7 @@ const KURL& ExecutionContext::url() const
return emptyURL;
}
- return m_client->virtualURL();
+ return virtualURL();
}
KURL ExecutionContext::completeURL(const String& url) const
@@ -256,14 +265,7 @@ KURL ExecutionContext::completeURL(const String& url) const
return emptyURL;
}
- return m_client->virtualCompleteURL(url);
-}
-
-void ExecutionContext::userEventWasHandled()
-{
- if (!m_client)
- return;
- m_client->userEventWasHandled();
+ return virtualCompleteURL(url);
}
void ExecutionContext::disableEval(const String& errorMessage)
@@ -273,7 +275,7 @@ void ExecutionContext::disableEval(const String& errorMessage)
return m_client->disableEval(errorMessage);
}
-DOMWindow* ExecutionContext::executingWindow() const
+LocalDOMWindow* ExecutionContext::executingWindow() const
{
RELEASE_ASSERT(m_client);
return m_client->executingWindow();
@@ -334,4 +336,12 @@ void ExecutionContext::enforceSandboxFlags(SandboxFlags mask)
}
}
+void ExecutionContext::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_pendingExceptions);
+#endif
+ Supplementable<WebCore::ExecutionContext>::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 3fb01bb79f8..863b18b56f2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -37,6 +37,8 @@
#include "core/frame/ConsoleTypes.h"
#include "core/frame/DOMTimer.h"
#include "platform/LifecycleContext.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Functional.h"
#include "wtf/OwnPtr.h"
@@ -49,23 +51,24 @@ class OrdinalNumber;
namespace WebCore {
class ContextLifecycleNotifier;
-class DOMWindow;
+class LocalDOMWindow;
class EventListener;
class EventQueue;
class EventTarget;
class ExecutionContextTask;
+class ScriptState;
class PublicURLManager;
class SecurityOrigin;
class ScriptCallStack;
-class ScriptState;
-class ExecutionContext : public LifecycleContext<ExecutionContext> {
+class ExecutionContext
+ : public WillBeGarbageCollectedMixin
+ , public LifecycleContext<ExecutionContext>
+ , public Supplementable<ExecutionContext> {
public:
- ExecutionContext();
- virtual ~ExecutionContext();
+ virtual void trace(Visitor*);
// Delegating to ExecutionContextClient
- void setClient(ExecutionContextClient* client) { m_client = client; }
bool isDocument() const { return m_client && m_client->isDocument(); }
bool isWorkerGlobalScope() const { return m_client && m_client->isWorkerGlobalScope(); }
bool isJSExecutionForbidden() { return m_client && m_client->isJSExecutionForbidden(); }
@@ -73,16 +76,21 @@ public:
ContentSecurityPolicy* contentSecurityPolicy() const;
const KURL& url() const;
KURL completeURL(const String& url) const;
- void userEventWasHandled();
void disableEval(const String& errorMessage);
- DOMWindow* executingWindow() const;
+ LocalDOMWindow* executingWindow() const;
String userAgent(const KURL&) const;
void postTask(PassOwnPtr<ExecutionContextTask>);
void postTask(const Closure&);
double timerAlignmentInterval() const;
+ virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) = 0;
+
+ virtual SecurityContext& securityContext() = 0;
+ KURL contextURL() const { return virtualURL(); }
+ KURL contextCompleteURL(const String& url) const { return virtualCompleteURL(url); }
+
bool shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus);
- void reportException(PassRefPtr<ErrorEvent>, PassRefPtr<ScriptCallStack>, AccessControlStatus);
+ void reportException(PassRefPtrWillBeRawPtr<ErrorEvent>, PassRefPtrWillBeRawPtr<ScriptCallStack>, AccessControlStatus);
void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber);
void addConsoleMessage(MessageSource, MessageLevel, const String& message, ScriptState* = 0);
@@ -95,6 +103,7 @@ public:
void suspendActiveDOMObjects();
void resumeActiveDOMObjects();
void stopActiveDOMObjects();
+ unsigned activeDOMObjectCount();
virtual void suspendScheduledTasks();
virtual void resumeScheduledTasks();
@@ -106,9 +115,10 @@ public:
// Called after the construction of an ActiveDOMObject to synchronize suspend state.
void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*);
-
+#if !ENABLE(OILPAN)
void ref() { refExecutionContext(); }
void deref() { derefExecutionContext(); }
+#endif
// Gets the next id in a circular sequence from 1 to 2^31-1.
int circularSequentialID();
@@ -124,16 +134,25 @@ public:
virtual EventQueue* eventQueue() const = 0;
protected:
+ ExecutionContext();
+ virtual ~ExecutionContext();
+
+ void setClient(ExecutionContextClient* client) { m_client = client; }
+
+ virtual const KURL& virtualURL() const = 0;
+ virtual KURL virtualCompleteURL(const String&) const = 0;
ContextLifecycleNotifier& lifecycleNotifier();
private:
friend class DOMTimer; // For installNewTimeout() and removeTimeoutByID() below.
- bool dispatchErrorEvent(PassRefPtr<ErrorEvent>, AccessControlStatus);
+ bool dispatchErrorEvent(PassRefPtrWillBeRawPtr<ErrorEvent>, AccessControlStatus);
+#if !ENABLE(OILPAN)
virtual void refExecutionContext() = 0;
virtual void derefExecutionContext() = 0;
+#endif
// LifecycleContext implementation.
// Implementation details for DOMTimer. No other classes should call these functions.
@@ -149,7 +168,7 @@ private:
bool m_inDispatchErrorEvent;
class PendingException;
- OwnPtr<Vector<OwnPtr<PendingException> > > m_pendingExceptions;
+ OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<PendingException> > > m_pendingExceptions;
bool m_activeDOMObjectsAreSuspended;
bool m_activeDOMObjectsAreStopped;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h
index 4293c744c09..1964752a75c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h
@@ -29,14 +29,13 @@
#include "core/frame/ConsoleTypes.h"
#include "platform/LifecycleNotifier.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class EventQueue;
class EventTarget;
class ExecutionContextTask;
@@ -53,17 +52,13 @@ public:
virtual bool isDocument() const { return false; }
virtual bool isWorkerGlobalScope() const { return false; }
virtual bool isJSExecutionForbidden() const = 0;
- virtual DOMWindow* executingWindow() { return 0; }
- virtual void userEventWasHandled() { }
+ virtual LocalDOMWindow* executingWindow() { return 0; }
virtual String userAgent(const KURL&) const = 0;
virtual void disableEval(const String& errorMessage) = 0;
virtual SecurityContext& securityContext() = 0;
- virtual const KURL& virtualURL() const = 0;
- virtual KURL virtualCompleteURL(const String&) const = 0;
virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*) = 0;
- virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) = 0;
virtual EventTarget* errorEventTarget() = 0;
- virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0;
+ virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>) = 0;
virtual double timerAlignmentInterval() const = 0;
virtual void didUpdateSecurityOrigin() = 0;
@@ -72,8 +67,6 @@ public:
void addConsoleMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber) { addMessage(source, level, message, sourceURL, lineNumber, 0); }
void addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* state = 0) { addMessage(source, level, message, String(), 0, state); }
- KURL contextURL() const { return virtualURL(); }
- KURL contextCompleteURL(const String& url) const { return virtualCompleteURL(url); }
protected:
virtual ~ExecutionContextClient() { }
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp
deleted file mode 100644
index 124a5ac4aac..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ExecutionContextTask_h
-#define ExecutionContextTask_h
-
-#include "config.h"
-#include "core/dom/ExecutionContextTask.h"
-
-namespace WebCore {
-
-
-} // namespace
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
index 9d07d75d6a9..dbc98d3b69b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
@@ -47,7 +47,7 @@ public:
virtual bool isCleanupTask() const { return false; }
};
-class CallClosureTask : public ExecutionContextTask {
+class CallClosureTask FINAL : public ExecutionContextTask {
public:
static PassOwnPtr<CallClosureTask> create(const Closure& closure)
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp
index f6daf0e6631..b5363bc682b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp
@@ -28,15 +28,15 @@
#include "config.h"
#include "core/dom/FullscreenElementStack.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderFullScreen.h"
#include "platform/UserGestureIndicator.h"
@@ -44,13 +44,18 @@ namespace WebCore {
using namespace HTMLNames;
-static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, const WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner)
+static bool fullscreenIsAllowedForAllOwners(const Document& document)
{
+ const HTMLFrameOwnerElement* owner = document.ownerElement();
if (!owner)
return true;
do {
- if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
- return false;
+ if (!owner->hasAttribute(allowfullscreenAttr)) {
+ if (owner->hasAttribute(webkitallowfullscreenAttr))
+ UseCounter::count(document, UseCounter::PrefixedAllowFullscreenAttribute);
+ else
+ return false;
+ }
} while ((owner = owner->document().ownerElement()));
return true;
}
@@ -60,50 +65,50 @@ const char* FullscreenElementStack::supplementName()
return "FullscreenElementStack";
}
-FullscreenElementStack* FullscreenElementStack::from(Document* document)
+FullscreenElementStack& FullscreenElementStack::from(Document& document)
{
FullscreenElementStack* fullscreen = fromIfExists(document);
if (!fullscreen) {
fullscreen = new FullscreenElementStack(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(fullscreen));
+ DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBeNoop(fullscreen));
}
- return fullscreen;
+ return *fullscreen;
}
-FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document* document)
+FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document& document)
{
return static_cast<FullscreenElementStack*>(DocumentSupplement::from(document, supplementName()));
}
-Element* FullscreenElementStack::fullscreenElementFrom(Document* document)
+Element* FullscreenElementStack::fullscreenElementFrom(Document& document)
{
if (FullscreenElementStack* found = fromIfExists(document))
return found->webkitFullscreenElement();
return 0;
}
-Element* FullscreenElementStack::currentFullScreenElementFrom(Document* document)
+Element* FullscreenElementStack::currentFullScreenElementFrom(Document& document)
{
if (FullscreenElementStack* found = fromIfExists(document))
return found->webkitCurrentFullScreenElement();
return 0;
}
-bool FullscreenElementStack::isFullScreen(Document* document)
+bool FullscreenElementStack::isFullScreen(Document& document)
{
if (FullscreenElementStack* found = fromIfExists(document))
return found->webkitIsFullScreen();
return false;
}
-FullscreenElementStack::FullscreenElementStack(Document* document)
- : DocumentLifecycleObserver(document)
+FullscreenElementStack::FullscreenElementStack(Document& document)
+ : DocumentLifecycleObserver(&document)
, m_areKeysEnabledInFullScreen(false)
, m_fullScreenRenderer(0)
, m_fullScreenChangeDelayTimer(this, &FullscreenElementStack::fullScreenChangeDelayTimerFired)
{
- document->setHasFullscreenElementStack();
+ document.setHasFullscreenElementStack();
}
FullscreenElementStack::~FullscreenElementStack()
@@ -122,22 +127,36 @@ void FullscreenElementStack::documentWasDetached()
if (m_fullScreenRenderer)
setFullScreenRenderer(0);
+
+#if ENABLE(OILPAN)
+ m_fullScreenElement = nullptr;
+ m_fullScreenElementStack.clear();
+#endif
+
}
+#if !ENABLE(OILPAN)
void FullscreenElementStack::documentWasDisposed()
{
- m_fullScreenElement = 0;
+ // NOTE: the context dispose phase is not supported in oilpan. Please
+ // consider using the detach phase instead.
+ m_fullScreenElement = nullptr;
m_fullScreenElementStack.clear();
}
+#endif
bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) const
{
ASSERT(element);
- return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, element->document().ownerElement());
+ return fullscreenIsAllowedForAllOwners(element->document());
}
void FullscreenElementStack::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
{
+ // Ignore this request if the document is not in a live frame.
+ if (!document()->isActive())
+ return;
+
// The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
// for full screen mode, and do not have the concept of a full screen element stack.
bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);
@@ -171,7 +190,10 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// A descendant browsing context's document has a non-empty fullscreen element stack.
bool descendentHasNonEmptyStack = false;
for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
- if (fullscreenElementFrom(descendant->document())) {
+ if (!descendant->isLocalFrame())
+ continue;
+ ASSERT(toLocalFrame(descendant)->document());
+ if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) {
descendentHasNonEmptyStack = true;
break;
}
@@ -183,13 +205,10 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
// - an activation behavior is currently being processed whose click event was trusted, or
// - the event listener for a trusted click event is being handled.
- // FIXME: Does this need to null-check settings()?
- if (!UserGestureIndicator::processingUserGesture() && (!element->isMediaElement() || document()->settings()->mediaFullscreenRequiresUserGesture()))
+ if (!UserGestureIndicator::processingUserGesture())
break;
// There is a previously-established user preference, security risk, or platform limitation.
- if (!document()->settings() || !document()->settings()->fullScreenEnabled())
- break;
// 2. Let doc be element's node document. (i.e. "this")
Document* currentDoc = document();
@@ -217,19 +236,19 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
// set to true on the document.
if (!followingDoc) {
- from(currentDoc)->pushFullscreenElementStack(element);
+ from(*currentDoc).pushFullscreenElementStack(element);
addDocumentToFullScreenChangeEventQueue(currentDoc);
continue;
}
// 3. Otherwise, if document's fullscreen element stack is either empty or its top element
// is not following document's browsing context container,
- Element* topElement = fullscreenElementFrom(currentDoc);
+ Element* topElement = fullscreenElementFrom(*currentDoc);
if (!topElement || topElement != followingDoc->ownerElement()) {
// ...push following document's browsing context container on document's fullscreen element
// stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
// set to true on document.
- from(currentDoc)->pushFullscreenElementStack(followingDoc->ownerElement());
+ from(*currentDoc).pushFullscreenElementStack(followingDoc->ownerElement());
addDocumentToFullScreenChangeEventQueue(currentDoc);
continue;
}
@@ -240,14 +259,14 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// 5. Return, and run the remaining steps asynchronously.
// 6. Optionally, perform some animation.
m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT;
- document()->page()->chrome().client().enterFullScreenForElement(element);
+ document()->frameHost()->chrome().client().enterFullScreenForElement(element);
// 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
return;
} while (0);
m_fullScreenErrorEventTargetQueue.append(element ? element : document()->documentElement());
- m_fullScreenChangeDelayTimer.startOneShot(0);
+ m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
}
void FullscreenElementStack::webkitCancelFullScreen()
@@ -261,11 +280,11 @@ void FullscreenElementStack::webkitCancelFullScreen()
// To achieve that aim, remove all the elements from the top document's stack except for the first before
// calling webkitExitFullscreen():
- Vector<RefPtr<Element> > replacementFullscreenElementStack;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > replacementFullscreenElementStack;
replacementFullscreenElementStack.append(fullscreenElementFrom(document()->topDocument()));
- FullscreenElementStack* topFullscreenElementStack = from(document()->topDocument());
- topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscreenElementStack);
- topFullscreenElementStack->webkitExitFullscreen();
+ FullscreenElementStack& topFullscreenElementStack = from(document()->topDocument());
+ topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscreenElementStack);
+ topFullscreenElementStack.webkitExitFullscreen();
}
void FullscreenElementStack::webkitExitFullscreen()
@@ -274,6 +293,8 @@ void FullscreenElementStack::webkitExitFullscreen()
// 1. Let doc be the context object. (i.e. "this")
Document* currentDoc = document();
+ if (!currentDoc->isActive())
+ return;
// 2. If doc's fullscreen element stack is empty, terminate these steps.
if (m_fullScreenElementStack.isEmpty())
@@ -282,16 +303,20 @@ void FullscreenElementStack::webkitExitFullscreen()
// 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
// element stack (if any), ordered so that the child of the doc is last and the document furthest
// away from the doc is first.
- Deque<RefPtr<Document> > descendants;
- for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
- if (fullscreenElementFrom(descendant->document()))
- descendants.prepend(descendant->document());
+ WillBeHeapDeque<RefPtrWillBeMember<Document> > descendants;
+ for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
+ if (!descendant->isLocalFrame())
+ continue;
+ ASSERT(toLocalFrame(descendant)->document());
+ if (fullscreenElementFrom(*toLocalFrame(descendant)->document()))
+ descendants.prepend(toLocalFrame(descendant)->document());
}
// 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
// task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
- for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
- from(i->get())->clearFullscreenElementStack();
+ for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
+ ASSERT(*i);
+ from(**i).clearFullscreenElementStack();
addDocumentToFullScreenChangeEventQueue(i->get());
}
@@ -299,11 +324,11 @@ void FullscreenElementStack::webkitExitFullscreen()
Element* newTop = 0;
while (currentDoc) {
// 1. Pop the top element of doc's fullscreen element stack.
- from(currentDoc)->popFullscreenElementStack();
+ from(*currentDoc).popFullscreenElementStack();
// If doc's fullscreen element stack is non-empty and the element now at the top is either
// not in a document or its node document is not doc, repeat this substep.
- newTop = fullscreenElementFrom(currentDoc);
+ newTop = fullscreenElementFrom(*currentDoc);
if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
continue;
@@ -325,43 +350,40 @@ void FullscreenElementStack::webkitExitFullscreen()
// 6. Return, and run the remaining steps asynchronously.
// 7. Optionally, perform some animation.
- if (!document()->page())
+ FrameHost* host = document()->frameHost();
+
+ // Speculative fix for engaget.com/videos per crbug.com/336239.
+ // FIXME: This check is wrong. We ASSERT(document->isActive()) above
+ // so this should be redundant and should be removed!
+ if (!host)
return;
// Only exit out of full screen window mode if there are no remaining elements in the
// full screen stack.
if (!newTop) {
- document()->page()->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
+ host->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
return;
}
// Otherwise, notify the chrome of the new full screen element.
- document()->page()->chrome().client().enterFullScreenForElement(newTop);
+ host->chrome().client().enterFullScreenForElement(newTop);
}
-bool FullscreenElementStack::webkitFullscreenEnabled(Document* document)
+bool FullscreenElementStack::webkitFullscreenEnabled(Document& document)
{
// 4. The fullscreenEnabled attribute must return true if the context object and all ancestor
// browsing context's documents have their fullscreen enabled flag set, or false otherwise.
// Top-level browsing contexts are implied to have their allowFullScreen attribute set.
- return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, document->ownerElement());
-
+ return fullscreenIsAllowedForAllOwners(document);
}
void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* element)
{
- if (!document()->isActive())
- return;
-
ASSERT(element);
-
- // Protect against being called after the document has been removed from the page.
- if (!document()->settings())
+ if (!document()->isActive())
return;
- ASSERT(document()->settings()->fullScreenEnabled());
-
if (m_fullScreenRenderer)
m_fullScreenRenderer->unwrapRenderer();
@@ -383,7 +405,9 @@ void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* elemen
m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
- document()->recalcStyle(Force);
+ // FIXME: This should not call updateStyleIfNeeded.
+ document()->setNeedsStyleRecalc(SubtreeStyleChange);
+ document()->updateRenderTreeIfNeeded();
}
void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*)
@@ -396,7 +420,7 @@ void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*)
m_fullScreenElement->didBecomeFullscreenElement();
- m_fullScreenChangeDelayTimer.startOneShot(0);
+ m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
}
void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*)
@@ -425,16 +449,17 @@ void FullscreenElementStack::webkitDidExitFullScreenForElement(Element*)
if (m_fullScreenRenderer)
m_fullScreenRenderer->unwrapRenderer();
- m_fullScreenElement = 0;
- document()->setNeedsStyleRecalc();
+ m_fullScreenElement = nullptr;
+ document()->setNeedsStyleRecalc(SubtreeStyleChange);
// When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
// means that the events will be queued there. So if we have no events here, start the timer on
// the exiting document.
Document* exitingDocument = document();
if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTargetQueue.isEmpty())
- exitingDocument = document()->topDocument();
- from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0);
+ exitingDocument = &document()->topDocument();
+ ASSERT(exitingDocument);
+ from(*exitingDocument).m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
}
void FullscreenElementStack::setFullScreenRenderer(RenderFullScreen* renderer)
@@ -466,14 +491,14 @@ void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle
// Since we dispatch events in this function, it's possible that the
// document will be detached and GC'd. We protect it here to make sure we
// can finish the function successfully.
- RefPtr<Document> protectDocument(document());
- Deque<RefPtr<Node> > changeQueue;
+ RefPtrWillBeRawPtr<Document> protectDocument(document());
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > changeQueue;
m_fullScreenChangeEventTargetQueue.swap(changeQueue);
- Deque<RefPtr<Node> > errorQueue;
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > errorQueue;
m_fullScreenErrorEventTargetQueue.swap(errorQueue);
while (!changeQueue.isEmpty()) {
- RefPtr<Node> node = changeQueue.takeFirst();
+ RefPtrWillBeRawPtr<Node> node = changeQueue.takeFirst();
if (!node)
node = document()->documentElement();
// The dispatchEvent below may have blown away our documentElement.
@@ -489,7 +514,7 @@ void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle
}
while (!errorQueue.isEmpty()) {
- RefPtr<Node> node = errorQueue.takeFirst();
+ RefPtrWillBeRawPtr<Node> node = errorQueue.takeFirst();
if (!node)
node = document()->documentElement();
// The dispatchEvent below may have blown away our documentElement.
@@ -553,7 +578,7 @@ void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
ASSERT(doc);
Node* target = 0;
- if (FullscreenElementStack* fullscreen = fromIfExists(doc)) {
+ if (FullscreenElementStack* fullscreen = fromIfExists(*doc)) {
target = fullscreen->webkitFullscreenElement();
if (!target)
target = fullscreen->webkitCurrentFullScreenElement();
@@ -564,4 +589,13 @@ void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
m_fullScreenChangeEventTargetQueue.append(target);
}
+void FullscreenElementStack::trace(Visitor* visitor)
+{
+ visitor->trace(m_fullScreenElement);
+ visitor->trace(m_fullScreenElementStack);
+ visitor->trace(m_fullScreenChangeEventTargetQueue);
+ visitor->trace(m_fullScreenErrorEventTargetQueue);
+ DocumentSupplement::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h
index 4211a8387da..852812a70d4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h
+++ b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h
@@ -28,6 +28,7 @@
#ifndef FullscreenElementStack_h
#define FullscreenElementStack_h
+#include "core/dom/Document.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/Element.h"
#include "platform/Supplementable.h"
@@ -39,24 +40,22 @@
namespace WebCore {
-class Document;
-class Element;
-class Node;
class RenderFullScreen;
class RenderStyle;
-class ExecutionContext;
-class FullscreenElementStack
- : public DocumentSupplement
+class FullscreenElementStack FINAL
+ : public NoBaseWillBeGarbageCollectedFinalized<FullscreenElementStack>
+ , public DocumentSupplement
, public DocumentLifecycleObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FullscreenElementStack);
public:
virtual ~FullscreenElementStack();
static const char* supplementName();
- static FullscreenElementStack* from(Document*);
- static FullscreenElementStack* fromIfExists(Document*);
- static Element* fullscreenElementFrom(Document*);
- static Element* currentFullScreenElementFrom(Document*);
- static bool isFullScreen(Document*);
+ static FullscreenElementStack& from(Document&);
+ static FullscreenElementStack* fromIfExists(Document&);
+ static Element* fullscreenElementFrom(Document&);
+ static Element* currentFullScreenElementFrom(Document&);
+ static bool isFullScreen(Document&);
static bool isActiveFullScreenElement(const Element*);
enum FullScreenCheckType {
@@ -86,7 +85,7 @@ public:
void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false);
// W3C API
- static bool webkitFullscreenEnabled(Document*);
+ static bool webkitFullscreenEnabled(Document&);
Element* webkitFullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().get() : 0; }
void webkitExitFullscreen();
@@ -95,38 +94,42 @@ public:
Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); }
virtual void documentWasDetached() OVERRIDE;
+#if !ENABLE(OILPAN)
virtual void documentWasDisposed() OVERRIDE;
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- static FullscreenElementStack* fromIfExistsSlow(Document*);
+ static FullscreenElementStack* fromIfExistsSlow(Document&);
- explicit FullscreenElementStack(Document*);
+ explicit FullscreenElementStack(Document&);
Document* document();
void fullScreenChangeDelayTimerFired(Timer<FullscreenElementStack>*);
bool m_areKeysEnabledInFullScreen;
- RefPtr<Element> m_fullScreenElement;
- Vector<RefPtr<Element> > m_fullScreenElementStack;
+ RefPtrWillBeMember<Element> m_fullScreenElement;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > m_fullScreenElementStack;
RenderFullScreen* m_fullScreenRenderer;
Timer<FullscreenElementStack> m_fullScreenChangeDelayTimer;
- Deque<RefPtr<Node> > m_fullScreenChangeEventTargetQueue;
- Deque<RefPtr<Node> > m_fullScreenErrorEventTargetQueue;
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > m_fullScreenChangeEventTargetQueue;
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > m_fullScreenErrorEventTargetQueue;
LayoutRect m_savedPlaceholderFrameRect;
RefPtr<RenderStyle> m_savedPlaceholderRenderStyle;
};
inline bool FullscreenElementStack::isActiveFullScreenElement(const Element* element)
{
- FullscreenElementStack* controller = fromIfExists(&element->document());
+ FullscreenElementStack* controller = fromIfExists(element->document());
if (!controller)
return false;
return controller->webkitIsFullScreen() && controller->webkitCurrentFullScreenElement() == element;
}
-inline FullscreenElementStack* FullscreenElementStack::fromIfExists(Document* document)
+inline FullscreenElementStack* FullscreenElementStack::fromIfExists(Document& document)
{
- if (!document->hasFullscreenElementStack())
+ if (!document.hasFullscreenElementStack())
return 0;
return fromIfExistsSlow(document);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h
index 8da83b9add9..933d14f8fb8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h
+++ b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h
@@ -36,6 +36,8 @@ namespace WebCore {
namespace GlobalEventHandlers {
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(autocomplete);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(autocompleteerror);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay);
@@ -81,6 +83,7 @@ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking);
@@ -90,6 +93,7 @@ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(toggle);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
index 880038222f2..c835461307d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
@@ -27,56 +27,62 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/#globaleventhandlers
+
[
- NoInterfaceObject
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface GlobalEventHandlers {
attribute EventHandler onabort;
+ [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocomplete;
+ [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocompleteerror;
attribute EventHandler onblur;
attribute EventHandler oncancel;
attribute EventHandler oncanplay;
attribute EventHandler oncanplaythrough;
attribute EventHandler onchange;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onclick;
+ [LogActivity=SetterOnly] attribute EventHandler onclick;
attribute EventHandler onclose;
attribute EventHandler oncontextmenu;
attribute EventHandler oncuechange;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondblclick;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondrag;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragend;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragenter;
- //[PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragexit;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragleave;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragover;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragstart;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondrop;
+ [LogActivity=SetterOnly] attribute EventHandler ondblclick;
+ [LogActivity=SetterOnly] attribute EventHandler ondrag;
+ [LogActivity=SetterOnly] attribute EventHandler ondragend;
+ [LogActivity=SetterOnly] attribute EventHandler ondragenter;
+ //[LogActivity=SetterOnly] attribute EventHandler ondragexit;
+ [LogActivity=SetterOnly] attribute EventHandler ondragleave;
+ [LogActivity=SetterOnly] attribute EventHandler ondragover;
+ [LogActivity=SetterOnly] attribute EventHandler ondragstart;
+ [LogActivity=SetterOnly] attribute EventHandler ondrop;
attribute EventHandler ondurationchange;
attribute EventHandler onemptied;
attribute EventHandler onended;
attribute EventHandler onerror;
attribute EventHandler onfocus;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler oninput;
+ [LogActivity=SetterOnly] attribute EventHandler oninput;
attribute EventHandler oninvalid;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onkeydown;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onkeypress;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onkeyup;
+ [LogActivity=SetterOnly] attribute EventHandler onkeydown;
+ [LogActivity=SetterOnly] attribute EventHandler onkeypress;
+ [LogActivity=SetterOnly] attribute EventHandler onkeyup;
attribute EventHandler onload;
attribute EventHandler onloadeddata;
attribute EventHandler onloadedmetadata;
attribute EventHandler onloadstart;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmousedown;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseenter;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseleave;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmousemove;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseout;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseover;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseup;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmousewheel;
+ [LogActivity=SetterOnly] attribute EventHandler onmousedown;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseenter;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseleave;
+ [LogActivity=SetterOnly] attribute EventHandler onmousemove;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseout;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseover;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseup;
+ [LogActivity=SetterOnly] attribute EventHandler onmousewheel;
attribute EventHandler onpause;
attribute EventHandler onplay;
attribute EventHandler onplaying;
attribute EventHandler onprogress;
attribute EventHandler onratechange;
attribute EventHandler onreset;
+ attribute EventHandler onresize;
attribute EventHandler onscroll;
attribute EventHandler onseeked;
attribute EventHandler onseeking;
@@ -87,6 +93,7 @@
attribute EventHandler onsubmit;
attribute EventHandler onsuspend;
attribute EventHandler ontimeupdate;
+ attribute EventHandler ontoggle;
attribute EventHandler onvolumechange;
attribute EventHandler onwaiting;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp b/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp
index 248835b507e..b427d1a81eb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp
@@ -44,7 +44,7 @@ IconURL IconURL::defaultFavicon(const KURL& documentURL)
url.setPort(documentURL.port());
url.setPath("/favicon.ico");
- IconURL result(url, emptyString(), emptyString(), Favicon);
+ IconURL result(url, Vector<IntSize>(), emptyString(), Favicon);
result.m_isDefaultIcon = true;
return result;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/IconURL.h b/chromium/third_party/WebKit/Source/core/dom/IconURL.h
index adec2a7a8fd..4a6fa233342 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IconURL.h
+++ b/chromium/third_party/WebKit/Source/core/dom/IconURL.h
@@ -31,16 +31,11 @@
#ifndef IconURL_h
#define IconURL_h
+#include "platform/geometry/IntSize.h"
#include "platform/weborigin/KURL.h"
namespace WebCore {
-#if ENABLE(TOUCH_ICON_LOADING)
-#define ICON_COUNT 3
-#else
-#define ICON_COUNT 1
-#endif
-
enum IconType {
InvalidIcon = 0,
Favicon = 1,
@@ -50,7 +45,7 @@ enum IconType {
struct IconURL {
IconType m_iconType;
- String m_sizes;
+ Vector<IntSize> m_sizes;
String m_mimeType;
KURL m_iconURL;
bool m_isDefaultIcon;
@@ -61,7 +56,7 @@ struct IconURL {
{
}
- IconURL(const KURL& url, const String& sizes, const String& mimeType, IconType type)
+ IconURL(const KURL& url, const Vector<IntSize>& sizes, const String& mimeType, IconType type)
: m_iconType(type)
, m_sizes(sizes)
, m_mimeType(mimeType)
@@ -75,8 +70,6 @@ struct IconURL {
bool operator==(const IconURL&, const IconURL&);
-typedef Vector<IconURL, ICON_COUNT> IconURLs;
-
}
#endif // IconURL_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp
index 69579955c75..c821d7803c7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp
@@ -30,17 +30,30 @@
namespace WebCore {
-IdTargetObserver::IdTargetObserver(IdTargetObserverRegistry& registry, const AtomicString& id)
- : m_registry(&registry)
+IdTargetObserver::IdTargetObserver(IdTargetObserverRegistry& observerRegistry, const AtomicString& id)
+ : m_registry(&observerRegistry)
, m_id(id)
{
- m_registry->addObserver(m_id, this);
+ registry().addObserver(m_id, this);
}
IdTargetObserver::~IdTargetObserver()
{
- if (m_registry)
- m_registry->removeObserver(m_id, this);
+#if !ENABLE(OILPAN)
+ registry().removeObserver(m_id, this);
+#endif
+}
+
+void IdTargetObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_registry);
+}
+
+void IdTargetObserver::unregister()
+{
+#if ENABLE(OILPAN)
+ registry().removeObserver(m_id, this);
+#endif
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h
index e76b8a5dbf0..71ee604cde4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h
@@ -26,22 +26,27 @@
#ifndef IdTargetObserver_h
#define IdTargetObserver_h
+#include "platform/heap/Handle.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
class IdTargetObserverRegistry;
-class IdTargetObserver {
+class IdTargetObserver : public NoBaseWillBeGarbageCollectedFinalized<IdTargetObserver> {
public:
virtual ~IdTargetObserver();
+ virtual void trace(Visitor*);
virtual void idTargetChanged() = 0;
+ virtual void unregister();
protected:
IdTargetObserver(IdTargetObserverRegistry&, const AtomicString& id);
private:
- IdTargetObserverRegistry* m_registry;
+ IdTargetObserverRegistry& registry() { return *m_registry; }
+
+ RawPtrWillBeMember<IdTargetObserverRegistry> m_registry;
AtomicString m_id;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp
index 19d297ad5e7..36e7f60c868 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp
@@ -30,9 +30,15 @@
namespace WebCore {
-PassOwnPtr<IdTargetObserverRegistry> IdTargetObserverRegistry::create()
+PassOwnPtrWillBeRawPtr<IdTargetObserverRegistry> IdTargetObserverRegistry::create()
{
- return adoptPtr(new IdTargetObserverRegistry());
+ return adoptPtrWillBeNoop(new IdTargetObserverRegistry());
+}
+
+void IdTargetObserverRegistry::trace(Visitor* visitor)
+{
+ visitor->trace(m_registry);
+ visitor->trace(m_notifyingObserversInSet);
}
void IdTargetObserverRegistry::addObserver(const AtomicString& id, IdTargetObserver* observer)
@@ -42,9 +48,9 @@ void IdTargetObserverRegistry::addObserver(const AtomicString& id, IdTargetObser
IdToObserverSetMap::AddResult result = m_registry.add(id.impl(), nullptr);
if (result.isNewEntry)
- result.iterator->value = adoptPtr(new ObserverSet());
+ result.storedValue->value = adoptPtrWillBeNoop(new ObserverSet());
- result.iterator->value->add(observer);
+ result.storedValue->value->add(observer);
}
void IdTargetObserverRegistry::removeObserver(const AtomicString& id, IdTargetObserver* observer)
@@ -69,9 +75,9 @@ void IdTargetObserverRegistry::notifyObserversInternal(const AtomicString& id)
if (!m_notifyingObserversInSet)
return;
- Vector<IdTargetObserver*> copy;
+ WillBeHeapVector<RawPtrWillBeMember<IdTargetObserver> > copy;
copyToVector(*m_notifyingObserversInSet, copy);
- for (Vector<IdTargetObserver*>::const_iterator it = copy.begin(); it != copy.end(); ++it) {
+ for (WillBeHeapVector<RawPtrWillBeMember<IdTargetObserver> >::const_iterator it = copy.begin(); it != copy.end(); ++it) {
if (m_notifyingObserversInSet->contains(*it))
(*it)->idTargetChanged();
}
@@ -79,7 +85,15 @@ void IdTargetObserverRegistry::notifyObserversInternal(const AtomicString& id)
if (m_notifyingObserversInSet->isEmpty())
m_registry.remove(id.impl());
- m_notifyingObserversInSet = 0;
+ m_notifyingObserversInSet = nullptr;
+}
+
+bool IdTargetObserverRegistry::hasObservers(const AtomicString& id) const
+{
+ if (id.isEmpty() || m_registry.isEmpty())
+ return false;
+ ObserverSet* set = m_registry.get(id.impl());
+ return set && !set->isEmpty();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h
index 4af563a853c..2036b30e6a4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h
@@ -26,33 +26,36 @@
#ifndef IdTargetObserverRegistry_h
#define IdTargetObserverRegistry_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
-#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringHash.h"
namespace WebCore {
class IdTargetObserver;
-class IdTargetObserverRegistry {
- WTF_MAKE_FAST_ALLOCATED;
+class IdTargetObserverRegistry FINAL : public NoBaseWillBeGarbageCollectedFinalized<IdTargetObserverRegistry> {
+ WTF_MAKE_NONCOPYABLE(IdTargetObserverRegistry);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
friend class IdTargetObserver;
public:
- static PassOwnPtr<IdTargetObserverRegistry> create();
+ static PassOwnPtrWillBeRawPtr<IdTargetObserverRegistry> create();
+ void trace(Visitor*);
void notifyObservers(const AtomicString& id);
+ bool hasObservers(const AtomicString& id) const;
private:
- IdTargetObserverRegistry() : m_notifyingObserversInSet(0) { }
+ IdTargetObserverRegistry() : m_notifyingObserversInSet(nullptr) { }
void addObserver(const AtomicString& id, IdTargetObserver*);
void removeObserver(const AtomicString& id, IdTargetObserver*);
void notifyObserversInternal(const AtomicString& id);
- typedef HashSet<IdTargetObserver*> ObserverSet;
- typedef HashMap<StringImpl*, OwnPtr<ObserverSet> > IdToObserverSetMap;
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<IdTargetObserver> > ObserverSet;
+ typedef WillBeHeapHashMap<StringImpl*, OwnPtrWillBeMember<ObserverSet> > IdToObserverSetMap;
IdToObserverSetMap m_registry;
- ObserverSet* m_notifyingObserversInSet;
+ RawPtrWillBeMember<ObserverSet> m_notifyingObserversInSet;
};
inline void IdTargetObserverRegistry::notifyObservers(const AtomicString& id)
diff --git a/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
new file mode 100644
index 00000000000..36fc264d0a6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/IncrementLoadEventDelayCount.h"
+
+#include "core/dom/Document.h"
+
+namespace WebCore {
+
+IncrementLoadEventDelayCount::IncrementLoadEventDelayCount(Document& document)
+ : m_document(&document)
+{
+ document.incrementLoadEventDelayCount();
+}
+
+IncrementLoadEventDelayCount::~IncrementLoadEventDelayCount()
+{
+ m_document->decrementLoadEventDelayCount();
+}
+
+void IncrementLoadEventDelayCount::documentChanged(Document& newDocument)
+{
+ newDocument.incrementLoadEventDelayCount();
+ m_document->decrementLoadEventDelayCount();
+ m_document = &newDocument;
+}
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
new file mode 100644
index 00000000000..b90b5201ee2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IncrementLoadEventDelayCount_h
+#define IncrementLoadEventDelayCount_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Document;
+
+// A helper class that will increment a document's loadEventDelayCount on
+// contruction and decrement it on destruction (semantics similar to RefPtr).
+class IncrementLoadEventDelayCount {
+ WTF_MAKE_NONCOPYABLE(IncrementLoadEventDelayCount);
+
+public:
+ IncrementLoadEventDelayCount(Document&);
+ ~IncrementLoadEventDelayCount();
+
+ // Increments the new document's count and decrements the old count.
+ void documentChanged(Document& newDocument);
+
+private:
+ RefPtrWillBePersistent<Document> m_document;
+};
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp
index 5343cb9520f..a577323050d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp
@@ -23,72 +23,48 @@
#include "config.h"
#include "core/dom/LiveNodeList.h"
-#include "core/dom/Element.h"
-#include "core/html/HTMLCollection.h"
-
namespace WebCore {
-Node& LiveNodeListBase::rootNode() const
+static inline bool isMatchingElement(const LiveNodeList& nodeList, const Element& element)
{
- if (isRootedAtDocument() && m_ownerNode->inDocument())
- return m_ownerNode->document();
- return *m_ownerNode;
+ return nodeList.elementMatches(element);
}
-ContainerNode* LiveNodeListBase::rootContainerNode() const
+Node* LiveNodeList::virtualOwnerNode() const
{
- Node& rootNode = this->rootNode();
- if (!rootNode.isContainerNode())
- return 0;
- return toContainerNode(&rootNode);
+ return &ownerNode();
}
-void LiveNodeListBase::invalidateCache() const
+void LiveNodeList::invalidateCache(Document*) const
{
- m_cachedItem = 0;
- m_isLengthCacheValid = false;
- m_isItemCacheValid = false;
- m_isNameCacheValid = false;
- m_isItemRefElementsCacheValid = false;
- if (isNodeList(type()))
- return;
-
- const HTMLCollection* cacheBase = static_cast<const HTMLCollection*>(this);
- cacheBase->m_idCache.clear();
- cacheBase->m_nameCache.clear();
- cacheBase->m_cachedElementsArrayOffset = 0;
+ m_collectionIndexCache.invalidate();
}
-void LiveNodeListBase::invalidateIdNameCacheMaps() const
+Element* LiveNodeList::traverseToFirstElement() const
{
- ASSERT(hasIdNameCache());
- const HTMLCollection* cacheBase = static_cast<const HTMLCollection*>(this);
- cacheBase->m_idCache.clear();
- cacheBase->m_nameCache.clear();
+ return firstMatchingElement(*this);
}
-Node* LiveNodeList::namedItem(const AtomicString& elementId) const
+Element* LiveNodeList::traverseToLastElement() const
{
- Node& rootNode = this->rootNode();
+ return lastMatchingElement(*this);
+}
- if (rootNode.inDocument()) {
- Element* element = rootNode.treeScope().getElementById(elementId);
- if (element && nodeMatches(element) && element->isDescendantOf(&rootNode))
- return element;
- if (!element)
- return 0;
- // In the case of multiple nodes with the same name, just fall through.
- }
+Element* LiveNodeList::traverseForwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const
+{
+ return traverseMatchingElementsForwardToOffset(*this, offset, currentNode, currentOffset);
+}
- unsigned length = this->length();
- for (unsigned i = 0; i < length; i++) {
- Node* node = item(i);
- // FIXME: This should probably be using getIdAttribute instead of idForStyleResolution.
- if (node->hasID() && toElement(node)->idForStyleResolution() == elementId)
- return node;
- }
+Element* LiveNodeList::traverseBackwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const
+{
+ return traverseMatchingElementsBackwardToOffset(*this, offset, currentNode, currentOffset);
+}
- return 0;
+void LiveNodeList::trace(Visitor* visitor)
+{
+ visitor->trace(m_collectionIndexCache);
+ LiveNodeListBase::trace(visitor);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h
index 2145b245f9e..ca2da3aedd1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h
@@ -24,182 +24,55 @@
#ifndef LiveNodeList_h
#define LiveNodeList_h
-#include "HTMLNames.h"
-#include "core/dom/Document.h"
+#include "core/dom/LiveNodeListBase.h"
#include "core/dom/NodeList.h"
+#include "core/html/CollectionIndexCache.h"
#include "core/html/CollectionType.h"
-#include "wtf/Forward.h"
-#include "wtf/RefPtr.h"
+#include "platform/heap/Handle.h"
+#include "wtf/PassRefPtr.h"
namespace WebCore {
class Element;
-enum NodeListRootType {
- NodeListIsRootedAtNode,
- NodeListIsRootedAtDocument,
- NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr,
-};
-
-class LiveNodeListBase : public NodeList {
+class LiveNodeList : public NodeList, public LiveNodeListBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(LiveNodeList);
public:
- enum ItemAfterOverrideType {
- OverridesItemAfter,
- DoesNotOverrideItemAfter,
- };
-
- LiveNodeListBase(Node* ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
- bool shouldOnlyIncludeDirectChildren, CollectionType collectionType, ItemAfterOverrideType itemAfterOverrideType)
- : m_ownerNode(ownerNode)
- , m_cachedItem(0)
- , m_isLengthCacheValid(false)
- , m_isItemCacheValid(false)
- , m_rootType(rootType)
- , m_invalidationType(invalidationType)
- , m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren)
- , m_isNameCacheValid(false)
- , m_collectionType(collectionType)
- , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
- , m_isItemRefElementsCacheValid(false)
- {
- ASSERT(m_rootType == static_cast<unsigned>(rootType));
- ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
- ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
- ASSERT(!m_overridesItemAfter || !isNodeList(collectionType));
-
- if (collectionType != ChildNodeListType)
- document().registerNodeList(this);
- }
-
- virtual ~LiveNodeListBase()
- {
- if (type() != ChildNodeListType)
- document().unregisterNodeList(this);
- }
-
- // DOM API
- virtual unsigned length() const OVERRIDE;
- virtual Node* item(unsigned offset) const OVERRIDE;
-
- ALWAYS_INLINE bool hasIdNameCache() const { return !isNodeList(type()); }
- ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr; }
- ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
- ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
- Node* ownerNode() const { return m_ownerNode.get(); }
- ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const
- {
- if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
- invalidateCache();
- else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr))
- invalidateIdNameCacheMaps();
- }
- void invalidateCache() const;
- void invalidateIdNameCacheMaps() const;
-
- static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
-
-protected:
- Document& document() const { return m_ownerNode->document(); }
- Node& rootNode() const;
- ContainerNode* rootContainerNode() const;
- bool overridesItemAfter() const { return m_overridesItemAfter; }
-
- ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; }
- ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; }
- ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; }
-
- ALWAYS_INLINE bool isLengthCacheValid() const { return m_isLengthCacheValid; }
- ALWAYS_INLINE unsigned cachedLength() const { return m_cachedLength; }
- ALWAYS_INLINE void setLengthCache(unsigned length) const
- {
- m_cachedLength = length;
- m_isLengthCacheValid = true;
- }
- ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const
- {
- ASSERT(item);
- m_cachedItem = item;
- m_cachedItemOffset = offset;
- m_isItemCacheValid = true;
- }
- void setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const;
-
- ALWAYS_INLINE bool isItemRefElementsCacheValid() const { return m_isItemRefElementsCacheValid; }
- ALWAYS_INLINE void setItemRefElementsCacheValid() const { m_isItemRefElementsCacheValid = true; }
-
- ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
-
- bool hasNameCache() const { return m_isNameCacheValid; }
- void setHasNameCache() const { m_isNameCacheValid = true; }
-
- bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; }
+ LiveNodeList(ContainerNode& ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
+ : LiveNodeListBase(ownerNode, rootType, invalidationType, collectionType) { }
-private:
- Node* itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const;
- Node* traverseChildNodeListForwardToOffset(unsigned offset, Node* currentNode, unsigned& currentOffset) const;
- Element* traverseLiveNodeListFirstElement(ContainerNode& root) const;
- Element* traverseLiveNodeListForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) const;
- bool isLastItemCloserThanLastOrCachedItem(unsigned offset) const;
- bool isFirstItemCloserThanCachedItem(unsigned offset) const;
- Node* iterateForPreviousNode(Node* current) const;
- Node* itemBefore(Node* previousItem) const;
-
- RefPtr<Node> m_ownerNode;
- mutable Node* m_cachedItem;
- mutable unsigned m_cachedLength;
- mutable unsigned m_cachedItemOffset;
- mutable unsigned m_isLengthCacheValid : 1;
- mutable unsigned m_isItemCacheValid : 1;
- const unsigned m_rootType : 2;
- const unsigned m_invalidationType : 4;
- const unsigned m_shouldOnlyIncludeDirectChildren : 1;
-
- // From HTMLCollection
- mutable unsigned m_isNameCacheValid : 1;
- const unsigned m_collectionType : 5;
- const unsigned m_overridesItemAfter : 1;
- mutable unsigned m_isItemRefElementsCacheValid : 1;
-};
+ virtual unsigned length() const OVERRIDE FINAL { return m_collectionIndexCache.nodeCount(*this); }
+ virtual Element* item(unsigned offset) const OVERRIDE FINAL { return m_collectionIndexCache.nodeAt(*this, offset); }
+ virtual bool elementMatches(const Element&) const = 0;
-ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)
-{
- switch (type) {
- case InvalidateOnClassAttrChange:
- return attrName == HTMLNames::classAttr;
- case InvalidateOnNameAttrChange:
- return attrName == HTMLNames::nameAttr;
- case InvalidateOnIdNameAttrChange:
- return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr;
- case InvalidateOnForAttrChange:
- return attrName == HTMLNames::forAttr;
- case InvalidateForFormControls:
- return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
- || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
- case InvalidateOnHRefAttrChange:
- return attrName == HTMLNames::hrefAttr;
- case InvalidateOnItemAttrChange:
- case DoNotInvalidateOnAttributeChanges:
- return false;
- case InvalidateOnAnyAttrChange:
- return true;
- }
- return false;
-}
+ virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE FINAL;
+ void invalidateCacheForAttribute(const QualifiedName*) const;
-class LiveNodeList : public LiveNodeListBase {
-public:
- LiveNodeList(PassRefPtr<Node> ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
- : LiveNodeListBase(ownerNode.get(), rootType, invalidationType, collectionType == ChildNodeListType,
- collectionType, DoesNotOverrideItemAfter)
- { }
+ bool shouldOnlyIncludeDirectChildren() const { return false; }
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
- virtual bool nodeMatches(Element*) const = 0;
+ // Collection IndexCache API.
+ bool canTraverseBackward() const { return true; }
+ Element* traverseToFirstElement() const;
+ Element* traverseToLastElement() const;
+ Element* traverseForwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const;
+ Element* traverseBackwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- virtual bool isLiveNodeList() const OVERRIDE { return true; }
+ virtual Node* virtualOwnerNode() const OVERRIDE FINAL;
+
+ mutable CollectionIndexCache<LiveNodeList, Element> m_collectionIndexCache;
};
+DEFINE_TYPE_CASTS(LiveNodeList, LiveNodeListBase, list, isLiveNodeListType(list->type()), isLiveNodeListType(list.type()));
+
+inline void LiveNodeList::invalidateCacheForAttribute(const QualifiedName* attrName) const
+{
+ if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+ invalidateCache();
+}
+
} // namespace WebCore
#endif // LiveNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp
new file mode 100644
index 00000000000..bfcea21151d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/LiveNodeListBase.h"
+
+#include "core/dom/LiveNodeList.h"
+#include "core/html/HTMLCollection.h"
+
+namespace WebCore {
+
+void LiveNodeListBase::invalidateCacheForAttribute(const QualifiedName* attrName) const
+{
+ if (isLiveNodeListType(type()))
+ toLiveNodeList(this)->invalidateCacheForAttribute(attrName);
+ else
+ toHTMLCollection(this)->invalidateCacheForAttribute(attrName);
+}
+
+ContainerNode& LiveNodeListBase::rootNode() const
+{
+ if (isRootedAtDocument() && m_ownerNode->inDocument())
+ return m_ownerNode->document();
+ return *m_ownerNode;
+}
+
+void LiveNodeListBase::didMoveToDocument(Document& oldDocument, Document& newDocument)
+{
+ invalidateCache(&oldDocument);
+ oldDocument.unregisterNodeList(this);
+ newDocument.registerNodeList(this);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h
new file mode 100644
index 00000000000..f301ad89d77
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LiveNodeListBase_h
+#define LiveNodeListBase_h
+
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/NodeTraversal.h"
+#include "core/html/CollectionType.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+enum NodeListRootType {
+ NodeListIsRootedAtNode,
+ NodeListIsRootedAtDocument
+};
+
+class LiveNodeListBase : public WillBeGarbageCollectedMixin {
+public:
+ LiveNodeListBase(ContainerNode& ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
+ CollectionType collectionType)
+ : m_ownerNode(ownerNode)
+ , m_rootType(rootType)
+ , m_invalidationType(invalidationType)
+ , m_collectionType(collectionType)
+ {
+ ASSERT(m_rootType == static_cast<unsigned>(rootType));
+ ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
+ ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
+
+ document().registerNodeList(this);
+ }
+
+ virtual ~LiveNodeListBase()
+ {
+#if !ENABLE(OILPAN)
+ document().unregisterNodeList(this);
+#endif
+ }
+
+ ContainerNode& rootNode() const;
+
+ void didMoveToDocument(Document& oldDocument, Document& newDocument);
+ ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument; }
+ ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
+ ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
+ ContainerNode& ownerNode() const { return *m_ownerNode; }
+
+ virtual void invalidateCache(Document* oldDocument = 0) const = 0;
+ void invalidateCacheForAttribute(const QualifiedName*) const;
+
+ static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
+
+protected:
+ Document& document() const { return m_ownerNode->document(); }
+
+ ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
+
+ template <class NodeListType>
+ static Element* firstMatchingElement(const NodeListType&);
+ template <class NodeListType>
+ static Element* lastMatchingElement(const NodeListType&);
+ template <class NodeListType>
+ static Element* nextMatchingElement(const NodeListType&, Element& current);
+ template <class NodeListType>
+ static Element* previousMatchingElement(const NodeListType&, Element& current);
+ template <class NodeListType>
+ static Element* traverseMatchingElementsForwardToOffset(const NodeListType&, unsigned offset, Element& currentElement, unsigned& currentOffset);
+ template <class NodeListType>
+ static Element* traverseMatchingElementsBackwardToOffset(const NodeListType&, unsigned offset, Element& currentElement, unsigned& currentOffset);
+
+ void trace(Visitor* visitor) { visitor->trace(m_ownerNode); }
+
+private:
+ RefPtrWillBeMember<ContainerNode> m_ownerNode; // Cannot be null.
+ const unsigned m_rootType : 1;
+ const unsigned m_invalidationType : 4;
+ const unsigned m_collectionType : 5;
+};
+
+ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)
+{
+ switch (type) {
+ case InvalidateOnClassAttrChange:
+ return attrName == HTMLNames::classAttr;
+ case InvalidateOnNameAttrChange:
+ return attrName == HTMLNames::nameAttr;
+ case InvalidateOnIdNameAttrChange:
+ return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr;
+ case InvalidateOnForAttrChange:
+ return attrName == HTMLNames::forAttr;
+ case InvalidateForFormControls:
+ return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
+ || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
+ case InvalidateOnHRefAttrChange:
+ return attrName == HTMLNames::hrefAttr;
+ case DoNotInvalidateOnAttributeChanges:
+ return false;
+ case InvalidateOnAnyAttrChange:
+ return true;
+ }
+ return false;
+}
+
+template <typename NodeListType>
+Element* LiveNodeListBase::lastMatchingElement(const NodeListType& nodeList)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* element = ElementTraversal::lastWithin(root);
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::previous(*element, &root);
+ return element;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::firstMatchingElement(const NodeListType& nodeList)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* element = ElementTraversal::firstWithin(root);
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::next(*element, &root);
+ return element;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::nextMatchingElement(const NodeListType& nodeList, Element& current)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* next = &current;
+ do {
+ next = ElementTraversal::next(*next, &root);
+ } while (next && !isMatchingElement(nodeList, *next));
+ return next;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::previousMatchingElement(const NodeListType& nodeList, Element& current)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* previous = &current;
+ do {
+ previous = ElementTraversal::previous(*previous, &root);
+ } while (previous && !isMatchingElement(nodeList, *previous));
+ return previous;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::traverseMatchingElementsForwardToOffset(const NodeListType& nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset)
+{
+ ASSERT(currentOffset < offset);
+ Element* next = &currentElement;
+ while ((next = nextMatchingElement(nodeList, *next))) {
+ if (++currentOffset == offset)
+ return next;
+ }
+ return 0;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::traverseMatchingElementsBackwardToOffset(const NodeListType& nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset)
+{
+ ASSERT(currentOffset > offset);
+ Element* previous = &currentElement;
+ while ((previous = previousMatchingElement(nodeList, *previous))) {
+ if (--currentOffset == offset)
+ return previous;
+ }
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // LiveNodeListBase_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp
index 976d971ce66..d8b53106188 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp
@@ -99,7 +99,7 @@ void MainThreadTaskRunner::resume()
{
ASSERT(m_suspended);
if (!m_pendingTasks.isEmpty())
- m_pendingTasksTimer.startOneShot(0);
+ m_pendingTasksTimer.startOneShot(0, FROM_HERE);
m_suspended = false;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp
index ca1779947a4..56e05f9940d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp
@@ -28,50 +28,19 @@
#include "config.h"
#include "core/dom/MainThreadTaskRunner.h"
-#include "core/dom/ExecutionContext.h"
#include "core/dom/ExecutionContextTask.h"
-#include "core/events/EventQueue.h"
+#include "core/testing/NullExecutionContext.h"
#include "core/testing/UnitTestHelpers.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
#include <gtest/gtest.h>
using namespace WebCore;
namespace {
-class NullEventQueue : public EventQueue {
-public:
- NullEventQueue() { }
- virtual ~NullEventQueue() { }
- virtual bool enqueueEvent(PassRefPtr<Event>) OVERRIDE { return true; }
- virtual bool cancelEvent(Event*) OVERRIDE { return true; }
- virtual void close() OVERRIDE { }
-};
-
-class NullExecutionContext : public ExecutionContext, public RefCounted<NullExecutionContext> {
-public:
- using RefCounted<NullExecutionContext>::ref;
- using RefCounted<NullExecutionContext>::deref;
-
- virtual void refExecutionContext() OVERRIDE { ref(); }
- virtual void derefExecutionContext() OVERRIDE { deref(); }
- virtual EventQueue* eventQueue() const OVERRIDE { return m_queue.get(); }
- virtual bool tasksNeedSuspension() { return m_tasksNeedSuspension; }
-
- void setTasksNeedSuspention(bool flag) { m_tasksNeedSuspension = flag; }
-
- NullExecutionContext();
-
-private:
- bool m_tasksNeedSuspension;
- OwnPtr<EventQueue> m_queue;
-};
-
-NullExecutionContext::NullExecutionContext()
- : m_tasksNeedSuspension(false)
- , m_queue(adoptPtr(new NullEventQueue()))
-{
-}
-
class MarkingBooleanTask FINAL : public ExecutionContextTask {
public:
static PassOwnPtr<MarkingBooleanTask> create(bool* toBeMarked)
@@ -95,7 +64,7 @@ private:
TEST(MainThreadTaskRunnerTest, PostTask)
{
- RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
+ RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
@@ -107,17 +76,17 @@ TEST(MainThreadTaskRunnerTest, PostTask)
TEST(MainThreadTaskRunnerTest, SuspendTask)
{
- RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
+ RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
- context->setTasksNeedSuspention(true);
+ context->setTasksNeedSuspension(true);
runner->postTask(MarkingBooleanTask::create(&isMarked));
runner->suspend();
WebCore::testing::runPendingTasks();
EXPECT_FALSE(isMarked);
- context->setTasksNeedSuspention(false);
+ context->setTasksNeedSuspension(false);
runner->resume();
WebCore::testing::runPendingTasks();
EXPECT_TRUE(isMarked);
@@ -125,11 +94,11 @@ TEST(MainThreadTaskRunnerTest, SuspendTask)
TEST(MainThreadTaskRunnerTest, RemoveRunner)
{
- RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
+ RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
- context->setTasksNeedSuspention(true);
+ context->setTasksNeedSuspension(true);
runner->postTask(MarkingBooleanTask::create(&isMarked));
runner.clear();
WebCore::testing::runPendingTasks();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp
index 20a493d97c8..0131a3b6581 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp
@@ -35,17 +35,14 @@ namespace WebCore {
static void createChannel(MessagePort* port1, MessagePort* port2)
{
- // Create proxies for each endpoint.
- OwnPtr<blink::WebMessagePortChannel> channel1 = adoptPtr(blink::Platform::current()->createMessagePortChannel());
- OwnPtr<blink::WebMessagePortChannel> channel2 = adoptPtr(blink::Platform::current()->createMessagePortChannel());
-
- // Entangle the two endpoints.
- channel1->entangle(channel2.get());
- channel2->entangle(channel1.get());
+ blink::WebMessagePortChannel* channel1;
+ blink::WebMessagePortChannel* channel2;
+ blink::Platform::current()->createMessageChannel(&channel1, &channel2);
+ ASSERT(channel1 && channel2);
// Now entangle the proxies with the appropriate local ports.
- port1->entangle(channel2.release());
- port2->entangle(channel1.release());
+ port1->entangle(adoptPtr(channel2));
+ port2->entangle(adoptPtr(channel1));
}
MessageChannel::MessageChannel(ExecutionContext* context)
@@ -60,4 +57,10 @@ MessageChannel::~MessageChannel()
{
}
+void MessageChannel::trace(Visitor* visitor)
+{
+ visitor->trace(m_port1);
+ visitor->trace(m_port2);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h
index 5b1dc49a04f..750c601e5fc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h
@@ -28,6 +28,7 @@
#define MessageChannel_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -37,19 +38,24 @@ namespace WebCore {
class MessagePort;
class ExecutionContext;
-class MessageChannel : public RefCounted<MessageChannel>, public ScriptWrappable {
+class MessageChannel FINAL : public RefCountedWillBeGarbageCollectedFinalized<MessageChannel>, public ScriptWrappable {
public:
- static PassRefPtr<MessageChannel> create(ExecutionContext* context) { return adoptRef(new MessageChannel(context)); }
+ static PassRefPtrWillBeRawPtr<MessageChannel> create(ExecutionContext* context)
+ {
+ return adoptRefWillBeNoop(new MessageChannel(context));
+ }
~MessageChannel();
MessagePort* port1() const { return m_port1.get(); }
MessagePort* port2() const { return m_port2.get(); }
+ void trace(Visitor*);
+
private:
explicit MessageChannel(ExecutionContext*);
- RefPtr<MessagePort> m_port1;
- RefPtr<MessagePort> m_port2;
+ RefPtrWillBeMember<MessagePort> m_port1;
+ RefPtrWillBeMember<MessagePort> m_port2;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl
index fbd8babde20..3a1123c78d1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl
@@ -26,7 +26,8 @@
[
CustomConstructor,
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
+ WillBeGarbageCollected
] interface MessageChannel {
readonly attribute MessagePort port1;
readonly attribute MessagePort port2;
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp b/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp
index 887bfc9bad7..1426ddbb838 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp
@@ -34,8 +34,7 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/events/MessageEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/workers/WorkerGlobalScope.h"
#include "public/platform/WebString.h"
#include "wtf/Functional.h"
@@ -43,9 +42,9 @@
namespace WebCore {
-PassRefPtr<MessagePort> MessagePort::create(ExecutionContext& executionContext)
+PassRefPtrWillBeRawPtr<MessagePort> MessagePort::create(ExecutionContext& executionContext)
{
- RefPtr<MessagePort> port = adoptRef(new MessagePort(executionContext));
+ RefPtrWillBeRawPtr<MessagePort> port = adoptRefWillBeRefCountedGarbageCollected(new MessagePort(executionContext));
port->suspendIfNeeded();
return port.release();
}
@@ -74,10 +73,10 @@ void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const M
OwnPtr<MessagePortChannelArray> channels;
// Make sure we aren't connected to any of the passed-in ports.
if (ports) {
- for (unsigned int i = 0; i < ports->size(); ++i) {
+ for (unsigned i = 0; i < ports->size(); ++i) {
MessagePort* dataPort = (*ports)[i].get();
if (dataPort == this) {
- exceptionState.throwDOMException(DataCloneError, "Item #" + String::number(i) + " in the array of ports contains the source port.");
+ exceptionState.throwDOMException(DataCloneError, "Port at index " + String::number(i) + " contains the source port.");
return;
}
}
@@ -87,13 +86,33 @@ void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const M
}
blink::WebString messageString = message->toWireString();
- blink::WebMessagePortChannelArray* webChannels = 0;
+ OwnPtr<blink::WebMessagePortChannelArray> webChannels = toWebMessagePortChannelArray(channels.release());
+ m_entangledChannel->postMessage(messageString, webChannels.leakPtr());
+}
+
+// static
+PassOwnPtr<blink::WebMessagePortChannelArray> MessagePort::toWebMessagePortChannelArray(PassOwnPtr<MessagePortChannelArray> channels)
+{
+ OwnPtr<blink::WebMessagePortChannelArray> webChannels;
if (channels && channels->size()) {
- webChannels = new blink::WebMessagePortChannelArray(channels->size());
+ webChannels = adoptPtr(new blink::WebMessagePortChannelArray(channels->size()));
for (size_t i = 0; i < channels->size(); ++i)
(*webChannels)[i] = (*channels)[i].leakPtr();
}
- m_entangledChannel->postMessage(messageString, webChannels);
+ return webChannels.release();
+}
+
+// static
+PassOwnPtr<MessagePortArray> MessagePort::toMessagePortArray(ExecutionContext* context, const blink::WebMessagePortChannelArray& webChannels)
+{
+ OwnPtr<MessagePortArray> ports;
+ if (!webChannels.isEmpty()) {
+ OwnPtr<MessagePortChannelArray> channels = adoptPtr(new MessagePortChannelArray(webChannels.size()));
+ for (size_t i = 0; i < webChannels.size(); ++i)
+ (*channels)[i] = adoptPtr(webChannels[i]);
+ ports = MessagePort::entanglePorts(*context, channels.release());
+ }
+ return ports.release();
}
PassOwnPtr<blink::WebMessagePortChannel> MessagePort::disentangle()
@@ -178,7 +197,7 @@ void MessagePort::dispatchMessages()
return;
OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*executionContext(), channels.release());
- RefPtr<Event> evt = MessageEvent::create(ports.release(), message.release());
+ RefPtrWillBeRawPtr<Event> evt = MessageEvent::create(ports.release(), message.release());
dispatchEvent(evt.release(), ASSERT_NO_EXCEPTION);
}
@@ -210,7 +229,7 @@ PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessageP
type = "already neutered";
else
type = "a duplicate";
- exceptionState.throwDOMException(DataCloneError, "Item #" + String::number(i) + " in the array of ports is " + type + ".");
+ exceptionState.throwDOMException(DataCloneError, "Port at index " + String::number(i) + " is " + type + ".");
return nullptr;
}
portSet.add(port);
@@ -229,7 +248,7 @@ PassOwnPtr<MessagePortArray> MessagePort::entanglePorts(ExecutionContext& contex
return nullptr;
OwnPtr<MessagePortArray> portArray = adoptPtr(new MessagePortArray(channels->size()));
- for (unsigned int i = 0; i < channels->size(); ++i) {
+ for (unsigned i = 0; i < channels->size(); ++i) {
RefPtr<MessagePort> port = MessagePort::create(context);
port->entangle((*channels)[i].release());
(*portArray)[i] = port.release();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessagePort.h b/chromium/third_party/WebKit/Source/core/dom/MessagePort.h
index c5f78eac9ee..648f574979a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessagePort.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MessagePort.h
@@ -45,7 +45,7 @@ namespace WebCore {
class Event;
class ExceptionState;
-class Frame;
+class LocalFrame;
class MessagePort;
class ExecutionContext;
class SerializedScriptValue;
@@ -56,14 +56,15 @@ typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
// Not to be confused with blink::WebMessagePortChannelArray; this one uses Vector and OwnPtr instead of WebVector and raw pointers.
typedef Vector<OwnPtr<blink::WebMessagePortChannel>, 1> MessagePortChannelArray;
-class MessagePort : public RefCounted<MessagePort>
+class MessagePort FINAL : public RefCountedWillBeRefCountedGarbageCollected<MessagePort>
, public ActiveDOMObject
, public EventTargetWithInlineData
, public ScriptWrappable
, public blink::WebMessagePortChannelClient {
REFCOUNTED_EVENT_TARGET(MessagePort);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MessagePort);
public:
- static PassRefPtr<MessagePort> create(ExecutionContext&);
+ static PassRefPtrWillBeRawPtr<MessagePort> create(ExecutionContext&);
virtual ~MessagePort();
void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, ExceptionState&);
@@ -74,6 +75,9 @@ public:
void entangle(PassOwnPtr<blink::WebMessagePortChannel>);
PassOwnPtr<blink::WebMessagePortChannel> disentangle();
+ static PassOwnPtr<blink::WebMessagePortChannelArray> toWebMessagePortChannelArray(PassOwnPtr<MessagePortChannelArray>);
+ static PassOwnPtr<MessagePortArray> toMessagePortArray(ExecutionContext*, const blink::WebMessagePortChannelArray&);
+
// Returns 0 if there is an exception, or if the passed-in array is 0/empty.
static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionState&);
@@ -84,18 +88,18 @@ public:
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE { return ActiveDOMObject::executionContext(); }
- MessagePort* toMessagePort() OVERRIDE { return this; }
+ virtual MessagePort* toMessagePort() OVERRIDE { return this; }
// ActiveDOMObject implementation.
virtual bool hasPendingActivity() const OVERRIDE;
virtual void stop() OVERRIDE { close(); }
- void setOnmessage(PassRefPtr<EventListener> listener, DOMWrapperWorld* world)
+ void setOnmessage(PassRefPtr<EventListener> listener)
{
- setAttributeEventListener(EventTypeNames::message, listener, world);
+ setAttributeEventListener(EventTypeNames::message, listener);
start();
}
- EventListener* onmessage(DOMWrapperWorld* world) { return getAttributeEventListener(EventTypeNames::message, world); }
+ EventListener* onmessage() { return getAttributeEventListener(EventTypeNames::message); }
// A port starts out its life entangled, and remains entangled until it is closed or is cloned.
bool isEntangled() const { return !m_closed && !isNeutered(); }
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl b/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl
index 17ae44910fe..f834df6318a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl
@@ -26,9 +26,10 @@
*/
[
- ActiveDOMObject
+ ActiveDOMObject,
+ WillBeGarbageCollected
] interface MessagePort : EventTarget {
- [Custom, RaisesException] void postMessage(any message, optional Array messagePorts);
+ [Custom, RaisesException] void postMessage(any message, optional MessagePort[] messagePorts);
void start();
void close();
diff --git a/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp b/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp
index 27cd2178f46..c732cdcaaaf 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp
@@ -31,26 +31,41 @@
#include "config.h"
#include "core/dom/Microtask.h"
-#include "core/dom/MutationObserver.h"
-#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+#include "bindings/v8/V8PerIsolateData.h"
+#include "platform/Task.h"
+#include "public/platform/WebThread.h"
#include "wtf/Vector.h"
+#include <v8.h>
namespace WebCore {
void Microtask::performCheckpoint()
{
- static bool performingCheckpoint = false;
- if (performingCheckpoint)
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
+ ASSERT(isolateData);
+ if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint())
return;
- performingCheckpoint = true;
+ isolateData->setPerformingMicrotaskCheckpoint(true);
+ isolate->RunMicrotasks();
+ isolateData->setPerformingMicrotaskCheckpoint(false);
+}
- bool anyWorkDone;
- do {
- MutationObserver::deliverAllMutations();
- anyWorkDone = CustomElementCallbackDispatcher::instance().dispatch();
- } while (anyWorkDone);
+static void microtaskFunctionCallback(void* data)
+{
+ OwnPtr<blink::WebThread::Task> task = adoptPtr(static_cast<blink::WebThread::Task*>(data));
+ task->run();
+}
- performingCheckpoint = false;
+void Microtask::enqueueMicrotask(PassOwnPtr<blink::WebThread::Task> callback)
+{
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ isolate->EnqueueMicrotask(&microtaskFunctionCallback, callback.leakPtr());
+}
+
+void Microtask::enqueueMicrotask(const Closure& callback)
+{
+ enqueueMicrotask(adoptPtr(new Task(callback)));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Microtask.h b/chromium/third_party/WebKit/Source/core/dom/Microtask.h
index 27f72cbec01..5bea815d0a9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Microtask.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Microtask.h
@@ -31,11 +31,17 @@
#ifndef Microtask_h
#define Microtask_h
+#include "public/platform/WebThread.h"
+#include "wtf/Functional.h"
+#include "wtf/PassOwnPtr.h"
+
namespace WebCore {
class Microtask {
public:
static void performCheckpoint();
+ static void enqueueMicrotask(PassOwnPtr<blink::WebThread::Task>);
+ static void enqueueMicrotask(const Closure&);
private:
explicit Microtask();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h b/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h
index 88f230bb35d..9445becca81 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h
@@ -31,6 +31,7 @@
#ifndef MutationCallback_h
#define MutationCallback_h
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
@@ -43,7 +44,7 @@ class MutationCallback {
public:
virtual ~MutationCallback() { }
- virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) = 0;
+ virtual void call(const WillBeHeapVector<RefPtrWillBeMember<MutationRecord> >&, MutationObserver*) = 0;
virtual ExecutionContext* executionContext() const = 0;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp
index 06e610a33f4..e36a1a7b243 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp
@@ -36,10 +36,12 @@
#include "bindings/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/Microtask.h"
#include "core/dom/MutationCallback.h"
#include "core/dom/MutationObserverRegistration.h"
#include "core/dom/MutationRecord.h"
#include "core/dom/Node.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "wtf/MainThread.h"
namespace WebCore {
@@ -47,16 +49,16 @@ namespace WebCore {
static unsigned s_observerPriority = 0;
struct MutationObserver::ObserverLessThan {
- bool operator()(const RefPtr<MutationObserver>& lhs, const RefPtr<MutationObserver>& rhs)
+ bool operator()(const RefPtrWillBeMember<MutationObserver>& lhs, const RefPtrWillBeMember<MutationObserver>& rhs)
{
return lhs->m_priority < rhs->m_priority;
}
};
-PassRefPtr<MutationObserver> MutationObserver::create(PassOwnPtr<MutationCallback> callback)
+PassRefPtrWillBeRawPtr<MutationObserver> MutationObserver::create(PassOwnPtr<MutationCallback> callback)
{
ASSERT(isMainThread());
- return adoptRef(new MutationObserver(callback));
+ return adoptRefWillBeNoop(new MutationObserver(callback));
}
MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback)
@@ -68,7 +70,11 @@ MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback)
MutationObserver::~MutationObserver()
{
+#if !ENABLE(OILPAN)
ASSERT(m_registrations.isEmpty());
+#endif
+ if (!m_records.isEmpty())
+ InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionContext(), this);
}
void MutationObserver::observe(Node* node, const Dictionary& optionsDictionary, ExceptionState& exceptionState)
@@ -115,40 +121,43 @@ void MutationObserver::observe(Node* node, const Dictionary& optionsDictionary,
if (!(options & Attributes)) {
if (options & AttributeOldValue) {
- exceptionState.throwDOMException(TypeError, "The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.");
+ exceptionState.throwTypeError("The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.");
return;
}
if (options & AttributeFilter) {
- exceptionState.throwDOMException(TypeError, "The options object may only set 'attributeFilter' when 'attributes' is true or not present.");
+ exceptionState.throwTypeError("The options object may only set 'attributeFilter' when 'attributes' is true or not present.");
return;
}
}
if (!((options & CharacterData) || !(options & CharacterDataOldValue))) {
- exceptionState.throwDOMException(TypeError, "The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.");
+ exceptionState.throwTypeError("The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.");
return;
}
if (!(options & (Attributes | CharacterData | ChildList))) {
- exceptionState.throwDOMException(TypeError, "The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
+ exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
return;
}
- node->registerMutationObserver(this, options, attributeFilter);
+ node->registerMutationObserver(*this, options, attributeFilter);
}
-Vector<RefPtr<MutationRecord> > MutationObserver::takeRecords()
+MutationRecordVector MutationObserver::takeRecords()
{
- Vector<RefPtr<MutationRecord> > records;
+ MutationRecordVector records;
records.swap(m_records);
+ InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionContext(), this);
return records;
}
void MutationObserver::disconnect()
{
m_records.clear();
- HashSet<MutationObserverRegistration*> registrations(m_registrations);
- for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
+ InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionContext(), this);
+ MutationObserverRegistrationSet registrations(m_registrations);
+ for (MutationObserverRegistrationSet::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
(*iter)->unregister();
+ ASSERT(m_registrations.isEmpty());
}
void MutationObserver::observationStarted(MutationObserverRegistration* registration)
@@ -163,37 +172,54 @@ void MutationObserver::observationEnded(MutationObserverRegistration* registrati
m_registrations.remove(registration);
}
-typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet;
-
static MutationObserverSet& activeMutationObservers()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, activeObservers, (new MutationObserverSet()));
+ return *activeObservers;
+#else
DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ());
return activeObservers;
+#endif
}
static MutationObserverSet& suspendedMutationObservers()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspendedObservers, (new MutationObserverSet()));
+ return *suspendedObservers;
+#else
DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ());
return suspendedObservers;
+#endif
}
-void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation)
+static void activateObserver(PassRefPtrWillBeRawPtr<MutationObserver> observer)
+{
+ if (activeMutationObservers().isEmpty())
+ Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations));
+
+ activeMutationObservers().add(observer);
+}
+
+void MutationObserver::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord> mutation)
{
ASSERT(isMainThread());
m_records.append(mutation);
- activeMutationObservers().add(this);
+ activateObserver(this);
+ InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionContext(), this);
}
void MutationObserver::setHasTransientRegistration()
{
ASSERT(isMainThread());
- activeMutationObservers().add(this);
+ activateObserver(this);
}
HashSet<Node*> MutationObserver::getObservedNodes() const
{
HashSet<Node*> observedNodes;
- for (HashSet<MutationObserverRegistration*>::const_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter)
+ for (MutationObserverRegistrationSet::const_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter)
(*iter)->addRegistrationNodesToSet(observedNodes);
return observedNodes;
}
@@ -209,8 +235,8 @@ void MutationObserver::deliver()
// Calling clearTransientRegistrations() can modify m_registrations, so it's necessary
// to make a copy of the transient registrations before operating on them.
- Vector<MutationObserverRegistration*, 1> transientRegistrations;
- for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) {
+ WillBeHeapVector<RawPtrWillBeMember<MutationObserverRegistration>, 1> transientRegistrations;
+ for (MutationObserverRegistrationSet::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) {
if ((*iter)->hasTransientRegistrations())
transientRegistrations.append(*iter);
}
@@ -220,46 +246,49 @@ void MutationObserver::deliver()
if (m_records.isEmpty())
return;
- Vector<RefPtr<MutationRecord> > records;
+ MutationRecordVector records;
records.swap(m_records);
+ InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionContext(), this);
m_callback->call(records, this);
+ InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionContext());
}
-void MutationObserver::deliverAllMutations()
+void MutationObserver::resumeSuspendedObservers()
{
ASSERT(isMainThread());
- static bool deliveryInProgress = false;
- if (deliveryInProgress)
+ if (suspendedMutationObservers().isEmpty())
return;
- deliveryInProgress = true;
-
- if (!suspendedMutationObservers().isEmpty()) {
- Vector<RefPtr<MutationObserver> > suspended;
- copyToVector(suspendedMutationObservers(), suspended);
- for (size_t i = 0; i < suspended.size(); ++i) {
- if (!suspended[i]->canDeliver())
- continue;
+ MutationObserverVector suspended;
+ copyToVector(suspendedMutationObservers(), suspended);
+ for (size_t i = 0; i < suspended.size(); ++i) {
+ if (suspended[i]->canDeliver()) {
suspendedMutationObservers().remove(suspended[i]);
- activeMutationObservers().add(suspended[i]);
+ activateObserver(suspended[i]);
}
}
+}
- while (!activeMutationObservers().isEmpty()) {
- Vector<RefPtr<MutationObserver> > observers;
- copyToVector(activeMutationObservers(), observers);
- activeMutationObservers().clear();
- std::sort(observers.begin(), observers.end(), ObserverLessThan());
- for (size_t i = 0; i < observers.size(); ++i) {
- if (observers[i]->canDeliver())
- observers[i]->deliver();
- else
- suspendedMutationObservers().add(observers[i]);
- }
+void MutationObserver::deliverMutations()
+{
+ ASSERT(isMainThread());
+ MutationObserverVector observers;
+ copyToVector(activeMutationObservers(), observers);
+ activeMutationObservers().clear();
+ std::sort(observers.begin(), observers.end(), ObserverLessThan());
+ for (size_t i = 0; i < observers.size(); ++i) {
+ if (observers[i]->canDeliver())
+ observers[i]->deliver();
+ else
+ suspendedMutationObservers().add(observers[i]);
}
+}
- deliveryInProgress = false;
+void MutationObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_records);
+ visitor->trace(m_registrations);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h
index 062d01edfe1..5036587d3bd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h
@@ -32,7 +32,9 @@
#define MutationObserver_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -43,6 +45,7 @@ namespace WebCore {
class Dictionary;
class ExceptionState;
class MutationCallback;
+class MutationObserver;
class MutationObserverRegistration;
class MutationRecord;
class Node;
@@ -50,7 +53,12 @@ class Node;
typedef unsigned char MutationObserverOptions;
typedef unsigned char MutationRecordDeliveryOptions;
-class MutationObserver : public RefCounted<MutationObserver>, public ScriptWrappable {
+typedef WillBeHeapHashSet<RefPtrWillBeMember<MutationObserver> > MutationObserverSet;
+typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> > MutationObserverRegistrationSet;
+typedef WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > MutationObserverVector;
+typedef WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > MutationRecordVector;
+
+class MutationObserver FINAL : public RefCountedWillBeGarbageCollectedFinalized<MutationObserver>, public ScriptWrappable {
public:
enum MutationType {
ChildList = 1 << 0,
@@ -70,22 +78,25 @@ public:
CharacterDataOldValue = 1 << 6,
};
- static PassRefPtr<MutationObserver> create(PassOwnPtr<MutationCallback>);
- static void deliverAllMutations();
+ static PassRefPtrWillBeRawPtr<MutationObserver> create(PassOwnPtr<MutationCallback>);
+ static void resumeSuspendedObservers();
+ static void deliverMutations();
~MutationObserver();
void observe(Node*, const Dictionary&, ExceptionState&);
- Vector<RefPtr<MutationRecord> > takeRecords();
+ WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > takeRecords();
void disconnect();
void observationStarted(MutationObserverRegistration*);
void observationEnded(MutationObserverRegistration*);
- void enqueueMutationRecord(PassRefPtr<MutationRecord>);
+ void enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord>);
void setHasTransientRegistration();
bool canDeliver();
HashSet<Node*> getObservedNodes() const;
+ void trace(Visitor*);
+
private:
struct ObserverLessThan;
@@ -93,8 +104,8 @@ private:
void deliver();
OwnPtr<MutationCallback> m_callback;
- Vector<RefPtr<MutationRecord> > m_records;
- HashSet<MutationObserverRegistration*> m_registrations;
+ MutationRecordVector m_records;
+ MutationObserverRegistrationSet m_registrations;
unsigned m_priority;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl
index d16bb4fd3e2..2c6d142f8f8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl
@@ -30,6 +30,8 @@
[
CustomConstructor(MutationCallback callback),
+ Custom=VisitDOMWrapper,
+ WillBeGarbageCollected,
] interface MutationObserver {
[RaisesException] void observe(Node target, Dictionary options);
sequence<MutationRecord> takeRecords();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp
index e9e839ba0be..3d48535d5ff 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp
@@ -36,18 +36,18 @@
namespace WebCore {
-PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node& target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
+PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node& target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
{
ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
- HashMap<MutationObserver*, MutationRecordDeliveryOptions> observers;
+ WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions> observers;
target.getRegisteredMutationObserversOfType(observers, type, attributeName);
if (observers.isEmpty())
return nullptr;
- return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
+ return adoptPtrWillBeNoop(new MutationObserverInterestGroup(observers, oldValueFlag));
}
-MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
+MutationObserverInterestGroup::MutationObserverInterestGroup(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
: m_oldValueFlag(oldValueFlag)
{
ASSERT(!observers.isEmpty());
@@ -56,18 +56,18 @@ MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<MutationObs
bool MutationObserverInterestGroup::isOldValueRequested()
{
- for (HashMap<MutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
+ for (WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
if (hasOldValue(iter->value))
return true;
}
return false;
}
-void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRecord> prpMutation)
+void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord> prpMutation)
{
- RefPtr<MutationRecord> mutation = prpMutation;
- RefPtr<MutationRecord> mutationWithNullOldValue;
- for (HashMap<MutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
+ RefPtrWillBeRawPtr<MutationRecord> mutation = prpMutation;
+ RefPtrWillBeRawPtr<MutationRecord> mutationWithNullOldValue = nullptr;
+ for (WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
MutationObserver* observer = iter->key;
if (hasOldValue(iter->value)) {
observer->enqueueMutationRecord(mutation);
@@ -83,4 +83,9 @@ void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRec
}
}
+void MutationObserverInterestGroup::trace(Visitor* visitor)
+{
+ visitor->trace(m_observers);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h
index b149afcf935..9df7498930b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h
@@ -35,14 +35,15 @@
#include "core/dom/MutationObserver.h"
#include "core/dom/Node.h"
#include "core/dom/QualifiedName.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-class MutationObserverInterestGroup {
+class MutationObserverInterestGroup FINAL : public NoBaseWillBeGarbageCollectedFinalized<MutationObserverInterestGroup> {
public:
- static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node& target)
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createForChildListMutation(Node& target)
{
if (!target.document().hasMutationObserversOfType(MutationObserver::ChildList))
return nullptr;
@@ -51,7 +52,7 @@ public:
return createIfNeeded(target, MutationObserver::ChildList, oldValueFlag);
}
- static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node& target)
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node& target)
{
if (!target.document().hasMutationObserversOfType(MutationObserver::CharacterData))
return nullptr;
@@ -59,7 +60,7 @@ public:
return createIfNeeded(target, MutationObserver::CharacterData, MutationObserver::CharacterDataOldValue);
}
- static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node& target, const QualifiedName& attributeName)
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createForAttributesMutation(Node& target, const QualifiedName& attributeName)
{
if (!target.document().hasMutationObserversOfType(MutationObserver::Attributes))
return nullptr;
@@ -68,15 +69,17 @@ public:
}
bool isOldValueRequested();
- void enqueueMutationRecord(PassRefPtr<MutationRecord>);
+ void enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord>);
+
+ void trace(Visitor*);
private:
- static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node& target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
- MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createIfNeeded(Node& target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
+ MutationObserverInterestGroup(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
- HashMap<MutationObserver*, MutationRecordDeliveryOptions> m_observers;
+ WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions> m_observers;
MutationRecordDeliveryOptions m_oldValueFlag;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp
index 1ece4d1cbdc..5421360f707 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp
@@ -37,12 +37,12 @@
namespace WebCore {
-PassOwnPtr<MutationObserverRegistration> MutationObserverRegistration::create(PassRefPtr<MutationObserver> observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+PassOwnPtrWillBeRawPtr<MutationObserverRegistration> MutationObserverRegistration::create(MutationObserver& observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
{
- return adoptPtr(new MutationObserverRegistration(observer, registrationNode, options, attributeFilter));
+ return adoptPtrWillBeNoop(new MutationObserverRegistration(observer, registrationNode, options, attributeFilter));
}
-MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<MutationObserver> observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+MutationObserverRegistration::MutationObserverRegistration(MutationObserver& observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
: m_observer(observer)
, m_registrationNode(registrationNode)
, m_options(options)
@@ -53,8 +53,16 @@ MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<MutationOb
MutationObserverRegistration::~MutationObserverRegistration()
{
+#if !ENABLE(OILPAN)
+ dispose();
+#endif
+}
+
+void MutationObserverRegistration::dispose()
+{
clearTransientRegistrations();
m_observer->observationEnded(this);
+ m_observer.clear();
}
void MutationObserverRegistration::resetObservation(MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
@@ -64,21 +72,22 @@ void MutationObserverRegistration::resetObservation(MutationObserverOptions opti
m_attributeFilter = attributeFilter;
}
-void MutationObserverRegistration::observedSubtreeNodeWillDetach(Node* node)
+void MutationObserverRegistration::observedSubtreeNodeWillDetach(Node& node)
{
if (!isSubtree())
return;
- node->registerTransientMutationObserver(this);
+ node.registerTransientMutationObserver(this);
m_observer->setHasTransientRegistration();
if (!m_transientRegistrationNodes) {
- m_transientRegistrationNodes = adoptPtr(new NodeHashSet);
+ m_transientRegistrationNodes = adoptPtrWillBeNoop(new NodeHashSet);
+ ASSERT(m_registrationNode);
ASSERT(!m_registrationNodeKeepAlive);
- m_registrationNodeKeepAlive = m_registrationNode; // Balanced in clearTransientRegistrations.
+ m_registrationNodeKeepAlive = PassRefPtrWillBeRawPtr<Node>(m_registrationNode.get()); // Balanced in clearTransientRegistrations.
}
- m_transientRegistrationNodes->add(node);
+ m_transientRegistrationNodes->add(&node);
}
void MutationObserverRegistration::clearTransientRegistrations()
@@ -94,22 +103,23 @@ void MutationObserverRegistration::clearTransientRegistrations()
m_transientRegistrationNodes.clear();
ASSERT(m_registrationNodeKeepAlive);
- m_registrationNodeKeepAlive = 0; // Balanced in observeSubtreeNodeWillDetach.
+ m_registrationNodeKeepAlive = nullptr; // Balanced in observeSubtreeNodeWillDetach.
}
void MutationObserverRegistration::unregister()
{
+ ASSERT(m_registrationNode);
m_registrationNode->unregisterMutationObserver(this);
// The above line will cause this object to be deleted, so don't do any more in this function.
}
-bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
+bool MutationObserverRegistration::shouldReceiveMutationFrom(Node& node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
{
ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
if (!(m_options & type))
return false;
- if (m_registrationNode != node && !isSubtree())
+ if (m_registrationNode != &node && !isSubtree())
return false;
if (type != MutationObserver::Attributes || !(m_options & MutationObserver::AttributeFilter))
@@ -123,11 +133,22 @@ bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, Mutatio
void MutationObserverRegistration::addRegistrationNodesToSet(HashSet<Node*>& nodes) const
{
- nodes.add(m_registrationNode);
+ ASSERT(m_registrationNode);
+ nodes.add(m_registrationNode.get());
if (!m_transientRegistrationNodes)
return;
for (NodeHashSet::const_iterator iter = m_transientRegistrationNodes->begin(); iter != m_transientRegistrationNodes->end(); ++iter)
nodes.add(iter->get());
}
+void MutationObserverRegistration::trace(Visitor* visitor)
+{
+ visitor->trace(m_observer);
+ visitor->trace(m_registrationNode);
+ visitor->trace(m_registrationNodeKeepAlive);
+#if ENABLE(OILPAN)
+ visitor->trace(m_transientRegistrationNodes);
+#endif
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h
index 7c0fb527839..386a65aa230 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h
@@ -32,6 +32,7 @@
#define MutationObserverRegistration_h
#include "core/dom/MutationObserver.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/AtomicStringHash.h"
@@ -40,34 +41,38 @@ namespace WebCore {
class QualifiedName;
-class MutationObserverRegistration {
+class MutationObserverRegistration FINAL : public NoBaseWillBeGarbageCollectedFinalized<MutationObserverRegistration> {
public:
- static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<MutationObserver>, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ static PassOwnPtrWillBeRawPtr<MutationObserverRegistration> create(MutationObserver&, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
~MutationObserverRegistration();
void resetObservation(MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
- void observedSubtreeNodeWillDetach(Node*);
+ void observedSubtreeNodeWillDetach(Node&);
void clearTransientRegistrations();
bool hasTransientRegistrations() const { return m_transientRegistrationNodes && !m_transientRegistrationNodes->isEmpty(); }
void unregister();
- bool shouldReceiveMutationFrom(Node*, MutationObserver::MutationType, const QualifiedName* attributeName) const;
+ bool shouldReceiveMutationFrom(Node&, MutationObserver::MutationType, const QualifiedName* attributeName) const;
bool isSubtree() const { return m_options & MutationObserver::Subtree; }
- MutationObserver* observer() const { return m_observer.get(); }
+ MutationObserver& observer() const { return *m_observer; }
MutationRecordDeliveryOptions deliveryOptions() const { return m_options & (MutationObserver::AttributeOldValue | MutationObserver::CharacterDataOldValue); }
MutationObserverOptions mutationTypes() const { return m_options & MutationObserver::AllMutationTypes; }
void addRegistrationNodesToSet(HashSet<Node*>&) const;
+ void trace(Visitor*);
+
+ void dispose();
+
private:
- MutationObserverRegistration(PassRefPtr<MutationObserver>, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ MutationObserverRegistration(MutationObserver&, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
- RefPtr<MutationObserver> m_observer;
- Node* m_registrationNode;
- RefPtr<Node> m_registrationNodeKeepAlive;
- typedef HashSet<RefPtr<Node> > NodeHashSet;
- OwnPtr<NodeHashSet> m_transientRegistrationNodes;
+ RefPtrWillBeMember<MutationObserver> m_observer;
+ RawPtrWillBeWeakMember<Node> m_registrationNode;
+ RefPtrWillBeMember<Node> m_registrationNodeKeepAlive;
+ typedef WillBeHeapHashSet<RefPtrWillBeMember<Node> > NodeHashSet;
+ OwnPtrWillBeMember<NodeHashSet> m_transientRegistrationNodes;
MutationObserverOptions m_options;
HashSet<AtomicString> m_attributeFilter;
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp
index 77c6f393073..4d81e614d67 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp
@@ -44,7 +44,7 @@ namespace {
class ChildListRecord : public MutationRecord {
public:
- ChildListRecord(PassRefPtr<Node> target, PassRefPtr<NodeList> added, PassRefPtr<NodeList> removed, PassRefPtr<Node> previousSibling, PassRefPtr<Node> nextSibling)
+ ChildListRecord(PassRefPtrWillBeRawPtr<Node> target, PassRefPtrWillBeRawPtr<StaticNodeList> added, PassRefPtrWillBeRawPtr<StaticNodeList> removed, PassRefPtrWillBeRawPtr<Node> previousSibling, PassRefPtrWillBeRawPtr<Node> nextSibling)
: m_target(target)
, m_addedNodes(added)
, m_removedNodes(removed)
@@ -53,51 +53,69 @@ public:
{
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_target);
+ visitor->trace(m_addedNodes);
+ visitor->trace(m_removedNodes);
+ visitor->trace(m_previousSibling);
+ visitor->trace(m_nextSibling);
+ MutationRecord::trace(visitor);
+ }
+
private:
virtual const AtomicString& type() OVERRIDE;
virtual Node* target() OVERRIDE { return m_target.get(); }
- virtual NodeList* addedNodes() OVERRIDE { return m_addedNodes.get(); }
- virtual NodeList* removedNodes() OVERRIDE { return m_removedNodes.get(); }
+ virtual StaticNodeList* addedNodes() OVERRIDE { return m_addedNodes.get(); }
+ virtual StaticNodeList* removedNodes() OVERRIDE { return m_removedNodes.get(); }
virtual Node* previousSibling() OVERRIDE { return m_previousSibling.get(); }
virtual Node* nextSibling() OVERRIDE { return m_nextSibling.get(); }
- RefPtr<Node> m_target;
- RefPtr<NodeList> m_addedNodes;
- RefPtr<NodeList> m_removedNodes;
- RefPtr<Node> m_previousSibling;
- RefPtr<Node> m_nextSibling;
+ RefPtrWillBeMember<Node> m_target;
+ RefPtrWillBeMember<StaticNodeList> m_addedNodes;
+ RefPtrWillBeMember<StaticNodeList> m_removedNodes;
+ RefPtrWillBeMember<Node> m_previousSibling;
+ RefPtrWillBeMember<Node> m_nextSibling;
};
class RecordWithEmptyNodeLists : public MutationRecord {
public:
- RecordWithEmptyNodeLists(PassRefPtr<Node> target, const String& oldValue)
+ RecordWithEmptyNodeLists(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue)
: m_target(target)
, m_oldValue(oldValue)
{
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_target);
+ visitor->trace(m_addedNodes);
+ visitor->trace(m_removedNodes);
+ MutationRecord::trace(visitor);
+ }
+
private:
virtual Node* target() OVERRIDE { return m_target.get(); }
virtual String oldValue() OVERRIDE { return m_oldValue; }
- virtual NodeList* addedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_addedNodes); }
- virtual NodeList* removedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_removedNodes); }
+ virtual StaticNodeList* addedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_addedNodes); }
+ virtual StaticNodeList* removedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_removedNodes); }
- static NodeList* lazilyInitializeEmptyNodeList(RefPtr<NodeList>& nodeList)
+ static StaticNodeList* lazilyInitializeEmptyNodeList(RefPtrWillBeMember<StaticNodeList>& nodeList)
{
if (!nodeList)
nodeList = StaticNodeList::createEmpty();
return nodeList.get();
}
- RefPtr<Node> m_target;
+ RefPtrWillBeMember<Node> m_target;
String m_oldValue;
- RefPtr<NodeList> m_addedNodes;
- RefPtr<NodeList> m_removedNodes;
+ RefPtrWillBeMember<StaticNodeList> m_addedNodes;
+ RefPtrWillBeMember<StaticNodeList> m_removedNodes;
};
class AttributesRecord : public RecordWithEmptyNodeLists {
public:
- AttributesRecord(PassRefPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
+ AttributesRecord(PassRefPtrWillBeRawPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
: RecordWithEmptyNodeLists(target, oldValue)
, m_attributeName(name.localName())
, m_attributeNamespace(name.namespaceURI())
@@ -115,7 +133,7 @@ private:
class CharacterDataRecord : public RecordWithEmptyNodeLists {
public:
- CharacterDataRecord(PassRefPtr<Node> target, const String& oldValue)
+ CharacterDataRecord(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue)
: RecordWithEmptyNodeLists(target, oldValue)
{
}
@@ -126,16 +144,22 @@ private:
class MutationRecordWithNullOldValue : public MutationRecord {
public:
- MutationRecordWithNullOldValue(PassRefPtr<MutationRecord> record)
+ MutationRecordWithNullOldValue(PassRefPtrWillBeRawPtr<MutationRecord> record)
: m_record(record)
{
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_record);
+ MutationRecord::trace(visitor);
+ }
+
private:
virtual const AtomicString& type() OVERRIDE { return m_record->type(); }
virtual Node* target() OVERRIDE { return m_record->target(); }
- virtual NodeList* addedNodes() OVERRIDE { return m_record->addedNodes(); }
- virtual NodeList* removedNodes() OVERRIDE { return m_record->removedNodes(); }
+ virtual StaticNodeList* addedNodes() OVERRIDE { return m_record->addedNodes(); }
+ virtual StaticNodeList* removedNodes() OVERRIDE { return m_record->removedNodes(); }
virtual Node* previousSibling() OVERRIDE { return m_record->previousSibling(); }
virtual Node* nextSibling() OVERRIDE { return m_record->nextSibling(); }
virtual const AtomicString& attributeName() OVERRIDE { return m_record->attributeName(); }
@@ -143,7 +167,7 @@ private:
virtual String oldValue() OVERRIDE { return String(); }
- RefPtr<MutationRecord> m_record;
+ RefPtrWillBeMember<MutationRecord> m_record;
};
const AtomicString& ChildListRecord::type()
@@ -166,24 +190,24 @@ const AtomicString& CharacterDataRecord::type()
} // namespace
-PassRefPtr<MutationRecord> MutationRecord::createChildList(PassRefPtr<Node> target, PassRefPtr<NodeList> added, PassRefPtr<NodeList> removed, PassRefPtr<Node> previousSibling, PassRefPtr<Node> nextSibling)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createChildList(PassRefPtrWillBeRawPtr<Node> target, PassRefPtrWillBeRawPtr<StaticNodeList> added, PassRefPtrWillBeRawPtr<StaticNodeList> removed, PassRefPtrWillBeRawPtr<Node> previousSibling, PassRefPtrWillBeRawPtr<Node> nextSibling)
{
- return adoptRef(new ChildListRecord(target, added, removed, previousSibling, nextSibling));
+ return adoptRefWillBeNoop(new ChildListRecord(target, added, removed, previousSibling, nextSibling));
}
-PassRefPtr<MutationRecord> MutationRecord::createAttributes(PassRefPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createAttributes(PassRefPtrWillBeRawPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
{
- return adoptRef(new AttributesRecord(target, name, oldValue));
+ return adoptRefWillBeNoop(new AttributesRecord(target, name, oldValue));
}
-PassRefPtr<MutationRecord> MutationRecord::createCharacterData(PassRefPtr<Node> target, const String& oldValue)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createCharacterData(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue)
{
- return adoptRef(new CharacterDataRecord(target, oldValue));
+ return adoptRefWillBeNoop(new CharacterDataRecord(target, oldValue));
}
-PassRefPtr<MutationRecord> MutationRecord::createWithNullOldValue(PassRefPtr<MutationRecord> record)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createWithNullOldValue(PassRefPtrWillBeRawPtr<MutationRecord> record)
{
- return adoptRef(new MutationRecordWithNullOldValue(record));
+ return adoptRefWillBeNoop(new MutationRecordWithNullOldValue(record));
}
MutationRecord::~MutationRecord()
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h
index 2c9812e0e05..de7cb5b3fcc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h
@@ -32,6 +32,7 @@
#define MutationRecord_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -39,15 +40,15 @@
namespace WebCore {
class Node;
-class NodeList;
class QualifiedName;
+class StaticNodeList;
-class MutationRecord : public RefCounted<MutationRecord>, public ScriptWrappable {
+class MutationRecord : public RefCountedWillBeGarbageCollectedFinalized<MutationRecord>, public ScriptWrappable {
public:
- static PassRefPtr<MutationRecord> createChildList(PassRefPtr<Node> target, PassRefPtr<NodeList> added, PassRefPtr<NodeList> removed, PassRefPtr<Node> previousSibling, PassRefPtr<Node> nextSibling);
- static PassRefPtr<MutationRecord> createAttributes(PassRefPtr<Node> target, const QualifiedName&, const AtomicString& oldValue);
- static PassRefPtr<MutationRecord> createCharacterData(PassRefPtr<Node> target, const String& oldValue);
- static PassRefPtr<MutationRecord> createWithNullOldValue(PassRefPtr<MutationRecord>);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createChildList(PassRefPtrWillBeRawPtr<Node> target, PassRefPtrWillBeRawPtr<StaticNodeList> added, PassRefPtrWillBeRawPtr<StaticNodeList> removed, PassRefPtrWillBeRawPtr<Node> previousSibling, PassRefPtrWillBeRawPtr<Node> nextSibling);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createAttributes(PassRefPtrWillBeRawPtr<Node> target, const QualifiedName&, const AtomicString& oldValue);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createCharacterData(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createWithNullOldValue(PassRefPtrWillBeRawPtr<MutationRecord>);
MutationRecord()
{
@@ -59,8 +60,8 @@ public:
virtual const AtomicString& type() = 0;
virtual Node* target() = 0;
- virtual NodeList* addedNodes() = 0;
- virtual NodeList* removedNodes() = 0;
+ virtual StaticNodeList* addedNodes() = 0;
+ virtual StaticNodeList* removedNodes() = 0;
virtual Node* previousSibling() { return 0; }
virtual Node* nextSibling() { return 0; }
@@ -68,6 +69,9 @@ public:
virtual const AtomicString& attributeNamespace() { return nullAtom; }
virtual String oldValue() { return String(); }
+
+ virtual void trace(Visitor*) { }
+
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl
index c3ef6164eb8..daecf1d0c37 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl
@@ -29,6 +29,7 @@
*/
[
+ WillBeGarbageCollected,
] interface MutationRecord {
readonly attribute DOMString type;
readonly attribute Node target;
diff --git a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp
index 69634c9f48a..cd844cac8fe 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp
@@ -31,7 +31,7 @@ namespace WebCore {
using namespace HTMLNames;
-NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name)
+NameNodeList::NameNodeList(ContainerNode& rootNode, const AtomicString& name)
: LiveNodeList(rootNode, NameNodeListType, InvalidateOnNameAttrChange)
, m_name(name)
{
@@ -39,12 +39,14 @@ NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name)
NameNodeList::~NameNodeList()
{
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, NameNodeListType, m_name);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, NameNodeListType, m_name);
+#endif
}
-bool NameNodeList::nodeMatches(Element* testNode) const
+bool NameNodeList::elementMatches(const Element& element) const
{
- return testNode->getNameAttribute() == m_name;
+ return element.getNameAttribute() == m_name;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h
index 5a595d8d9a3..55f313c5904 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h
@@ -26,25 +26,24 @@
#include "core/dom/LiveNodeList.h"
#include "wtf/Forward.h"
-#include "wtf/text/AtomicString.h"
namespace WebCore {
// NodeList which lists all Nodes in a Element with a given "name" attribute
class NameNodeList FINAL : public LiveNodeList {
public:
- static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& name)
+ static PassRefPtrWillBeRawPtr<NameNodeList> create(ContainerNode& rootNode, CollectionType type, const AtomicString& name)
{
ASSERT_UNUSED(type, type == NameNodeListType);
- return adoptRef(new NameNodeList(rootNode, name));
+ return adoptRefWillBeNoop(new NameNodeList(rootNode, name));
}
virtual ~NameNodeList();
private:
- NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name);
+ NameNodeList(ContainerNode& rootNode, const AtomicString& name);
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ virtual bool elementMatches(const Element&) const OVERRIDE;
AtomicString m_name;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp
deleted file mode 100644
index 04f1c08d1f7..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/NamedFlow.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/NamedFlowCollection.h"
-#include "core/dom/StaticNodeList.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/UIEvent.h"
-#include "core/rendering/RenderNamedFlowFragment.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-
-namespace WebCore {
-
-NamedFlow::NamedFlow(PassRefPtr<NamedFlowCollection> manager, const AtomicString& flowThreadName)
- : m_flowThreadName(flowThreadName)
- , m_flowManager(manager)
- , m_parentFlowThread(0)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- ScriptWrappable::init(this);
-}
-
-NamedFlow::~NamedFlow()
-{
- // The named flow is not "strong" referenced from anywhere at this time so it shouldn't be reused if the named flow is recreated.
- m_flowManager->discardNamedFlow(this);
-}
-
-PassRefPtr<NamedFlow> NamedFlow::create(PassRefPtr<NamedFlowCollection> manager, const AtomicString& flowThreadName)
-{
- return adoptRef(new NamedFlow(manager, flowThreadName));
-}
-
-const AtomicString& NamedFlow::name() const
-{
- return m_flowThreadName;
-}
-
-bool NamedFlow::overset() const
-{
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- return m_parentFlowThread ? m_parentFlowThread->overset() : true;
-}
-
-static inline bool inFlowThread(RenderObject* renderer, RenderNamedFlowThread* flowThread)
-{
- if (!renderer)
- return false;
- RenderFlowThread* currentFlowThread = renderer->flowThreadContainingBlock();
- if (flowThread == currentFlowThread)
- return true;
- if (renderer->flowThreadState() != RenderObject::InsideInFlowThread)
- return false;
-
- // An in-flow flow thread can be nested inside an out-of-flow one, so we have to recur up to check.
- return inFlowThread(currentFlowThread->containingBlock(), flowThread);
-}
-
-int NamedFlow::firstEmptyRegionIndex() const
-{
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- if (!m_parentFlowThread)
- return -1;
-
- const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
- if (regionList.isEmpty())
- return -1;
-
- int countNonPseudoRegions = -1;
- RenderRegionList::const_iterator iter = regionList.begin();
- for (int index = 0; iter != regionList.end(); ++index, ++iter) {
- const RenderNamedFlowFragment* renderRegion = toRenderNamedFlowFragment(*iter);
- // FIXME: Pseudo-elements are not included in the list.
- // They will be included when we will properly support the Region interface
- // http://dev.w3.org/csswg/css-regions/#the-region-interface
- if (!renderRegion->isElementBasedRegion())
- continue;
- countNonPseudoRegions++;
- if (renderRegion->regionOversetState() == RegionEmpty)
- return countNonPseudoRegions;
- }
- return -1;
-}
-
-PassRefPtr<NodeList> NamedFlow::getRegionsByContent(Node* contentNode)
-{
- Vector<RefPtr<Node> > regionNodes;
-
- if (!contentNode)
- return StaticNodeList::adopt(regionNodes);
-
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- if (!m_parentFlowThread)
- return StaticNodeList::adopt(regionNodes);
-
- if (inFlowThread(contentNode->renderer(), m_parentFlowThread)) {
- const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
- for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) {
- const RenderNamedFlowFragment* renderRegion = toRenderNamedFlowFragment(*iter);
- // They will be included when we will properly support the Region interface
- // http://dev.w3.org/csswg/css-regions/#the-region-interface
- if (!renderRegion->isElementBasedRegion())
- continue;
- if (m_parentFlowThread->objectInFlowRegion(contentNode->renderer(), renderRegion))
- regionNodes.append(renderRegion->nodeForRegion());
- }
- }
-
- return StaticNodeList::adopt(regionNodes);
-}
-
-PassRefPtr<NodeList> NamedFlow::getRegions()
-{
- Vector<RefPtr<Node> > regionNodes;
-
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- if (!m_parentFlowThread)
- return StaticNodeList::adopt(regionNodes);
-
- const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
- for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) {
- const RenderNamedFlowFragment* renderRegion = toRenderNamedFlowFragment(*iter);
- // They will be included when we will properly support the Region interface
- // http://dev.w3.org/csswg/css-regions/#the-region-interface
- if (!renderRegion->isElementBasedRegion())
- continue;
- regionNodes.append(renderRegion->nodeForRegion());
- }
-
- return StaticNodeList::adopt(regionNodes);
-}
-
-PassRefPtr<NodeList> NamedFlow::getContent()
-{
- Vector<RefPtr<Node> > contentNodes;
-
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- if (!m_parentFlowThread)
- return StaticNodeList::adopt(contentNodes);
-
- const NamedFlowContentNodes& contentNodesList = m_parentFlowThread->contentNodes();
- for (NamedFlowContentNodes::const_iterator it = contentNodesList.begin(); it != contentNodesList.end(); ++it) {
- Node* node = *it;
- ASSERT(node->computedStyle()->flowThread() == m_parentFlowThread->flowThreadName());
- contentNodes.append(node);
- }
-
- return StaticNodeList::adopt(contentNodes);
-}
-
-void NamedFlow::setRenderer(RenderNamedFlowThread* parentFlowThread)
-{
- // The named flow can either go from a no_renderer->renderer or renderer->no_renderer state; anything else could indicate a bug.
- ASSERT((!m_parentFlowThread && parentFlowThread) || (m_parentFlowThread && !parentFlowThread));
-
- // If parentFlowThread is 0, the flow thread will move in the "NULL" state.
- m_parentFlowThread = parentFlowThread;
-}
-
-void NamedFlow::dispatchRegionLayoutUpdateEvent()
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- // If the flow is in the "NULL" state the event should not be dispatched any more.
- if (flowState() == FlowStateNull)
- return;
-
- RefPtr<Event> event = UIEvent::create(EventTypeNames::webkitregionlayoutupdate, false, false, m_flowManager->document()->domWindow(), 0);
-
- dispatchEvent(event);
-}
-
-void NamedFlow::dispatchRegionOversetChangeEvent()
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- // If the flow is in the "NULL" state the event should not be dispatched any more.
- if (flowState() == FlowStateNull)
- return;
-
- RefPtr<Event> event = UIEvent::create(EventTypeNames::webkitregionoversetchange, false, false, m_flowManager->document()->domWindow(), 0);
-
- dispatchEvent(event);
-}
-
-const AtomicString& NamedFlow::interfaceName() const
-{
- return EventTargetNames::NamedFlow;
-}
-
-ExecutionContext* NamedFlow::executionContext() const
-{
- return m_flowManager->document();
-}
-
-Node* NamedFlow::ownerNode() const
-{
- return m_flowManager->document();
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.h b/chromium/third_party/WebKit/Source/core/dom/NamedFlow.h
deleted file mode 100644
index 75f2bd5765a..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef NamedFlow_h
-#define NamedFlow_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/events/EventTarget.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-class Document;
-class NamedFlowCollection;
-class Node;
-class NodeList;
-class RenderNamedFlowThread;
-class ExecutionContext;
-
-class NamedFlow : public RefCounted<NamedFlow>, public ScriptWrappable, public EventTargetWithInlineData {
- REFCOUNTED_EVENT_TARGET(NamedFlow);
-public:
- static PassRefPtr<NamedFlow> create(PassRefPtr<NamedFlowCollection> manager, const AtomicString& flowThreadName);
-
- ~NamedFlow();
-
- const AtomicString& name() const;
- bool overset() const;
- int firstEmptyRegionIndex() const;
- PassRefPtr<NodeList> getRegionsByContent(Node*);
- PassRefPtr<NodeList> getRegions();
- PassRefPtr<NodeList> getContent();
-
- virtual const AtomicString& interfaceName() const OVERRIDE;
- virtual ExecutionContext* executionContext() const OVERRIDE;
-
- // This function is called from the JS binding code to determine if the NamedFlow object is reachable or not.
- // If the object has listeners, the object should only be discarded if the parent Document is not reachable.
- Node* ownerNode() const;
-
- void setRenderer(RenderNamedFlowThread* parentFlowThread);
-
- enum FlowState {
- FlowStateCreated,
- FlowStateNull
- };
-
- FlowState flowState() const { return m_parentFlowThread ? FlowStateCreated : FlowStateNull; }
-
- void dispatchRegionLayoutUpdateEvent();
- void dispatchRegionOversetChangeEvent();
-
-private:
- NamedFlow(PassRefPtr<NamedFlowCollection>, const AtomicString&);
-
- // The name of the flow thread as specified in CSS.
- AtomicString m_flowThreadName;
-
- RefPtr<NamedFlowCollection> m_flowManager;
- RenderNamedFlowThread* m_parentFlowThread;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp
deleted file mode 100644
index 2b48c7be3d1..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/NamedFlowCollection.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/DOMNamedFlowCollection.h"
-#include "core/dom/Document.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-NamedFlowCollection::NamedFlowCollection(Document* document)
- : DocumentLifecycleObserver(document)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
-}
-
-Vector<RefPtr<NamedFlow> > NamedFlowCollection::namedFlows()
-{
- Vector<RefPtr<NamedFlow> > namedFlows;
-
- for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it) {
- if ((*it)->flowState() == NamedFlow::FlowStateNull)
- continue;
-
- namedFlows.append(RefPtr<NamedFlow>(*it));
- }
-
- return namedFlows;
-}
-
-NamedFlow* NamedFlowCollection::flowByName(const String& flowName)
-{
- NamedFlowSet::iterator it = m_namedFlows.find<NamedFlowHashTranslator>(flowName);
- if (it == m_namedFlows.end() || (*it)->flowState() == NamedFlow::FlowStateNull)
- return 0;
-
- return *it;
-}
-
-PassRefPtr<NamedFlow> NamedFlowCollection::ensureFlowWithName(const String& flowName)
-{
- NamedFlowSet::iterator it = m_namedFlows.find<NamedFlowHashTranslator>(flowName);
- if (it != m_namedFlows.end()) {
- NamedFlow* namedFlow = *it;
- ASSERT(namedFlow->flowState() == NamedFlow::FlowStateNull);
-
- return namedFlow;
- }
-
- RefPtr<NamedFlow> newFlow = NamedFlow::create(this, flowName);
- m_namedFlows.add(newFlow.get());
-
- InspectorInstrumentation::didCreateNamedFlow(document(), newFlow.get());
-
- return newFlow.release();
-}
-
-void NamedFlowCollection::discardNamedFlow(NamedFlow* namedFlow)
-{
- // The document is not valid anymore so the collection will be destroyed anyway.
- if (!document())
- return;
-
- ASSERT(namedFlow->flowState() == NamedFlow::FlowStateNull);
- ASSERT(m_namedFlows.contains(namedFlow));
-
- InspectorInstrumentation::willRemoveNamedFlow(document(), namedFlow);
-
- m_namedFlows.remove(namedFlow);
-}
-
-Document* NamedFlowCollection::document() const
-{
- return lifecycleContext();
-}
-
-PassRefPtr<DOMNamedFlowCollection> NamedFlowCollection::createCSSOMSnapshot()
-{
- Vector<NamedFlow*> createdFlows;
- for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it)
- if ((*it)->flowState() == NamedFlow::FlowStateCreated)
- createdFlows.append(*it);
- return DOMNamedFlowCollection::create(createdFlows);
-}
-
-// The HashFunctions object used by the HashSet to compare between NamedFlows.
-// It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values.
-struct NamedFlowCollection::NamedFlowHashFunctions {
- static unsigned hash(NamedFlow* key) { return DefaultHash<String>::Hash::hash(key->name()); }
- static bool equal(NamedFlow* a, NamedFlow* b) { return a->name() == b->name(); }
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-// The HashTranslator is used to lookup a NamedFlow in the set using a name.
-struct NamedFlowCollection::NamedFlowHashTranslator {
- static unsigned hash(const String& key) { return DefaultHash<String>::Hash::hash(key); }
- static bool equal(NamedFlow* a, const String& b) { return a->name() == b; }
-};
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h b/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h
deleted file mode 100644
index f9c4b9cb446..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef NamedFlowCollection_h
-#define NamedFlowCollection_h
-
-#include "core/dom/DocumentLifecycleObserver.h"
-#include "core/dom/NamedFlow.h"
-#include "wtf/Forward.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Document;
-class DOMNamedFlowCollection;
-
-class NamedFlowCollection : public RefCounted<NamedFlowCollection>, public DocumentLifecycleObserver {
-public:
- static PassRefPtr<NamedFlowCollection> create(Document* doc) { return adoptRef(new NamedFlowCollection(doc)); }
-
- Vector<RefPtr<NamedFlow> > namedFlows();
- NamedFlow* flowByName(const String&);
- PassRefPtr<NamedFlow> ensureFlowWithName(const String&);
-
- void discardNamedFlow(NamedFlow*);
-
- Document* document() const;
-
- virtual ~NamedFlowCollection() { }
-
- PassRefPtr<DOMNamedFlowCollection> createCSSOMSnapshot();
-
-private:
- struct NamedFlowHashFunctions;
- struct NamedFlowHashTranslator;
-
- typedef ListHashSet<NamedFlow*, 1, NamedFlowHashFunctions> NamedFlowSet;
-
- explicit NamedFlowCollection(Document*);
-
- NamedFlowSet m_namedFlows;
-};
-
-} // namespace WebCore
-
-#endif // NamedFlowCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp
index 2265972d656..09808b8895f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp
@@ -35,6 +35,7 @@ namespace WebCore {
using namespace HTMLNames;
+#if !ENABLE(OILPAN)
void NamedNodeMap::ref()
{
m_element->ref();
@@ -44,63 +45,64 @@ void NamedNodeMap::deref()
{
m_element->deref();
}
+#endif
-PassRefPtr<Node> NamedNodeMap::getNamedItem(const AtomicString& name) const
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::getNamedItem(const AtomicString& name) const
{
return m_element->getAttributeNode(name);
}
-PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
return m_element->getAttributeNodeNS(namespaceURI, localName);
}
-PassRefPtr<Node> NamedNodeMap::removeNamedItem(const AtomicString& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::removeNamedItem(const AtomicString& name, ExceptionState& exceptionState)
{
- size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(name, m_element->shouldIgnoreAttributeCase()) : kNotFound;
+ size_t index = m_element->hasAttributes() ? m_element->findAttributeIndexByName(name, m_element->shouldIgnoreAttributeCase()) : kNotFound;
if (index == kNotFound) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "No item with name '" + name + "' was found.");
+ return nullptr;
}
return m_element->detachAttribute(index);
}
-PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState& exceptionState)
{
- size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI)) : kNotFound;
+ size_t index = m_element->hasAttributes() ? m_element->findAttributeIndexByName(QualifiedName(nullAtom, localName, namespaceURI)) : kNotFound;
if (index == kNotFound) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "No item with name '" + namespaceURI + "::" + localName + "' was found.");
+ return nullptr;
}
return m_element->detachAttribute(index);
}
-PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
+ return nullptr;
}
// Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node
if (!node->isAttributeNode()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is not an attribute node.");
+ return nullptr;
}
return m_element->setAttributeNode(toAttr(node), exceptionState);
}
-PassRefPtr<Node> NamedNodeMap::setNamedItemNS(Node* node, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::setNamedItemNS(Node* node, ExceptionState& exceptionState)
{
return setNamedItem(node, exceptionState);
}
-PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::item(unsigned index) const
{
if (index >= length())
- return 0;
- return m_element->ensureAttr(m_element->attributeItem(index)->name());
+ return nullptr;
+ return m_element->ensureAttr(m_element->attributeAt(index).name());
}
size_t NamedNodeMap::length() const
@@ -110,4 +112,9 @@ size_t NamedNodeMap::length() const
return m_element->attributeCount();
}
+void NamedNodeMap::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h
index f01102c9957..b1e569323e5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h
@@ -26,6 +26,7 @@
#define NamedNodeMap_h
#include "bindings/v8/ScriptWrappable.h"
+#include "core/dom/Element.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/AtomicString.h"
@@ -33,47 +34,50 @@
namespace WebCore {
class Node;
-class Element;
class ExceptionState;
-class NamedNodeMap : public ScriptWrappable {
- WTF_MAKE_FAST_ALLOCATED;
+class NamedNodeMap FINAL : public NoBaseWillBeGarbageCollectedFinalized<NamedNodeMap>, public ScriptWrappable {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
friend class Element;
public:
- static PassOwnPtr<NamedNodeMap> create(Element* element)
+ static PassOwnPtrWillBeRawPtr<NamedNodeMap> create(Element* element)
{
- return adoptPtr(new NamedNodeMap(element));
+ return adoptPtrWillBeNoop(new NamedNodeMap(element));
}
+#if !ENABLE(OILPAN)
void ref();
void deref();
+#endif
// Public DOM interface.
- PassRefPtr<Node> getNamedItem(const AtomicString&) const;
- PassRefPtr<Node> removeNamedItem(const AtomicString& name, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> getNamedItem(const AtomicString&) const;
+ PassRefPtrWillBeRawPtr<Node> removeNamedItem(const AtomicString& name, ExceptionState&);
- PassRefPtr<Node> getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
- PassRefPtr<Node> removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
+ PassRefPtrWillBeRawPtr<Node> removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState&);
- PassRefPtr<Node> setNamedItem(Node*, ExceptionState&);
- PassRefPtr<Node> setNamedItemNS(Node*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> setNamedItem(Node*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> setNamedItemNS(Node*, ExceptionState&);
- PassRefPtr<Node> item(unsigned index) const;
+ PassRefPtrWillBeRawPtr<Node> item(unsigned index) const;
size_t length() const;
Element* element() const { return m_element; }
+ void trace(Visitor*);
+
private:
explicit NamedNodeMap(Element* element)
: m_element(element)
{
- // Only supports NamedNodeMaps with Element associated, DocumentType.entities and DocumentType.notations are not supported yet.
+ // Only supports NamedNodeMaps with Element associated.
ASSERT(m_element);
ScriptWrappable::init(this);
}
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl
index 0f51574fdd1..7de6a6f8454 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl
@@ -19,31 +19,31 @@
*/
[
- GenerateVisitDOMWrapper=element,
+ SetWrapperReferenceFrom=element,
+ WillBeGarbageCollected,
] interface NamedNodeMap {
- Node getNamedItem([Default=Undefined] optional DOMString name);
+ [MeasureAs=NamedNodeMapGetNamedItem] Node getNamedItem([Default=Undefined] optional DOMString name);
[NotEnumerable, ImplementedAs=getNamedItem] getter Node ([Default=Undefined] optional DOMString name);
- [RaisesException, CustomElementCallbacks] Node setNamedItem([Default=Undefined] optional Node node);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapSetNamedItem] Node setNamedItem([Default=Undefined] optional Node node);
- [RaisesException, CustomElementCallbacks] Node removeNamedItem([Default=Undefined] optional DOMString name);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapRemoveNamedItem] Node removeNamedItem([Default=Undefined] optional DOMString name);
- getter Node item([Default=Undefined] optional unsigned long index);
+ [MeasureAs=NamedNodeMapItem] getter Node item([Default=Undefined] optional unsigned long index);
readonly attribute unsigned long length;
// Introduced in DOM Level 2:
- // FIXME: the implementation does take an exceptioncode parameter.
- /*[RaisesException]*/ Node getNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
- [Default=Undefined] optional DOMString localName);
+ [MeasureAs=NamedNodeMapGetNamedItemNS] Node getNamedItemNS([TreatNullAs=NullString, Default=Undefined] optional DOMString namespaceURI,
+ [Default=Undefined] optional DOMString localName);
- [RaisesException, CustomElementCallbacks] Node setNamedItemNS([Default=Undefined] optional Node node);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapSetNamedItemNS] Node setNamedItemNS([Default=Undefined] optional Node node);
- [RaisesException, CustomElementCallbacks] Node removeNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
- [Default=Undefined] optional DOMString localName);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapRemoveNamedItemNS] Node removeNamedItemNS([TreatNullAs=NullString, Default=Undefined] optional DOMString namespaceURI,
+ [Default=Undefined] optional DOMString localName);
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp
index fb6b772693b..85727582353 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp
@@ -34,21 +34,17 @@
namespace WebCore {
-Node* NamedNodesCollection::item(unsigned index) const
+Element* NamedNodesCollection::item(unsigned index) const
{
if (index < m_nodes.size())
return m_nodes[index].get();
return 0;
}
-Node* NamedNodesCollection::namedItem(const AtomicString& id) const
+void NamedNodesCollection::trace(Visitor* visitor)
{
- for (unsigned i = 0; i < m_nodes.size(); ++i) {
- Node* node = m_nodes[i].get();
- if (node->hasID() && toElement(node)->getIdAttribute() == id)
- return node;
- }
- return 0;
+ visitor->trace(m_nodes);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h
index b202bcf238f..d30a2ad05b6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h
@@ -31,7 +31,7 @@
#ifndef NamedNodesCollection_h
#define NamedNodesCollection_h
-#include "core/dom/Node.h"
+#include "core/dom/Element.h"
#include "core/dom/NodeList.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -41,20 +41,21 @@ namespace WebCore {
class NamedNodesCollection FINAL : public NodeList {
public:
- static PassRefPtr<NodeList> create(const Vector<RefPtr<Node> >& nodes)
+ static PassRefPtrWillBeRawPtr<NodeList> create(const WillBeHeapVector<RefPtrWillBeMember<Element> >& nodes)
{
- return adoptRef(new NamedNodesCollection(nodes));
+ return adoptRefWillBeNoop(new NamedNodesCollection(nodes));
}
virtual unsigned length() const OVERRIDE { return m_nodes.size(); }
- virtual Node* item(unsigned) const OVERRIDE;
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
+ virtual Element* item(unsigned) const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- explicit NamedNodesCollection(const Vector<RefPtr<Node> >& nodes)
+ explicit NamedNodesCollection(const WillBeHeapVector<RefPtrWillBeMember<Element> > nodes)
: m_nodes(nodes) { }
- Vector<RefPtr<Node> > m_nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > m_nodes;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h b/chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h
new file mode 100644
index 00000000000..a495212c275
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h
@@ -0,0 +1,76 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NoEventDispatchAssertion_h
+#define NoEventDispatchAssertion_h
+
+#include "wtf/MainThread.h"
+#include "wtf/TemporaryChange.h"
+
+namespace WebCore {
+
+#ifndef NDEBUG
+
+class NoEventDispatchAssertion {
+public:
+ NoEventDispatchAssertion()
+ {
+ if (!isMainThread())
+ return;
+ ++s_count;
+ }
+
+ ~NoEventDispatchAssertion()
+ {
+ if (!isMainThread())
+ return;
+ ASSERT(s_count);
+ --s_count;
+ }
+
+ static bool isEventDispatchForbidden()
+ {
+ if (!isMainThread())
+ return false;
+ return s_count;
+ }
+
+ // It's safe to dispatch events in SVGImage since there can't be any script
+ // listeners.
+ class AllowSVGImageEvents {
+ public:
+ AllowSVGImageEvents()
+ : m_change(s_count, 0)
+ {
+ }
+
+ ~AllowSVGImageEvents()
+ {
+ ASSERT(!s_count);
+ }
+
+ TemporaryChange<unsigned> m_change;
+ };
+
+private:
+ static unsigned s_count;
+};
+
+#else
+
+class NoEventDispatchAssertion {
+public:
+ NoEventDispatchAssertion() { }
+
+ class AllowSVGImageEvents {
+ public:
+ AllowSVGImageEvents() { }
+ };
+};
+
+#endif // NDEBUG
+
+} // namespace WebCore
+
+#endif // NoEventDispatchAssertion_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Node.cpp b/chromium/third_party/WebKit/Source/core/dom/Node.cpp
index abea9efac4e..6dcd3c17be8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Node.cpp
@@ -25,16 +25,15 @@
#include "config.h"
#include "core/dom/Node.h"
-#include "HTMLNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptCallStackFactory.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Attr.h"
#include "core/dom/Attribute.h"
#include "core/dom/ChildListMutationScope.h"
#include "core/dom/ChildNodeList.h"
-#include "core/dom/ClassNodeList.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
@@ -42,25 +41,26 @@
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ElementRareData.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/LiveNodeList.h"
-#include "core/dom/NameNodeList.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeRareData.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/Range.h"
-#include "core/dom/SelectorQuery.h"
-#include "core/dom/TagNodeList.h"
+#include "core/dom/StaticNodeList.h"
#include "core/dom/TemplateContentDocumentFragment.h"
#include "core/dom/Text.h"
#include "core/dom/TreeScopeAdopter.h"
#include "core/dom/UserActionElementSet.h"
-#include "core/dom/WheelController.h"
+#include "core/dom/WeakNodeMap.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/htmlediting.h"
-#include "core/events/BeforeLoadEvent.h"
+#include "core/editing/markup.h"
#include "core/events/Event.h"
#include "core/events/EventDispatchMediator.h"
#include "core/events/EventDispatcher.h"
@@ -70,24 +70,25 @@
#include "core/events/MouseEvent.h"
#include "core/events/MutationEvent.h"
#include "core/events/TextEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/TouchEvent.h"
#include "core/events/UIEvent.h"
#include "core/events/WheelEvent.h"
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/html/RadioNodeList.h"
#include "core/page/ContextMenuController.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/RenderBox.h"
#include "core/svg/graphics/SVGImage.h"
#include "platform/Partitions.h"
+#include "platform/TraceEvent.h"
+#include "platform/TracedValue.h"
#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCountedLeakCounter.h"
@@ -95,12 +96,11 @@
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
+#if !ENABLE(OILPAN)
void* Node::operator new(size_t size)
{
ASSERT(isMainThread());
@@ -112,14 +112,14 @@ void Node::operator delete(void* ptr)
ASSERT(isMainThread());
partitionFree(ptr);
}
+#endif
-bool Node::isSupported(const String& feature, const String& version)
+#if DUMP_NODE_STATISTICS
+static HashSet<Node*>& liveNodeSet()
{
- return DOMImplementation::hasFeature(feature, version);
+ DEFINE_STATIC_LOCAL(HashSet<Node*>, s_liveNodeSet, ());
+ return s_liveNodeSet;
}
-
-#if DUMP_NODE_STATISTICS
-static HashSet<Node*> liveNodeSet;
#endif
void Node::dumpStatistics()
@@ -132,24 +132,20 @@ void Node::dumpStatistics()
size_t textNodes = 0;
size_t cdataNodes = 0;
size_t commentNodes = 0;
- size_t entityNodes = 0;
size_t piNodes = 0;
size_t documentNodes = 0;
size_t docTypeNodes = 0;
size_t fragmentNodes = 0;
- size_t notationNodes = 0;
- size_t xpathNSNodes = 0;
size_t shadowRootNodes = 0;
HashMap<String, size_t> perTagCount;
size_t attributes = 0;
- size_t attributesWithAttr = 0;
size_t elementsWithAttributeStorage = 0;
size_t elementsWithRareData = 0;
size_t elementsWithNamedNodeMap = 0;
- for (HashSet<Node*>::iterator it = liveNodeSet.begin(); it != liveNodeSet.end(); ++it) {
+ for (HashSet<Node*>::iterator it = liveNodeSet().begin(); it != liveNodeSet().end(); ++it) {
Node* node = *it;
if (node->hasRareData()) {
@@ -169,16 +165,11 @@ void Node::dumpStatistics()
Element* element = toElement(node);
HashMap<String, size_t>::AddResult result = perTagCount.add(element->tagName(), 1);
if (!result.isNewEntry)
- result.iterator->value++;
+ result.storedValue->value++;
- if (ElementData* elementData = element->elementData()) {
+ if (const ElementData* elementData = element->elementData()) {
attributes += elementData->length();
++elementsWithAttributeStorage;
- for (unsigned i = 0; i < elementData->length(); ++i) {
- Attribute* attr = elementData->attributeItem(i);
- if (attr->attr())
- ++attributesWithAttr;
- }
}
break;
}
@@ -198,10 +189,6 @@ void Node::dumpStatistics()
++commentNodes;
break;
}
- case ENTITY_NODE: {
- ++entityNodes;
- break;
- }
case PROCESSING_INSTRUCTION_NODE: {
++piNodes;
break;
@@ -221,18 +208,10 @@ void Node::dumpStatistics()
++fragmentNodes;
break;
}
- case NOTATION_NODE: {
- ++notationNodes;
- break;
- }
- case XPATH_NAMESPACE_NODE: {
- ++xpathNSNodes;
- break;
- }
}
}
- printf("Number of Nodes: %d\n\n", liveNodeSet.size());
+ printf("Number of Nodes: %d\n\n", liveNodeSet().size());
printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
printf("NodeType distribution:\n");
@@ -241,13 +220,10 @@ void Node::dumpStatistics()
printf(" Number of Text nodes: %zu\n", textNodes);
printf(" Number of CDATASection nodes: %zu\n", cdataNodes);
printf(" Number of Comment nodes: %zu\n", commentNodes);
- printf(" Number of Entity nodes: %zu\n", entityNodes);
printf(" Number of ProcessingInstruction nodes: %zu\n", piNodes);
printf(" Number of Document nodes: %zu\n", documentNodes);
printf(" Number of DocumentType nodes: %zu\n", docTypeNodes);
printf(" Number of DocumentFragment nodes: %zu\n", fragmentNodes);
- printf(" Number of Notation nodes: %zu\n", notationNodes);
- printf(" Number of XPathNS nodes: %zu\n", xpathNSNodes);
printf(" Number of ShadowRoot nodes: %zu\n", shadowRootNodes);
printf("Element tag name distibution:\n");
@@ -256,7 +232,6 @@ void Node::dumpStatistics()
printf("Attributes:\n");
printf(" Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));
- printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr);
printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData));
printf(" Number of Elements with RareData: %zu\n", elementsWithRareData);
printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap));
@@ -272,8 +247,28 @@ void Node::trackForDebugging()
#endif
#if DUMP_NODE_STATISTICS
- liveNodeSet.add(this);
+ liveNodeSet().add(this);
+#endif
+}
+
+Node::Node(TreeScope* treeScope, ConstructionType type)
+ : m_nodeFlags(type)
+ , m_parentOrShadowHostNode(nullptr)
+ , m_treeScope(treeScope)
+ , m_previous(nullptr)
+ , m_next(nullptr)
+{
+ ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot);
+ ScriptWrappable::init(this);
+#if !ENABLE(OILPAN)
+ if (m_treeScope)
+ m_treeScope->guardRef();
+#endif
+
+#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
+ trackForDebugging();
#endif
+ InspectorCounters::incrementCounter(InspectorCounters::NodeCounter);
}
Node::~Node()
@@ -283,9 +278,10 @@ Node::~Node()
#endif
#if DUMP_NODE_STATISTICS
- liveNodeSet.remove(this);
+ liveNodeSet().remove(this);
#endif
+#if !ENABLE(OILPAN)
if (hasRareData())
clearRareData();
@@ -301,10 +297,20 @@ Node::~Node()
if (m_treeScope)
m_treeScope->guardDeref();
+#else
+ // With Oilpan, the rare data finalizer also asserts for
+ // this condition (we cannot directly access it here.)
+ RELEASE_ASSERT(hasRareData() || !renderer());
+#endif
InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
+
+ if (getFlag(HasWeakReferencesFlag))
+ WeakNodeMap::notifyNodeDestroyed(this);
}
+#if !ENABLE(OILPAN)
+// With Oilpan all of this is handled with weak processing of the document.
void Node::willBeDeletedFromDocument()
{
if (!isTreeScopeInitialized())
@@ -313,15 +319,18 @@ void Node::willBeDeletedFromDocument()
Document& document = this->document();
if (hasEventTargetData()) {
- document.didRemoveEventTargetNode(this);
clearEventTargetData();
+ document.didClearTouchEventHandlers(this);
+ if (document.frameHost())
+ document.frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
}
if (AXObjectCache* cache = document.existingAXObjectCache())
cache->remove(this);
- document.markers()->removeMarkers(this);
+ document.markers().removeMarkers(this);
}
+#endif
NodeRareData* Node::rareData() const
{
@@ -334,18 +343,18 @@ NodeRareData& Node::ensureRareData()
if (hasRareData())
return *rareData();
- NodeRareData* data;
if (isElementNode())
- data = ElementRareData::create(m_data.m_renderer).leakPtr();
+ m_data.m_rareData = ElementRareData::create(m_data.m_renderer);
else
- data = NodeRareData::create(m_data.m_renderer).leakPtr();
- ASSERT(data);
+ m_data.m_rareData = NodeRareData::create(m_data.m_renderer);
+
+ ASSERT(m_data.m_rareData);
- m_data.m_rareData = data;
setFlag(HasRareDataFlag);
- return *data;
+ return *rareData();
}
+#if !ENABLE(OILPAN)
void Node::clearRareData()
{
ASSERT(hasRareData());
@@ -359,6 +368,7 @@ void Node::clearRareData()
m_data.m_renderer = renderer;
clearFlag(HasRareDataFlag);
}
+#endif
Node* Node::toNode()
{
@@ -380,12 +390,14 @@ void Node::setNodeValue(const String&)
// By default, setting nodeValue has no effect.
}
-PassRefPtr<NodeList> Node::childNodes()
+PassRefPtrWillBeRawPtr<NodeList> Node::childNodes()
{
- return ensureRareData().ensureNodeLists().ensureChildNodeList(this);
+ if (isContainerNode())
+ return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this));
+ return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this);
}
-Node& Node::lastDescendant() const
+Node& Node::lastDescendantOrSelf() const
{
Node* n = const_cast<Node*>(this);
while (n && n->lastChild())
@@ -450,7 +462,7 @@ Node* Node::pseudoAwareLastChild() const
return lastChild();
}
-void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
+void Node::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
{
if (isContainerNode())
toContainerNode(this)->insertBefore(newChild, refChild, exceptionState);
@@ -458,7 +470,7 @@ void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionStat
exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
}
-void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
+void Node::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
{
if (isContainerNode())
toContainerNode(this)->replaceChild(newChild, oldChild, exceptionState);
@@ -474,7 +486,7 @@ void Node::removeChild(Node* oldChild, ExceptionState& exceptionState)
exceptionState.throwDOMException(NotFoundError, "This node type does not support this method.");
}
-void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& exceptionState)
+void Node::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& exceptionState)
{
if (isContainerNode())
toContainerNode(this)->appendChild(newChild, exceptionState);
@@ -493,38 +505,23 @@ void Node::normalize()
// Go through the subtree beneath us, normalizing all nodes. This means that
// any two adjacent text nodes are merged and any empty text nodes are removed.
- RefPtr<Node> node = this;
+ RefPtrWillBeRawPtr<Node> node = this;
while (Node* firstChild = node->firstChild())
node = firstChild;
while (node) {
- NodeType type = node->nodeType();
- if (type == ELEMENT_NODE)
+ if (node->isElementNode())
toElement(node)->normalizeAttributes();
if (node == this)
break;
- if (type == TEXT_NODE)
+ if (node->nodeType() == TEXT_NODE)
node = toText(node)->mergeNextSiblingNodesIfPossible();
else
node = NodeTraversal::nextPostOrder(*node);
}
}
-const AtomicString& Node::prefix() const
-{
- // For nodes other than elements and attributes, the prefix is always null
- return nullAtom;
-}
-
-void Node::setPrefix(const AtomicString& /*prefix*/, ExceptionState& exceptionState)
-{
- // The spec says that for nodes other than elements and attributes, prefix is always null.
- // It does not say what to do when the user tries to set the prefix on another type of
- // node, however Mozilla throws a NamespaceError exception.
- exceptionState.throwDOMException(NamespaceError, "Prefixes are only supported on element and attribute nodes.");
-}
-
const AtomicString& Node::localName() const
{
return nullAtom;
@@ -537,13 +534,13 @@ const AtomicString& Node::namespaceURI() const
bool Node::isContentEditable(UserSelectAllTreatment treatment)
{
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
return rendererIsEditable(Editable, treatment);
}
bool Node::isContentRichlyEditable()
{
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
}
@@ -677,47 +674,32 @@ void Node::setIsLink(bool isLink)
setFlag(isLink && !SVGImage::isInSVGImage(toElement(this)), IsLinkFlag);
}
-void Node::markAncestorsWithChildNeedsDistributionRecalc()
+void Node::setNeedsStyleInvalidation()
{
- for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
- node->setChildNeedsDistributionRecalc();
- if (document().childNeedsDistributionRecalc())
- document().scheduleStyleRecalc();
+ setFlag(NeedsStyleInvalidationFlag);
+ markAncestorsWithChildNeedsStyleInvalidation();
}
-namespace {
-
-unsigned styledSubtreeSize(const Node*);
-
-unsigned styledSubtreeSizeIgnoringSelfAndShadowRoots(const Node* rootNode)
+void Node::markAncestorsWithChildNeedsStyleInvalidation()
{
- unsigned nodeCount = 0;
- for (Node* child = rootNode->firstChild(); child; child = child->nextSibling())
- nodeCount += styledSubtreeSize(child);
- return nodeCount;
+ for (Node* node = parentOrShadowHostNode(); node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode())
+ node->setChildNeedsStyleInvalidation();
+ document().scheduleRenderTreeUpdateIfNeeded();
}
-unsigned styledSubtreeSize(const Node* rootNode)
+void Node::markAncestorsWithChildNeedsDistributionRecalc()
{
- if (rootNode->isTextNode())
- return 1;
- if (!rootNode->isElementNode())
- return 0;
-
- // FIXME: We should use a shadow-tree aware node-iterator when such exists.
- unsigned nodeCount = 1 + styledSubtreeSizeIgnoringSelfAndShadowRoots(rootNode);
-
- // ShadowRoots don't have style (so don't count them), but their children might.
- for (ShadowRoot* shadowRoot = rootNode->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
- nodeCount += styledSubtreeSizeIgnoringSelfAndShadowRoots(shadowRoot);
-
- return nodeCount;
+ for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
+ node->setChildNeedsDistributionRecalc();
+ document().scheduleRenderTreeUpdateIfNeeded();
}
+namespace {
+
PassRefPtr<JSONArray> jsStackAsJSONArray()
{
RefPtr<JSONArray> jsonArray = JSONArray::create();
- RefPtr<ScriptCallStack> stack = createScriptCallStack(10);
+ RefPtrWillBeRawPtr<ScriptCallStack> stack = createScriptCallStack(10);
if (!stack)
return jsonArray.release();
for (size_t i = 0; i < stack->size(); i++)
@@ -736,16 +718,30 @@ PassRefPtr<JSONObject> jsonObjectForStyleInvalidation(unsigned nodeCount, const
} // anonymous namespace'd functions supporting traceStyleChange
+unsigned Node::styledSubtreeSize() const
+{
+ unsigned nodeCount = 0;
+
+ for (const Node* node = this; node; node = NodeTraversal::next(*node, this)) {
+ if (node->isTextNode() || node->isElementNode())
+ nodeCount++;
+ for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ nodeCount += root->styledSubtreeSize();
+ }
+
+ return nodeCount;
+}
+
void Node::traceStyleChange(StyleChangeType changeType)
{
static const unsigned kMinLoggedSize = 100;
- unsigned nodeCount = styledSubtreeSize(this);
+ unsigned nodeCount = styledSubtreeSize();
if (nodeCount < kMinLoggedSize)
return;
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("style.debug"),
"Node::setNeedsStyleRecalc",
- "data", jsonObjectForStyleInvalidation(nodeCount, this)->toJSONString().ascii()
+ "data", TracedValue::fromJSONValue(jsonObjectForStyleInvalidation(nodeCount, this))
);
}
@@ -767,20 +763,15 @@ void Node::markAncestorsWithChildNeedsStyleRecalc()
{
for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode())
p->setChildNeedsStyleRecalc();
-
- if (document().needsStyleRecalc() || document().childNeedsStyleRecalc())
- document().scheduleStyleRecalc();
+ document().scheduleRenderTreeUpdateIfNeeded();
}
-void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource source)
+void Node::setNeedsStyleRecalc(StyleChangeType changeType)
{
ASSERT(changeType != NoStyleChange);
if (!inActiveDocument())
return;
- if (source == StyleChangeFromRenderer)
- setFlag(NotifyRendererWithIdenticalStyles);
-
StyleChangeType existingChangeType = styleChangeType();
if (changeType > existingChangeType) {
setStyleChange(changeType);
@@ -798,7 +789,8 @@ void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource sou
void Node::clearNeedsStyleRecalc()
{
m_nodeFlags &= ~StyleChangeMask;
- clearFlag(NotifyRendererWithIdenticalStyles);
+
+ clearSVGFilterNeedsLayerUpdate();
if (isElementNode() && hasRareData())
toElement(*this).setAnimationStyleChange(false);
@@ -823,7 +815,7 @@ bool Node::shouldHaveFocusAppearance() const
bool Node::isInert() const
{
const HTMLDialogElement* dialog = document().activeModalDialog();
- if (dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this))
+ if (dialog && this != document() && !NodeRenderingTraversal::contains(dialog, this))
return true;
return document().ownerElement() && document().ownerElement()->isInert();
}
@@ -837,40 +829,6 @@ unsigned Node::nodeIndex() const
return count;
}
-template<unsigned type>
-bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
-{
- if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
- return true;
- return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
-}
-
-template<>
-bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
-{
- return false;
-}
-
-bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
-{
- if (attrName)
- return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
-
- for (int type = 0; type < numNodeListInvalidationTypes; type++) {
- if (m_nodeListCounts[type])
- return true;
- }
-
- return false;
-}
-
-void Document::invalidateNodeListCaches(const QualifiedName* attrName)
-{
- HashSet<LiveNodeListBase*>::iterator end = m_listsInvalidatedAtDocument.end();
- for (HashSet<LiveNodeListBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
- (*it)->invalidateCache(attrName);
-}
-
void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement)
{
if (hasRareData() && (!attrName || isAttributeNode())) {
@@ -888,11 +846,8 @@ void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, El
document().invalidateNodeListCaches(attrName);
for (Node* node = this; node; node = node->parentNode()) {
- if (!node->hasRareData())
- continue;
- NodeRareData* data = node->rareData();
- if (data->nodeLists())
- data->nodeLists()->invalidateCaches(attrName);
+ if (NodeListsNodeData* lists = node->nodeLists())
+ lists->invalidateCaches(attrName);
}
}
@@ -906,35 +861,10 @@ void Node::clearNodeLists()
rareData()->clearNodeLists();
}
-void Node::checkSetPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
-{
- // Perform error checking as required by spec for setting Node.prefix. Used by
- // Element::setPrefix() and Attr::setPrefix()
-
- if (!prefix.isEmpty() && !Document::isValidName(prefix)) {
- exceptionState.throwDOMException(InvalidCharacterError, "The prefix '" + prefix + "' is not a valid name.");
- return;
- }
-
- // FIXME: Raise NamespaceError if prefix is malformed per the Namespaces in XML specification.
-
- const AtomicString& nodeNamespaceURI = namespaceURI();
- if (nodeNamespaceURI.isEmpty() && !prefix.isEmpty()) {
- exceptionState.throwDOMException(NamespaceError, "No namespace is set, so a namespace prefix may not be set.");
- return;
- }
-
- if (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI) {
- exceptionState.throwDOMException(NamespaceError, "The prefix '" + xmlAtom + "' may not be set on namespace '" + nodeNamespaceURI + "'.");
- return;
- }
- // Attribute-specific checks are in Attr::setPrefix().
-}
-
bool Node::isDescendantOf(const Node *other) const
{
// Return true if other is an ancestor of this, otherwise false
- if (!other || !other->hasChildNodes() || inDocument() != other->inDocument())
+ if (!other || !other->hasChildren() || inDocument() != other->inDocument())
return false;
if (other->treeScope() != treeScope())
return false;
@@ -968,7 +898,7 @@ bool Node::containsIncludingShadowDOM(const Node* node) const
if (inDocument() != node->inDocument())
return false;
- bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildNodes();
+ bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildren();
bool hasShadow = isElementNode() && toElement(this)->shadow();
if (!hasChildren && !hasShadow)
return false;
@@ -1051,10 +981,8 @@ void Node::attach(const AttachContext&)
clearNeedsStyleRecalc();
- if (Document* doc = documentInternal()) {
- if (AXObjectCache* cache = doc->axObjectCache())
- cache->updateCacheAfterNodeIsAttached(this);
- }
+ if (AXObjectCache* cache = document().axObjectCache())
+ cache->updateCacheAfterNodeIsAttached(this);
}
#ifndef NDEBUG
@@ -1068,6 +996,9 @@ bool Node::inDetach() const
void Node::detach(const AttachContext& context)
{
+ ASSERT(document().lifecycle().stateAllowsDetach());
+ DocumentLifecycle::DetachScope willDetach(document().lifecycle());
+
#ifndef NDEBUG
ASSERT(!detachingNode);
detachingNode = this;
@@ -1093,6 +1024,11 @@ void Node::detach(const AttachContext& context)
setStyleChange(NeedsReattachStyleChange);
setChildNeedsStyleRecalc();
+ if (StyleResolver* resolver = document().styleResolver())
+ resolver->ruleFeatureSet().styleInvalidator().clearInvalidation(*this);
+ clearChildNeedsStyleInvalidation();
+ clearNeedsStyleInvalidation();
+
#ifndef NDEBUG
detachingNode = 0;
#endif
@@ -1102,12 +1038,12 @@ void Node::reattachWhitespaceSiblings(Text* start)
{
for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) {
if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) {
- bool hadRenderer = sibling->hasRenderer();
+ bool hadRenderer = !!sibling->renderer();
sibling->reattach();
// If the reattach didn't toggle the visibility of the whitespace we don't
// need to continue reattaching siblings since they won't toggle visibility
// either.
- if (hadRenderer == sibling->hasRenderer())
+ if (hadRenderer == !!sibling->renderer())
return;
} else if (sibling->renderer()) {
return;
@@ -1196,11 +1132,6 @@ bool Node::canStartSelection() const
return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true;
}
-bool Node::isRegisteredWithNamedFlow() const
-{
- return document().renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
-}
-
Element* Node::shadowHost() const
{
if (ShadowRoot* root = containingShadowRoot())
@@ -1218,8 +1149,8 @@ Node* Node::deprecatedShadowAncestorNode() const
ShadowRoot* Node::containingShadowRoot() const
{
- Node* root = treeScope().rootNode();
- return root && root->isShadowRoot() ? toShadowRoot(root) : 0;
+ Node& root = treeScope().rootNode();
+ return root.isShadowRoot() ? toShadowRoot(&root) : 0;
}
Node* Node::nonBoundaryShadowTreeRootNode()
@@ -1280,7 +1211,7 @@ Element *Node::enclosingBlockFlowElement() const
n = n->parentNode();
if (!n)
break;
- if (n->isBlockFlowElement() || n->hasTagName(bodyTag))
+ if (n->isBlockFlowElement() || isHTMLBodyElement(*n))
return toElement(n);
}
return 0;
@@ -1289,7 +1220,7 @@ Element *Node::enclosingBlockFlowElement() const
bool Node::isRootEditableElement() const
{
return rendererIsEditable() && isElementNode() && (!parentNode() || !parentNode()->rendererIsEditable()
- || !parentNode()->isElementNode() || hasTagName(bodyTag));
+ || !parentNode()->isElementNode() || isHTMLBodyElement((*this)));
}
Element* Node::rootEditableElement(EditableType editableType) const
@@ -1308,7 +1239,7 @@ Element* Node::rootEditableElement() const
for (Node* n = const_cast<Node*>(this); n && n->rendererIsEditable(); n = n->parentNode()) {
if (n->isElementNode())
result = toElement(n);
- if (n->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*n))
break;
}
return result;
@@ -1321,69 +1252,6 @@ bool Node::inSameContainingBlockFlowElement(Node *n)
// FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node.
-PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& localName)
-{
- if (localName.isNull())
- return 0;
-
- if (document().isHTMLDocument())
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTagNodeList>(this, HTMLTagNodeListType, localName);
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<TagNodeList>(this, TagNodeListType, localName);
-}
-
-PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
-{
- if (localName.isNull())
- return 0;
-
- if (namespaceURI == starAtom)
- return getElementsByTagName(localName);
-
- return ensureRareData().ensureNodeLists().addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
-}
-
-PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
-{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<NameNodeList>(this, NameNodeListType, elementName);
-}
-
-PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
-{
- return ensureRareData().ensureNodeLists().addCacheWithName<ClassNodeList>(this, ClassNodeListType, classNames);
-}
-
-PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
-{
- ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<RadioNodeList>(this, RadioNodeListType, name);
-}
-
-PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, ExceptionState& exceptionState)
-{
- if (selectors.isEmpty()) {
- exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
- return 0;
- }
-
- SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
- if (!selectorQuery)
- return 0;
- return selectorQuery->queryFirst(*this);
-}
-
-PassRefPtr<NodeList> Node::querySelectorAll(const AtomicString& selectors, ExceptionState& exceptionState)
-{
- if (selectors.isEmpty()) {
- exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
- return 0;
- }
-
- SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
- if (!selectorQuery)
- return 0;
- return selectorQuery->queryAll(*this);
-}
-
Document* Node::ownerDocument() const
{
Document* doc = &document();
@@ -1413,9 +1281,6 @@ bool Node::isEqualNode(Node* other) const
if (namespaceURI() != other->namespaceURI())
return false;
- if (prefix() != other->prefix())
- return false;
-
if (nodeValue() != other->nodeValue())
return false;
@@ -1436,7 +1301,7 @@ bool Node::isEqualNode(Node* other) const
if (otherChild)
return false;
- if (nodeType == DOCUMENT_TYPE_NODE) {
+ if (isDocumentTypeNode()) {
const DocumentType* documentTypeThis = toDocumentType(this);
const DocumentType* documentTypeOther = toDocumentType(other);
@@ -1445,11 +1310,6 @@ bool Node::isEqualNode(Node* other) const
if (documentTypeThis->systemId() != documentTypeOther->systemId())
return false;
-
- if (documentTypeThis->internalSubset() != documentTypeOther->internalSubset())
- return false;
-
- // FIXME: We don't compare entities or notations because currently both are always empty.
}
return true;
@@ -1461,22 +1321,22 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
switch (nodeType()) {
case ELEMENT_NODE: {
- const Element* elem = toElement(this);
-
- if (elem->prefix().isNull())
- return elem->namespaceURI() == namespaceURI;
+ const Element& element = toElement(*this);
- if (elem->hasAttributes()) {
- for (unsigned i = 0; i < elem->attributeCount(); i++) {
- const Attribute* attr = elem->attributeItem(i);
+ if (element.prefix().isNull())
+ return element.namespaceURI() == namespaceURI;
- if (attr->localName() == xmlnsAtom)
- return attr->value() == namespaceURI;
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->localName() == xmlnsAtom)
+ return it->value() == namespaceURI;
}
}
- if (Element* ancestor = ancestorElement())
- return ancestor->isDefaultNamespace(namespaceURI);
+ if (Element* parent = parentElement())
+ return parent->isDefaultNamespace(namespaceURI);
return false;
}
@@ -1484,8 +1344,6 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
if (Element* de = toDocument(this)->documentElement())
return de->isDefaultNamespace(namespaceURI);
return false;
- case ENTITY_NODE:
- case NOTATION_NODE:
case DOCUMENT_TYPE_NODE:
case DOCUMENT_FRAGMENT_NODE:
return false;
@@ -1496,8 +1354,8 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
return false;
}
default:
- if (Element* ancestor = ancestorElement())
- return ancestor->isDefaultNamespace(namespaceURI);
+ if (Element* parent = parentElement())
+ return parent->isDefaultNamespace(namespaceURI);
return false;
}
}
@@ -1505,34 +1363,37 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const
{
// Implemented according to
- // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespacePrefixAlgo
+ // http://dom.spec.whatwg.org/#dom-node-lookupprefix
- if (namespaceURI.isEmpty())
+ if (namespaceURI.isEmpty() || namespaceURI.isNull())
return nullAtom;
+ const Element* context;
+
switch (nodeType()) {
case ELEMENT_NODE:
- return lookupNamespacePrefix(namespaceURI, toElement(this));
+ context = toElement(this);
+ break;
case DOCUMENT_NODE:
- if (Element* de = toDocument(this)->documentElement())
- return de->lookupPrefix(namespaceURI);
- return nullAtom;
- case ENTITY_NODE:
- case NOTATION_NODE:
+ context = toDocument(this)->documentElement();
+ break;
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_TYPE_NODE:
- return nullAtom;
- case ATTRIBUTE_NODE: {
- const Attr *attr = toAttr(this);
- if (attr->ownerElement())
- return attr->ownerElement()->lookupPrefix(namespaceURI);
- return nullAtom;
- }
+ context = 0;
+ break;
+ // FIXME: Remove this when Attr no longer extends Node (CR305105)
+ case ATTRIBUTE_NODE:
+ context = toAttr(this)->ownerElement();
+ break;
default:
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupPrefix(namespaceURI);
- return nullAtom;
+ context = parentElement();
+ break;
}
+
+ if (!context)
+ return nullAtom;
+
+ return context->locateNamespacePrefix(namespaceURI);
}
const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
@@ -1545,38 +1406,35 @@ const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
switch (nodeType()) {
case ELEMENT_NODE: {
- const Element *elem = toElement(this);
-
- if (!elem->namespaceURI().isNull() && elem->prefix() == prefix)
- return elem->namespaceURI();
-
- if (elem->hasAttributes()) {
- for (unsigned i = 0; i < elem->attributeCount(); i++) {
- const Attribute* attr = elem->attributeItem(i);
-
- if (attr->prefix() == xmlnsAtom && attr->localName() == prefix) {
- if (!attr->value().isEmpty())
- return attr->value();
-
+ const Element& element = toElement(*this);
+
+ if (!element.namespaceURI().isNull() && element.prefix() == prefix)
+ return element.namespaceURI();
+
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->prefix() == xmlnsAtom && it->localName() == prefix) {
+ if (!it->value().isEmpty())
+ return it->value();
return nullAtom;
- } else if (attr->localName() == xmlnsAtom && prefix.isNull()) {
- if (!attr->value().isEmpty())
- return attr->value();
-
+ }
+ if (it->localName() == xmlnsAtom && prefix.isNull()) {
+ if (!it->value().isEmpty())
+ return it->value();
return nullAtom;
}
}
}
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupNamespaceURI(prefix);
+ if (Element* parent = parentElement())
+ return parent->lookupNamespaceURI(prefix);
return nullAtom;
}
case DOCUMENT_NODE:
if (Element* de = toDocument(this)->documentElement())
return de->lookupNamespaceURI(prefix);
return nullAtom;
- case ENTITY_NODE:
- case NOTATION_NODE:
case DOCUMENT_TYPE_NODE:
case DOCUMENT_FRAGMENT_NODE:
return nullAtom;
@@ -1588,37 +1446,12 @@ const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
return nullAtom;
}
default:
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupNamespaceURI(prefix);
+ if (Element* parent = parentElement())
+ return parent->lookupNamespaceURI(prefix);
return nullAtom;
}
}
-const AtomicString& Node::lookupNamespacePrefix(const AtomicString& _namespaceURI, const Element* originalElement) const
-{
- if (_namespaceURI.isNull())
- return nullAtom;
-
- if (originalElement->lookupNamespaceURI(prefix()) == _namespaceURI)
- return prefix();
-
- ASSERT(isElementNode());
- const Element* thisElement = toElement(this);
- if (thisElement->hasAttributes()) {
- for (unsigned i = 0; i < thisElement->attributeCount(); i++) {
- const Attribute* attr = thisElement->attributeItem(i);
-
- if (attr->prefix() == xmlnsAtom && attr->value() == _namespaceURI
- && originalElement->lookupNamespaceURI(attr->localName()) == _namespaceURI)
- return attr->localName();
- }
- }
-
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupNamespacePrefix(_namespaceURI, originalElement);
- return nullAtom;
-}
-
static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content)
{
switch (node->nodeType()) {
@@ -1635,18 +1468,18 @@ static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool&
break;
case Node::ELEMENT_NODE:
- if (node->hasTagName(brTag) && convertBRsToNewlines) {
+ if (isHTMLBRElement(*node) && convertBRsToNewlines) {
isNullString = false;
content.append('\n');
break;
}
// Fall through.
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
isNullString = false;
- for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
- if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
+ for (Node* child = toContainerNode(node)->firstChild(); child; child = child->nextSibling()) {
+ Node::NodeType childNodeType = child->nodeType();
+ if (childNodeType == Node::COMMENT_NODE || childNodeType == Node::PROCESSING_INSTRUCTION_NODE)
continue;
appendTextContent(child, convertBRsToNewlines, isNullString, content);
}
@@ -1654,8 +1487,6 @@ static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool&
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
}
}
@@ -1679,35 +1510,28 @@ void Node::setTextContent(const String& text)
return;
case ELEMENT_NODE:
case ATTRIBUTE_NODE:
- case ENTITY_NODE:
case DOCUMENT_FRAGMENT_NODE: {
- RefPtr<ContainerNode> container = toContainerNode(this);
+ // FIXME: Merge this logic into replaceChildrenWithText.
+ RefPtrWillBeRawPtr<ContainerNode> container = toContainerNode(this);
+ // No need to do anything if the text is identical.
+ if (container->hasOneTextChild() && toText(container->firstChild())->data() == text)
+ return;
ChildListMutationScope mutation(*this);
container->removeChildren();
+ // Note: This API will not insert empty text nodes:
+ // http://dom.spec.whatwg.org/#dom-node-textcontent
if (!text.isEmpty())
container->appendChild(document().createTextNode(text), ASSERT_NO_EXCEPTION);
return;
}
case DOCUMENT_NODE:
case DOCUMENT_TYPE_NODE:
- case NOTATION_NODE:
- case XPATH_NAMESPACE_NODE:
// Do nothing.
return;
}
ASSERT_NOT_REACHED();
}
-Element* Node::ancestorElement() const
-{
- // In theory, there can be EntityReference nodes between elements, but this is currently not supported.
- for (ContainerNode* n = parentNode(); n; n = n->parentNode()) {
- if (n->isElementNode())
- return toElement(n);
- }
- return 0;
-}
-
bool Node::offsetInCharacters() const
{
return false;
@@ -1751,17 +1575,17 @@ unsigned short Node::compareDocumentPositionInternal(const Node* otherNode, Shad
// We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first.
const Element* owner1 = attr1->ownerElement();
owner1->synchronizeAllAttributes();
- unsigned length = owner1->attributeCount();
- for (unsigned i = 0; i < length; ++i) {
+ AttributeCollection attributes = owner1->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
// If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
// implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of
// the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
// when comparing two attributes of the same element, and inserting or removing additional attributes might change
// the order between existing attributes.
- const Attribute* attribute = owner1->attributeItem(i);
- if (attr1->qualifiedName() == attribute->name())
+ if (attr1->qualifiedName() == it->name())
return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
- if (attr2->qualifiedName() == attribute->name())
+ if (attr2->qualifiedName() == it->name())
return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
}
@@ -1796,7 +1620,7 @@ unsigned short Node::compareDocumentPositionInternal(const Node* otherNode, Shad
unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0;
// Walk the two chains backwards and look for the first difference.
- for (unsigned i = min(index1, index2); i; --i) {
+ for (unsigned i = std::min(index1, index2); i; --i) {
const Node* child1 = chain1[--index1];
const Node* child2 = chain2[--index2];
if (child1 != child2) {
@@ -1848,8 +1672,7 @@ FloatPoint Node::convertToPage(const FloatPoint& p) const
return renderer()->localToAbsolute(p, UseTransforms);
// Otherwise go up the tree looking for a renderer
- Element *parent = ancestorElement();
- if (parent)
+ if (Element* parent = parentElement())
return parent->convertToPage(p);
// No parent - no conversion needed
@@ -1863,8 +1686,7 @@ FloatPoint Node::convertFromPage(const FloatPoint& p) const
return renderer()->absoluteToLocal(p, UseTransforms);
// Otherwise go up the tree looking for a renderer
- Element *parent = ancestorElement();
- if (parent)
+ if (Element* parent = parentElement())
return parent->convertFromPage(p);
// No parent - no conversion needed
@@ -1907,7 +1729,9 @@ static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder,
return;
stringBuilder.append(attrDesc);
+ stringBuilder.append("=\"");
stringBuilder.append(attr);
+ stringBuilder.append("\"");
}
void Node::showNode(const char* prefix) const
@@ -1921,8 +1745,9 @@ void Node::showNode(const char* prefix) const
fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
} else {
StringBuilder attrs;
- appendAttributeDesc(this, attrs, classAttr, " CLASS=");
- appendAttributeDesc(this, attrs, styleAttr, " STYLE=");
+ appendAttributeDesc(this, attrs, idAttr, " ID");
+ appendAttributeDesc(this, attrs, classAttr, " CLASS");
+ appendAttributeDesc(this, attrs, styleAttr, " STYLE");
fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.toString().utf8().data());
}
}
@@ -1963,11 +1788,12 @@ void Node::showNodePathForThis() const
if (previous->nodeName() == node->nodeName())
++count;
if (hasIdAttr)
- fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.string().utf8().data(), count);
+ fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.utf8().data(), count);
else
fprintf(stderr, "[%d]", count);
- } else if (hasIdAttr)
- fprintf(stderr, "[@id=\"%s\"]", idattr.string().utf8().data());
+ } else if (hasIdAttr) {
+ fprintf(stderr, "[@id=\"%s\"]", idattr.utf8().data());
+ }
break;
}
case TEXT_NODE:
@@ -2010,7 +1836,7 @@ void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, co
{
const Node* rootNode;
const Node* node = this;
- while (node->parentOrShadowHostNode() && !node->hasTagName(bodyTag))
+ while (node->parentOrShadowHostNode() && !isHTMLBodyElement(*node))
node = node->parentOrShadowHostNode();
rootNode = node;
@@ -2036,7 +1862,7 @@ static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node)
{
ContainerNode* parent = node->parentOrShadowHostNode();
if (!parent && node->document().frame())
- parent = node->document().frame()->ownerElement();
+ parent = node->document().frame()->deprecatedLocalOwner();
return parent;
}
@@ -2071,31 +1897,13 @@ void Node::showTreeForThisAcrossFrame() const
// --------
-void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
-{
- NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
- for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it)
- it->value->invalidateCache(attrName);
-
- NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
- for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it)
- it->value->invalidateCache(attrName);
-
- if (attrName)
- return;
-
- TagNodeListCacheNS::iterator tagCacheEnd = m_tagNodeListCacheNS.end();
- for (TagNodeListCacheNS::iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheEnd; ++it)
- it->value->invalidateCache();
-}
-
Node* Node::enclosingLinkEventParentOrSelf()
{
- for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
+ for (Node* node = this; node; node = NodeRenderingTraversal::parent(node)) {
// For imagemaps, the enclosing link node is the associated area element not the image itself.
// So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
// for them.
- if (node->isLink() && !node->hasTagName(imgTag))
+ if (node->isLink() && !isHTMLImageElement(*node))
return node;
}
@@ -2130,19 +1938,8 @@ void Node::didMoveToNewDocument(Document& oldDocument)
cache->remove(this);
}
- const EventListenerVector& mousewheelListeners = getEventListeners(EventTypeNames::mousewheel);
- WheelController* oldController = WheelController::from(&oldDocument);
- WheelController* newController = WheelController::from(&document());
- for (size_t i = 0; i < mousewheelListeners.size(); ++i) {
- oldController->didRemoveWheelEventHandler(&oldDocument);
- newController->didAddWheelEventHandler(&document());
- }
-
- const EventListenerVector& wheelListeners = getEventListeners(EventTypeNames::wheel);
- for (size_t i = 0; i < wheelListeners.size(); ++i) {
- oldController->didRemoveWheelEventHandler(&oldDocument);
- newController->didAddWheelEventHandler(&document());
- }
+ oldDocument.markers().removeMarkers(this);
+ oldDocument.updateRangesAfterNodeMovedToAnotherDocument(*this);
if (const TouchEventTargetSet* touchHandlers = oldDocument.touchEventTargets()) {
while (touchHandlers->contains(this)) {
@@ -2150,15 +1947,21 @@ void Node::didMoveToNewDocument(Document& oldDocument)
document().didAddTouchEventHandler(this);
}
}
+ if (oldDocument.frameHost() != document().frameHost()) {
+ if (oldDocument.frameHost())
+ oldDocument.frameHost()->eventHandlerRegistry().didMoveOutOfFrameHost(*this);
+ if (document().frameHost())
+ document().frameHost()->eventHandlerRegistry().didMoveIntoFrameHost(*this);
+ }
- if (Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
+ if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
for (size_t i = 0; i < registry->size(); ++i) {
document().addMutationObserverTypes(registry->at(i)->mutationTypes());
}
}
- if (HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry()) {
- for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
+ if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry()) {
+ for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
document().addMutationObserverTypes((*iter)->mutationTypes());
}
}
@@ -2171,10 +1974,10 @@ static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eve
Document& document = targetNode->document();
document.addListenerTypeIfNeeded(eventType);
- if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
- WheelController::from(&document)->didAddWheelEventHandler(&document);
- else if (isTouchEventType(eventType))
+ if (isTouchEventType(eventType))
document.didAddTouchEventHandler(targetNode);
+ if (document.frameHost())
+ document.frameHost()->eventHandlerRegistry().didAddEventHandler(*targetNode, eventType);
return true;
}
@@ -2192,10 +1995,10 @@ static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString&
// FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
// listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
Document& document = targetNode->document();
- if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
- WheelController::from(&document)->didAddWheelEventHandler(&document);
- else if (isTouchEventType(eventType))
+ if (isTouchEventType(eventType))
document.didRemoveTouchEventHandler(targetNode);
+ if (document.frameHost())
+ document.frameHost()->eventHandlerRegistry().didRemoveEventHandler(*targetNode, eventType);
return true;
}
@@ -2205,12 +2008,34 @@ bool Node::removeEventListener(const AtomicString& eventType, EventListener* lis
return tryRemoveEventListener(this, eventType, listener, useCapture);
}
-typedef HashMap<Node*, OwnPtr<EventTargetData> > EventTargetDataMap;
+void Node::removeAllEventListeners()
+{
+ if (hasEventListeners() && document().frameHost())
+ document().frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
+ EventTarget::removeAllEventListeners();
+ document().didClearTouchEventHandlers(this);
+}
+
+void Node::removeAllEventListenersRecursively()
+{
+ for (Node* node = this; node; node = NodeTraversal::next(*node)) {
+ node->removeAllEventListeners();
+ for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ root->removeAllEventListenersRecursively();
+ }
+}
+
+typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Node>, OwnPtr<EventTargetData> > EventTargetDataMap;
static EventTargetDataMap& eventTargetDataMap()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<EventTargetDataMap>, map, (new EventTargetDataMap()));
+ return *map;
+#else
DEFINE_STATIC_LOCAL(EventTargetDataMap, map, ());
return map;
+#endif
}
EventTargetData* Node::eventTargetData()
@@ -2228,12 +2053,14 @@ EventTargetData& Node::ensureEventTargetData()
return *data;
}
+#if !ENABLE(OILPAN)
void Node::clearEventTargetData()
{
eventTargetDataMap().remove(this);
}
+#endif
-Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry()
+WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* Node::mutationObserverRegistry()
{
if (!hasRareData())
return 0;
@@ -2243,7 +2070,7 @@ Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry()
return &data->registry;
}
-HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry()
+WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* Node::transientMutationObserverRegistry()
{
if (!hasRareData())
return 0;
@@ -2254,7 +2081,7 @@ HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry(
}
template<typename Registry>
-static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node* target, MutationObserver::MutationType type, const QualifiedName* attributeName)
+static inline void collectMatchingObserversForMutation(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
if (!registry)
return;
@@ -2262,30 +2089,30 @@ static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*
const MutationObserverRegistration& registration = **iter;
if (registration.shouldReceiveMutationFrom(target, type, attributeName)) {
MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions();
- HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration.observer(), deliveryOptions);
+ WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::AddResult result = observers.add(&registration.observer(), deliveryOptions);
if (!result.isNewEntry)
- result.iterator->value |= deliveryOptions;
+ result.storedValue->value |= deliveryOptions;
}
}
}
-void Node::getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
+void Node::getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
- collectMatchingObserversForMutation(observers, mutationObserverRegistry(), this, type, attributeName);
- collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), this, type, attributeName);
+ collectMatchingObserversForMutation(observers, mutationObserverRegistry(), *this, type, attributeName);
+ collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), *this, type, attributeName);
for (Node* node = parentNode(); node; node = node->parentNode()) {
- collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), this, type, attributeName);
- collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), this, type, attributeName);
+ collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), *this, type, attributeName);
+ collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), *this, type, attributeName);
}
}
-void Node::registerMutationObserver(MutationObserver* observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
{
MutationObserverRegistration* registration = 0;
- Vector<OwnPtr<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
for (size_t i = 0; i < registry.size(); ++i) {
- if (registry[i]->observer() == observer) {
+ if (&registry[i]->observer() == &observer) {
registration = registry[i].get();
registration->resetObservation(options, attributeFilter);
}
@@ -2301,7 +2128,7 @@ void Node::registerMutationObserver(MutationObserver* observer, MutationObserver
void Node::unregisterMutationObserver(MutationObserverRegistration* registration)
{
- Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry();
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry();
ASSERT(registry);
if (!registry)
return;
@@ -2314,7 +2141,12 @@ void Node::unregisterMutationObserver(MutationObserverRegistration* registration
// Deleting the registration may cause this node to be derefed, so we must make sure the Vector operation completes
// before that, in case |this| is destroyed (see MutationObserverRegistration::m_registrationNodeKeepAlive).
// FIXME: Simplify the registration/transient registration logic to make this understandable by humans.
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
+#if ENABLE(OILPAN)
+ // The explicit dispose() is needed to have the registration
+ // object unregister itself promptly.
+ registration->dispose();
+#endif
registry->remove(index);
}
@@ -2325,7 +2157,7 @@ void Node::registerTransientMutationObserver(MutationObserverRegistration* regis
void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration)
{
- HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry();
+ WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry();
ASSERT(transientRegistry);
if (!transientRegistry)
return;
@@ -2340,15 +2172,15 @@ void Node::notifyMutationObserversNodeWillDetach()
return;
for (Node* node = parentNode(); node; node = node->parentNode()) {
- if (Vector<OwnPtr<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
+ if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
const size_t size = registry->size();
for (size_t i = 0; i < size; ++i)
- registry->at(i)->observedSubtreeNodeWillDetach(this);
+ registry->at(i)->observedSubtreeNodeWillDetach(*this);
}
- if (HashSet<MutationObserverRegistration*>* transientRegistry = node->transientMutationObserverRegistry()) {
- for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
- (*iter)->observedSubtreeNodeWillDetach(this);
+ if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = node->transientMutationObserverRegistry()) {
+ for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
+ (*iter)->observedSubtreeNodeWillDetach(*this);
}
}
}
@@ -2364,17 +2196,17 @@ void Node::handleLocalEvents(Event* event)
fireEventListeners(event);
}
-void Node::dispatchScopedEvent(PassRefPtr<Event> event)
+void Node::dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event> event)
{
dispatchScopedEventDispatchMediator(EventDispatchMediator::create(event));
}
-void Node::dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator> eventDispatchMediator)
+void Node::dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator> eventDispatchMediator)
{
EventDispatcher::dispatchScopedEvent(this, eventDispatchMediator);
}
-bool Node::dispatchEvent(PassRefPtr<Event> event)
+bool Node::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
if (event->isMouseEvent())
return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(static_pointer_cast<MouseEvent>(event), MouseEventDispatchMediator::SyntheticMouseEvent));
@@ -2396,10 +2228,10 @@ void Node::dispatchSubtreeModifiedEvent()
dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMSubtreeModified, true));
}
-bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)
+bool Node::dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent)
{
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- RefPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail);
+ RefPtrWillBeRawPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail);
event->setUnderlyingEvent(underlyingEvent);
dispatchScopedEvent(event);
return event->defaultHandled();
@@ -2418,13 +2250,13 @@ bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicStrin
bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
{
- RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event);
+ RefPtrWillBeRawPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event);
if (!gestureEvent.get())
return false;
return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent));
}
-bool Node::dispatchTouchEvent(PassRefPtr<TouchEvent> event)
+bool Node::dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent> event)
{
return EventDispatcher::dispatchEvent(this, TouchEventDispatchMediator::create(event));
}
@@ -2434,27 +2266,11 @@ void Node::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEve
EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions);
}
-bool Node::dispatchBeforeLoadEvent(const String& sourceURL)
-{
- if (!document().hasListenerType(Document::BEFORELOAD_LISTENER))
- return true;
-
- RefPtr<Node> protector(this);
- RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
- dispatchEvent(beforeLoadEvent.get());
- return !beforeLoadEvent->defaultPrevented();
-}
-
bool Node::dispatchWheelEvent(const PlatformWheelEvent& event)
{
return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document().domWindow()));
}
-void Node::dispatchChangeEvent()
-{
- dispatchScopedEvent(Event::createBubble(EventTypeNames::change));
-}
-
void Node::dispatchInputEvent()
{
dispatchScopedEvent(Event::createBubble(EventTypeNames::input));
@@ -2467,7 +2283,7 @@ void Node::defaultEventHandler(Event* event)
const AtomicString& eventType = event->type();
if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) {
if (event->isKeyboardEvent()) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event));
}
} else if (eventType == EventTypeNames::click) {
@@ -2479,7 +2295,7 @@ void Node::defaultEventHandler(Event* event)
page->contextMenuController().handleContextMenuEvent(event);
} else if (eventType == EventTypeNames::textInput) {
if (event->hasInterface(EventNames::TextEvent)) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event));
}
#if OS(WIN)
@@ -2494,7 +2310,7 @@ void Node::defaultEventHandler(Event* event)
renderer = renderer->parent();
if (renderer) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().startPanScrolling(renderer);
}
}
@@ -2509,7 +2325,7 @@ void Node::defaultEventHandler(Event* event)
startNode = startNode->parentOrShadowHostNode();
if (startNode && startNode->renderer()) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent);
}
} else if (event->type() == EventTypeNames::webkitEditableContentChanged) {
@@ -2542,6 +2358,7 @@ bool Node::willRespondToTouchEvents()
return hasEventListeners(EventTypeNames::touchstart) || hasEventListeners(EventTypeNames::touchmove) || hasEventListeners(EventTypeNames::touchcancel) || hasEventListeners(EventTypeNames::touchend);
}
+#if !ENABLE(OILPAN)
// This is here for inlining
inline void TreeScope::removedLastRefToScope()
{
@@ -2553,14 +2370,14 @@ inline void TreeScope::removedLastRefToScope()
// extra self-only ref.
guardRef();
dispose();
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
// We need to do this right now since guardDeref() can delete this.
- rootNode()->m_inRemovedLastRefFunction = false;
+ rootNode().m_inRemovedLastRefFunction = false;
#endif
guardDeref();
} else {
-#if !ASSERT_DISABLED
- rootNode()->m_inRemovedLastRefFunction = false;
+#if ASSERT_ENABLED
+ rootNode().m_inRemovedLastRefFunction = false;
#endif
#if SECURITY_ASSERT_ENABLED
beginDeletion();
@@ -2586,6 +2403,7 @@ void Node::removedLastRef()
#endif
delete this;
}
+#endif
unsigned Node::connectedSubframeCount() const
{
@@ -2625,12 +2443,12 @@ void Node::updateAncestorConnectedSubframeCountForInsertion() const
node->incrementConnectedSubframeCount(count);
}
-PassRefPtr<NodeList> Node::getDestinationInsertionPoints()
+PassRefPtrWillBeRawPtr<StaticNodeList> Node::getDestinationInsertionPoints()
{
document().updateDistributionForNodeIfNeeded(this);
- Vector<InsertionPoint*, 8> insertionPoints;
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
collectDestinationInsertionPoints(*this, insertionPoints);
- Vector<RefPtr<Node> > filteredInsertionPoints;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > filteredInsertionPoints;
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* insertionPoint = insertionPoints[i];
ASSERT(insertionPoint->containingShadowRoot());
@@ -2640,28 +2458,6 @@ PassRefPtr<NodeList> Node::getDestinationInsertionPoints()
return StaticNodeList::adopt(filteredInsertionPoints);
}
-void Node::registerScopedHTMLStyleChild()
-{
- setHasScopedHTMLStyleChild(true);
-}
-
-void Node::unregisterScopedHTMLStyleChild()
-{
- ASSERT(hasScopedHTMLStyleChild());
- setHasScopedHTMLStyleChild(numberOfScopedHTMLStyleChildren());
-}
-
-size_t Node::numberOfScopedHTMLStyleChildren() const
-{
- size_t count = 0;
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(child)->isRegisteredAsScoped())
- count++;
- }
-
- return count;
-}
-
void Node::setFocus(bool flag)
{
document().userActionElements().setFocused(this, flag);
@@ -2720,17 +2516,56 @@ void Node::setCustomElementState(CustomElementState newState)
}
ASSERT(isHTMLElement() || isSVGElement());
- setFlag(CustomElement);
- setFlag(newState == Upgraded, CustomElementUpgraded);
+ setFlag(CustomElementFlag);
+ setFlag(newState == Upgraded, CustomElementUpgradedFlag);
if (oldState == NotCustomElement || newState == Upgraded)
- setNeedsStyleRecalc(); // :unresolved has changed
+ setNeedsStyleRecalc(SubtreeStyleChange); // :unresolved has changed
+}
+
+void Node::trace(Visitor* visitor)
+{
+ visitor->trace(m_parentOrShadowHostNode);
+ visitor->trace(m_previous);
+ visitor->trace(m_next);
+ if (hasRareData())
+ visitor->trace(rareData());
+ visitor->trace(m_treeScope);
+ EventTarget::trace(visitor);
+}
+
+unsigned Node::lengthOfContents() const
+{
+ // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
+ switch (nodeType()) {
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::COMMENT_NODE:
+ return toCharacterData(this)->length();
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ return toProcessingInstruction(this)->data().length();
+ case Node::ELEMENT_NODE:
+ case Node::ATTRIBUTE_NODE:
+ case Node::DOCUMENT_NODE:
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ return toContainerNode(this)->countChildren();
+ case Node::DOCUMENT_TYPE_NODE:
+ return 0;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
}
} // namespace WebCore
#ifndef NDEBUG
+void showNode(const WebCore::Node* node)
+{
+ if (node)
+ node->showNode("");
+}
+
void showTree(const WebCore::Node* node)
{
if (node)
diff --git a/chromium/third_party/WebKit/Source/core/dom/Node.h b/chromium/third_party/WebKit/Source/core/dom/Node.h
index 36235187f71..61858541de3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Node.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Node.h
@@ -36,10 +36,9 @@
#include "core/inspector/InspectorCounters.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURLHash.h"
#include "wtf/Forward.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/text/AtomicString.h"
// This needs to be here because Document.h also depends on it.
#define DUMP_NODE_STATISTICS 0
@@ -47,28 +46,27 @@
namespace WebCore {
class Attribute;
-class ClassNodeList;
+class ClassCollection;
class ContainerNode;
class DOMSettableTokenList;
class Document;
class Element;
class Event;
-class EventContext;
class EventDispatchMediator;
class EventListener;
class ExceptionState;
class FloatPoint;
-class Frame;
+class LocalFrame;
class HTMLInputElement;
class IntRect;
class KeyboardEvent;
class NSResolver;
class NameNodeList;
class NamedNodeMap;
+class NodeEventContext;
class NodeList;
class NodeListsNodeData;
class NodeRareData;
-class NodeRenderingContext;
class PlatformGestureEvent;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
@@ -81,11 +79,13 @@ class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
class ShadowRoot;
-class TagNodeList;
+class StaticNodeList;
+class TagCollection;
class Text;
class TouchEvent;
+class WeakNodeMap;
-const int nodeStyleChangeShift = 14;
+const int nodeStyleChangeShift = 19;
enum StyleChangeType {
NoStyleChange = 0,
@@ -94,13 +94,6 @@ enum StyleChangeType {
NeedsReattachStyleChange = 3 << nodeStyleChangeShift,
};
-// If the style change is from the renderer then we'll call setStyle on the
-// renderer even if the style computed from CSS is identical.
-enum StyleChangeSource {
- StyleChangeFromCSS,
- StyleChangeFromRenderer
-};
-
class NodeRareDataBase {
public:
RenderObject* renderer() const { return m_renderer; }
@@ -115,34 +108,43 @@ private:
RenderObject* m_renderer;
};
-class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
+#if ENABLE(OILPAN)
+#define NODE_BASE_CLASSES public GarbageCollectedFinalized<Node>, public EventTarget, public ScriptWrappable
+#else
+// TreeShared should be the last to pack TreeShared::m_refCount and
+// Node::m_nodeFlags on 64bit platforms.
+#define NODE_BASE_CLASSES public EventTarget, public ScriptWrappable, public TreeShared<Node>
+#endif
+
+class Node : NODE_BASE_CLASSES {
friend class Document;
friend class TreeScope;
friend class TreeScopeAdopter;
- DEFINE_EVENT_TARGET_REFCOUNTING(TreeShared<Node>);
+ DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(TreeShared<Node>);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Node);
public:
enum NodeType {
ELEMENT_NODE = 1,
ATTRIBUTE_NODE = 2,
TEXT_NODE = 3,
CDATA_SECTION_NODE = 4,
- ENTITY_NODE = 6,
PROCESSING_INSTRUCTION_NODE = 7,
COMMENT_NODE = 8,
DOCUMENT_NODE = 9,
DOCUMENT_TYPE_NODE = 10,
DOCUMENT_FRAGMENT_NODE = 11,
- NOTATION_NODE = 12,
- XPATH_NAMESPACE_NODE = 13,
};
- // EntityReference nodes are deprecated and impossible to create in WebKit.
- // We want Node.ENTITY_REFERNCE_NODE to exist in JS and this enum, makes the bindings
+ // Entity, EntityReference, Notation, and XPathNamespace nodes are impossible to create in Blink.
+ // But for compatibility reasons we want these enum values exist in JS, and this enum makes the bindings
// generation not complain about ENTITY_REFERENCE_NODE being missing from the implementation
// while not requiring all switch(NodeType) blocks to include this deprecated constant.
enum DeprecatedNodeType {
- ENTITY_REFERENCE_NODE = 5
+ ENTITY_REFERENCE_NODE = 5,
+ ENTITY_NODE = 6,
+ NOTATION_NODE = 12,
+ XPATH_NAMESPACE_NODE = 13,
};
enum DocumentPosition {
@@ -155,12 +157,13 @@ public:
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
};
+#if !ENABLE(OILPAN)
// All Nodes are placed in their own heap partition for security.
// See http://crbug.com/246860 for detail.
void* operator new(size_t);
void operator delete(void*);
+#endif
- static bool isSupported(const String& feature, const String& version);
static void dumpStatistics();
virtual ~Node();
@@ -174,15 +177,14 @@ public:
virtual NodeType nodeType() const = 0;
ContainerNode* parentNode() const;
Element* parentElement() const;
+ ContainerNode* parentElementOrShadowRoot() const;
+ ContainerNode* parentElementOrDocumentFragment() const;
Node* previousSibling() const { return m_previous; }
Node* nextSibling() const { return m_next; }
- PassRefPtr<NodeList> childNodes();
+ PassRefPtrWillBeRawPtr<NodeList> childNodes();
Node* firstChild() const;
Node* lastChild() const;
- // ChildNode interface API
- Element* previousElementSibling() const;
- Element* nextElementSibling() const;
void remove(ExceptionState&);
Node* pseudoAwareNextSibling() const;
@@ -194,17 +196,15 @@ public:
// These should all actually return a node, but this is only important for language bindings,
// which will already know and hold a ref on the right node to return.
- void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
- void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
void removeChild(Node* child, ExceptionState&);
- void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
- bool hasChildNodes() const { return firstChild(); }
- virtual PassRefPtr<Node> cloneNode(bool deep = false) = 0;
+ bool hasChildren() const { return firstChild(); }
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = false) = 0;
virtual const AtomicString& localName() const;
virtual const AtomicString& namespaceURI() const;
- virtual const AtomicString& prefix() const;
- virtual void setPrefix(const AtomicString&, ExceptionState&);
void normalize();
bool isSameNode(Node* other) const { return this == other; }
@@ -212,12 +212,11 @@ public:
bool isDefaultNamespace(const AtomicString& namespaceURI) const;
const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const;
const AtomicString& lookupNamespaceURI(const String& prefix) const;
- const AtomicString& lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const;
String textContent(bool convertBRsToNewlines = false) const;
void setTextContent(const String&);
- Node& lastDescendant() const;
+ Node& lastDescendantOrSelf() const;
// Other methods (not part of DOM)
@@ -232,7 +231,7 @@ public:
bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
PseudoId pseudoId() const { return (isElementNode() && hasCustomStyleCallbacks()) ? customPseudoId() : NOPSEUDO; }
- bool isCustomElement() const { return getFlag(CustomElement); }
+ bool isCustomElement() const { return getFlag(CustomElementFlag); }
enum CustomElementState {
NotCustomElement = 0,
WaitingForUpgrade = 1 << 0,
@@ -241,7 +240,7 @@ public:
CustomElementState customElementState() const
{
return isCustomElement()
- ? (getFlag(CustomElementUpgraded) ? Upgraded : WaitingForUpgrade)
+ ? (getFlag(CustomElementUpgradedFlag) ? Upgraded : WaitingForUpgrade)
: NotCustomElement;
}
void setCustomElementState(CustomElementState newState);
@@ -252,7 +251,6 @@ public:
virtual bool isAttributeNode() const { return false; }
virtual bool isCharacterDataNode() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
- virtual bool isPluginElement() const { return false; }
// StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color),
// class names (ex. class="foo bar") and other non-basic styling features. They and also control
@@ -265,16 +263,13 @@ public:
bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
bool isDocumentNode() const;
- bool isTreeScope() const { return treeScope().rootNode() == this; }
+ bool isTreeScope() const { return &treeScope().rootNode() == this; }
bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
- bool inNamedFlow() const { return getFlag(InNamedFlowFlag); }
bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
- bool isRegisteredWithNamedFlow() const;
-
bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); }
void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); }
@@ -293,7 +288,7 @@ public:
ContainerNode* parentOrShadowHostNode() const;
Element* parentOrShadowHostElement() const;
void setParentOrShadowHostNode(ContainerNode*);
- Node* highestAncestor() const;
+ Node& highestAncestorOrSelf() const;
// Knows about all kinds of hosts.
ContainerNode* parentOrShadowHostOrTemplateHostNode() const;
@@ -340,15 +335,6 @@ public:
bool inSameContainingBlockFlowElement(Node*);
- // Called by the parser when this element's close tag is reached,
- // signaling that all child tags have been parsed and added.
- // This is needed for <applet> and <object> elements, which can't lay themselves out
- // until they know all of their nested <param>s. [Radar 3603191, 4040848].
- // Also used for script elements and some SVG elements for similar purposes,
- // but making parsing a special case in this respect should be avoided if possible.
- virtual void finishParsingChildren() { }
- virtual void beginParsingChildren() { }
-
// For <link> and <style> elements.
virtual bool sheetLoaded() { return true; }
virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { }
@@ -358,8 +344,8 @@ public:
bool hasID() const;
bool hasClass() const;
- bool isUserActionElement() const { return getFlag(IsUserActionElement); }
- void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElement); }
+ bool isUserActionElement() const { return getFlag(IsUserActionElementFlag); }
+ void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElementFlag); }
bool active() const { return isUserActionElement() && isUserActionElementActive(); }
bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
@@ -377,31 +363,36 @@ public:
void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
- void setNeedsStyleRecalc(StyleChangeType = SubtreeStyleChange, StyleChangeSource = StyleChangeFromCSS);
+ void setNeedsStyleRecalc(StyleChangeType);
void clearNeedsStyleRecalc();
- bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalc); }
- void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalc); }
- void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalc); }
+ bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalcFlag); }
+ void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalcFlag); }
+ void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalcFlag); }
void markAncestorsWithChildNeedsDistributionRecalc();
+ bool childNeedsStyleInvalidation() const { return getFlag(ChildNeedsStyleInvalidationFlag); }
+ void setChildNeedsStyleInvalidation() { setFlag(ChildNeedsStyleInvalidationFlag); }
+ void clearChildNeedsStyleInvalidation() { clearFlag(ChildNeedsStyleInvalidationFlag); }
+ void markAncestorsWithChildNeedsStyleInvalidation();
+ bool needsStyleInvalidation() const { return getFlag(NeedsStyleInvalidationFlag); }
+ void clearNeedsStyleInvalidation() { clearFlag(NeedsStyleInvalidationFlag); }
+ void setNeedsStyleInvalidation();
+
void recalcDistribution();
- bool shouldNotifyRendererWithIdenticalStyles() const { return getFlag(NotifyRendererWithIdenticalStyles); }
+ bool svgFilterNeedsLayerUpdate() const { return getFlag(SVGFilterNeedsLayerUpdateFlag); }
+ void setSVGFilterNeedsLayerUpdate() { setFlag(SVGFilterNeedsLayerUpdateFlag); }
+ void clearSVGFilterNeedsLayerUpdate() { clearFlag(SVGFilterNeedsLayerUpdateFlag); }
void setIsLink(bool f);
- void setInNamedFlow() { setFlag(InNamedFlowFlag); }
- void clearInNamedFlow() { clearFlag(InNamedFlowFlag); }
-
- bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); }
- void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); }
-
bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); }
- void setV8CollectableDuringMinorGC(bool flag) { setFlag(flag, V8CollectableDuringMinorGCFlag); }
+ void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); }
+ void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); }
virtual void setFocus(bool flag);
virtual void setActive(bool flag = true);
@@ -466,9 +457,7 @@ public:
// Returns the document associated with this node. A Document node returns itself.
Document& document() const
{
- ASSERT(this);
- ASSERT(documentInternal());
- return *documentInternal();
+ return treeScope().document();
}
TreeScope& treeScope() const
@@ -483,7 +472,6 @@ public:
// node tree, false otherwise.
bool inDocument() const
{
- ASSERT(documentInternal() || !getFlag(InDocumentFlag));
return getFlag(InDocumentFlag);
}
bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
@@ -491,19 +479,15 @@ public:
bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
virtual bool childTypeAllowed(NodeType) const { return false; }
- unsigned childNodeCount() const;
- Node* childNode(unsigned index) const;
+ unsigned countChildren() const;
+ Node* traverseToChildAt(unsigned index) const;
- void checkSetPrefix(const AtomicString& prefix, ExceptionState&);
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
bool containsIncludingShadowDOM(const Node*) const;
bool containsIncludingHostElements(const Node&) const;
Node* commonAncestor(const Node&, Node* (*parent)(const Node&));
- // FIXME: Remove this when crbug.com/265716 cleans up contains semantics.
- bool bindingsContains(const Node* node) const { return containsIncludingShadowDOM(node); }
-
// Used to determine whether range offsets use characters or node indices.
virtual bool offsetInCharacters() const;
// Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
@@ -530,7 +514,6 @@ public:
else
m_data.m_renderer = renderer;
}
- bool hasRenderer() const { return renderer(); }
// Use these two methods with caution.
RenderBox* renderBox() const;
@@ -559,6 +542,9 @@ public:
void reattach(const AttachContext& = AttachContext());
void lazyReattachIfAttached();
+ // Returns true if recalcStyle should be called on the object, if there is such a method (on Document and Element).
+ bool shouldCallRecalcStyle(StyleRecalcChange);
+
// Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
RenderStyle* renderStyle() const;
RenderStyle* parentRenderStyle() const;
@@ -579,7 +565,7 @@ public:
//
// There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
// if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
- // return InsertionShouldCallDidNotifySubtreeInsertions from insrtedInto().
+ // return InsertionShouldCallDidNotifySubtreeInsertions from insertedInto().
//
enum InsertionNotificationRequest {
InsertionDone,
@@ -612,19 +598,10 @@ public:
NodeListsNodeData* nodeLists();
void clearNodeLists();
- PassRefPtr<NodeList> getElementsByTagName(const AtomicString&);
- PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<NodeList> getElementsByName(const String& elementName);
- PassRefPtr<NodeList> getElementsByClassName(const String& classNames);
- PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&);
-
virtual bool willRespondToMouseMoveEvents();
virtual bool willRespondToMouseClickEvents();
virtual bool willRespondToTouchEvents();
- PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionState&);
- PassRefPtr<NodeList> querySelectorAll(const AtomicString& selectors, ExceptionState&);
-
unsigned short compareDocumentPosition(const Node*) const;
enum ShadowTreesTreatment {
@@ -634,13 +611,15 @@ public:
unsigned short compareDocumentPositionInternal(const Node*, ShadowTreesTreatment) const;
- virtual Node* toNode();
+ virtual Node* toNode() OVERRIDE FINAL;
virtual const AtomicString& interfaceName() const OVERRIDE;
- virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual ExecutionContext* executionContext() const OVERRIDE FINAL;
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture = false) OVERRIDE;
+ virtual void removeAllEventListeners() OVERRIDE;
+ void removeAllEventListenersRecursively();
// Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
// has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch.
@@ -648,27 +627,25 @@ public:
virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
- void dispatchScopedEvent(PassRefPtr<Event>);
- void dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator>);
+ void dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event>);
+ void dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator>);
virtual void handleLocalEvents(Event*);
void dispatchSubtreeModifiedEvent();
- bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
+ bool dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent);
bool dispatchKeyEvent(const PlatformKeyboardEvent&);
bool dispatchWheelEvent(const PlatformWheelEvent&);
bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
bool dispatchGestureEvent(const PlatformGestureEvent&);
- bool dispatchTouchEvent(PassRefPtr<TouchEvent>);
+ bool dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent>);
void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents);
- virtual bool dispatchBeforeLoadEvent(const String& sourceURL);
- virtual void dispatchChangeEvent();
- virtual void dispatchInputEvent();
+ void dispatchInputEvent();
// Perform the default action for an event.
virtual void defaultEventHandler(Event*);
@@ -677,80 +654,89 @@ public:
virtual EventTargetData* eventTargetData() OVERRIDE;
virtual EventTargetData& ensureEventTargetData() OVERRIDE;
- void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
- void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ void getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
+ void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
void unregisterMutationObserver(MutationObserverRegistration*);
void registerTransientMutationObserver(MutationObserverRegistration*);
void unregisterTransientMutationObserver(MutationObserverRegistration*);
void notifyMutationObserversNodeWillDetach();
- virtual void registerScopedHTMLStyleChild();
- virtual void unregisterScopedHTMLStyleChild();
- size_t numberOfScopedHTMLStyleChildren() const;
-
unsigned connectedSubframeCount() const;
void incrementConnectedSubframeCount(unsigned amount = 1);
void decrementConnectedSubframeCount(unsigned amount = 1);
void updateAncestorConnectedSubframeCountForRemoval() const;
void updateAncestorConnectedSubframeCountForInsertion() const;
- PassRefPtr<NodeList> getDestinationInsertionPoints();
+ PassRefPtrWillBeRawPtr<StaticNodeList> getDestinationInsertionPoints();
void setAlreadySpellChecked(bool flag) { setFlag(flag, AlreadySpellCheckedFlag); }
bool isAlreadySpellChecked() { return getFlag(AlreadySpellCheckedFlag); }
+ bool isFinishedParsingChildren() const { return getFlag(IsFinishedParsingChildrenFlag); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ unsigned lengthOfContents() const;
+
private:
enum NodeFlags {
- IsTextFlag = 1,
- IsContainerFlag = 1 << 1,
- IsElementFlag = 1 << 2,
- IsHTMLFlag = 1 << 3,
- IsSVGFlag = 1 << 4,
-
- ChildNeedsDistributionRecalc = 1 << 5,
- ChildNeedsStyleRecalcFlag = 1 << 6,
- InDocumentFlag = 1 << 7,
+ HasRareDataFlag = 1,
+
+ // Node type flags. These never change once created.
+ IsTextFlag = 1 << 1,
+ IsContainerFlag = 1 << 2,
+ IsElementFlag = 1 << 3,
+ IsHTMLFlag = 1 << 4,
+ IsSVGFlag = 1 << 5,
+ IsDocumentFragmentFlag = 1 << 6,
+ IsInsertionPointFlag = 1 << 7,
+
+ // Changes based on if the element should be treated like a link,
+ // ex. When setting the href attribute on an <a>.
IsLinkFlag = 1 << 8,
- IsUserActionElement = 1 << 9,
- HasRareDataFlag = 1 << 10,
- IsDocumentFragmentFlag = 1 << 11,
-
- // These bits are used by derived classes, pulled up here so they can
- // be stored in the same memory word as the Node bits above.
- IsParsingChildrenFinishedFlag = 1 << 12, // Element
- HasSVGRareDataFlag = 1 << 13, // SVGElement
- StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
+ // Changes based on :hover, :active and :focus state.
+ IsUserActionElementFlag = 1 << 9,
- SelfOrAncestorHasDirAutoFlag = 1 << 16,
+ // Tree state flags. These change when the element is added/removed
+ // from a DOM tree.
+ InDocumentFlag = 1 << 10,
+ IsInShadowTreeFlag = 1 << 11,
- HasNameOrIsEditingTextFlag = 1 << 17,
+ // Set by the parser when the children are done parsing.
+ IsFinishedParsingChildrenFlag = 1 << 12,
- InNamedFlowFlag = 1 << 18,
- HasSyntheticAttrChildNodesFlag = 1 << 19,
- HasCustomStyleCallbacksFlag = 1 << 20,
- HasScopedHTMLStyleChildFlag = 1 << 21,
- HasEventTargetDataFlag = 1 << 22,
- V8CollectableDuringMinorGCFlag = 1 << 23,
- IsInsertionPointFlag = 1 << 24,
- IsInShadowTreeFlag = 1 << 25,
+ // Flags related to recalcStyle.
+ SVGFilterNeedsLayerUpdateFlag = 1 << 13,
+ HasCustomStyleCallbacksFlag = 1 << 14,
+ ChildNeedsStyleInvalidationFlag = 1 << 15,
+ NeedsStyleInvalidationFlag = 1 << 16,
+ ChildNeedsDistributionRecalcFlag = 1 << 17,
+ ChildNeedsStyleRecalcFlag = 1 << 18,
+ StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
- NotifyRendererWithIdenticalStyles = 1 << 26,
+ CustomElementFlag = 1 << 21,
+ CustomElementUpgradedFlag = 1 << 22,
- CustomElement = 1 << 27,
- CustomElementUpgraded = 1 << 28,
+ HasNameOrIsEditingTextFlag = 1 << 23,
+ HasWeakReferencesFlag = 1 << 24,
+ V8CollectableDuringMinorGCFlag = 1 << 25,
+ HasSyntheticAttrChildNodesFlag = 1 << 26,
+ HasEventTargetDataFlag = 1 << 27,
+ AlreadySpellCheckedFlag = 1 << 28,
- AlreadySpellCheckedFlag = 1 << 29,
+ // HTML dir=auto.
+ SelfOrAncestorHasDirAutoFlag = 1 << 29,
- DefaultNodeFlags = IsParsingChildrenFinishedFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange
+ DefaultNodeFlags = IsFinishedParsingChildrenFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange
};
- // 3 bits remaining.
+ // 2 bits remaining.
bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
- void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
- void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
- void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
+ void setFlag(bool f, NodeFlags mask) { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
+ void setFlag(NodeFlags mask) { m_nodeFlags |= mask; }
+ void clearFlag(NodeFlags mask) { m_nodeFlags &= ~mask; }
protected:
enum ConstructionType {
@@ -767,43 +753,28 @@ protected:
CreateEditingText = CreateText | HasNameOrIsEditingTextFlag,
};
- Node(TreeScope* treeScope, ConstructionType type)
- : m_nodeFlags(type)
- , m_parentOrShadowHostNode(0)
- , m_treeScope(treeScope)
- , m_previous(0)
- , m_next(0)
- {
- ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot);
- ScriptWrappable::init(this);
- if (m_treeScope)
- m_treeScope->guardRef();
-
-#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
- trackForDebugging();
-#endif
- InspectorCounters::incrementCounter(InspectorCounters::NodeCounter);
- }
+ Node(TreeScope*, ConstructionType);
virtual void didMoveToNewDocument(Document& oldDocument);
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
-
static void reattachWhitespaceSiblings(Text* start);
+#if !ENABLE(OILPAN)
void willBeDeletedFromDocument();
+#endif
bool hasRareData() const { return getFlag(HasRareDataFlag); }
NodeRareData* rareData() const;
NodeRareData& ensureRareData();
+#if !ENABLE(OILPAN)
void clearRareData();
void clearEventTargetData();
+#endif
void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
- Document* documentInternal() const { return treeScope().documentScope(); }
void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
// isTreeScopeInitialized() can be false
@@ -813,8 +784,11 @@ protected:
void markAncestorsWithChildNeedsStyleRecalc();
+ void setIsFinishedParsingChildren(bool value) { setFlag(value, IsFinishedParsingChildrenFlag); }
+
private:
friend class TreeShared<Node>;
+ friend class WeakNodeMap;
virtual PseudoId customPseudoId() const
{
@@ -822,7 +796,11 @@ private:
return NOPSEUDO;
}
+ unsigned styledSubtreeSize() const;
+
+#if !ENABLE(OILPAN)
void removedLastRef();
+#endif
bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
enum EditableLevel { Editable, RichlyEditable };
@@ -842,42 +820,24 @@ private:
virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO);
- Element* ancestorElement() const;
-
void trackForDebugging();
- Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry();
- HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* mutationObserverRegistry();
+ WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientMutationObserverRegistry();
- mutable uint32_t m_nodeFlags;
- ContainerNode* m_parentOrShadowHostNode;
- TreeScope* m_treeScope;
- Node* m_previous;
- Node* m_next;
+ uint32_t m_nodeFlags;
+ RawPtrWillBeMember<ContainerNode> m_parentOrShadowHostNode;
+ RawPtrWillBeMember<TreeScope> m_treeScope;
+ RawPtrWillBeMember<Node> m_previous;
+ RawPtrWillBeMember<Node> m_next;
// When a node has rare data we move the renderer into the rare data.
union DataUnion {
DataUnion() : m_renderer(0) { }
RenderObject* m_renderer;
NodeRareDataBase* m_rareData;
} m_data;
-
-protected:
- bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
- void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
- void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
-
- bool hasSVGRareData() const { return getFlag(HasSVGRareDataFlag); }
- void setHasSVGRareData() { setFlag(HasSVGRareDataFlag); }
- void clearHasSVGRareData() { clearFlag(HasSVGRareDataFlag); }
};
-// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs()
-inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
-{
- if (!url.isNull())
- urls.add(url);
-}
-
inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
{
ASSERT(isMainThread());
@@ -909,9 +869,9 @@ inline void Node::lazyReattachIfAttached()
markAncestorsWithChildNeedsStyleRecalc();
}
-inline bool shouldRecalcStyle(StyleRecalcChange change, const Node* node)
+inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change)
{
- return change >= Inherit || node->childNeedsStyleRecalc() || node->needsStyleRecalc();
+ return change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc();
}
inline bool isTreeScopeRoot(const Node* node)
@@ -925,16 +885,7 @@ inline bool isTreeScopeRoot(const Node& node)
}
// Allow equality comparisons of Nodes by reference or pointer, interchangeably.
-inline bool operator==(const Node& a, const Node& b) { return &a == &b; }
-inline bool operator==(const Node& a, const Node* b) { return &a == b; }
-inline bool operator==(const Node* a, const Node& b) { return a == &b; }
-inline bool operator!=(const Node& a, const Node& b) { return !(a == b); }
-inline bool operator!=(const Node& a, const Node* b) { return !(a == b); }
-inline bool operator!=(const Node* a, const Node& b) { return !(a == b); }
-inline bool operator==(const PassRefPtr<Node>& a, const Node& b) { return a.get() == &b; }
-inline bool operator==(const Node& a, const PassRefPtr<Node>& b) { return &a == b.get(); }
-inline bool operator!=(const PassRefPtr<Node>& a, const Node& b) { return !(a == b); }
-inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a == b); }
+DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(Node)
#define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
@@ -946,10 +897,19 @@ inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a ==
template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node))
+#define DECLARE_NODE_FACTORY(T) \
+ static PassRefPtrWillBeRawPtr<T> create(Document&)
+#define DEFINE_NODE_FACTORY(T) \
+PassRefPtrWillBeRawPtr<T> T::create(Document& document) \
+{ \
+ return adoptRefWillBeNoop(new T(document)); \
+}
+
} // namespace WebCore
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
+void showNode(const WebCore::Node*);
void showTree(const WebCore::Node*);
void showNodePath(const WebCore::Node*);
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Node.idl b/chromium/third_party/WebKit/Source/core/dom/Node.idl
index c67bbebddf5..4536b1f0e07 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Node.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Node.idl
@@ -36,11 +36,11 @@
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
- [PerWorldBindings] readonly attribute DOMString nodeName;
+ readonly attribute DOMString nodeName;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, CustomElementCallbacks] attribute DOMString nodeValue;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString nodeValue;
- [PerWorldBindings] readonly attribute unsigned short nodeType;
+ readonly attribute unsigned short nodeType;
[PerWorldBindings] readonly attribute Node parentNode;
[PerWorldBindings] readonly attribute NodeList childNodes;
[PerWorldBindings] readonly attribute Node firstChild;
@@ -49,28 +49,23 @@
[PerWorldBindings] readonly attribute Node nextSibling;
[PerWorldBindings] readonly attribute Document ownerDocument;
- [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node insertBefore(Node newChild, Node refChild);
- [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node replaceChild(Node newChild, Node oldChild);
- [Custom, CustomElementCallbacks, PerWorldBindings, RaisesException] Node removeChild(Node oldChild);
- [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node appendChild(Node newChild);
+ [Custom, CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Node insertBefore(Node newChild, Node refChild);
+ [Custom, CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Node replaceChild(Node newChild, Node oldChild);
+ [Custom, CustomElementCallbacks, RaisesException] Node removeChild(Node oldChild);
+ [Custom, CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Node appendChild(Node newChild);
- boolean hasChildNodes();
- [CustomElementCallbacks, PerWorldBindings]
- Node cloneNode(optional boolean deep);
+ [ImplementedAs=hasChildren] boolean hasChildNodes();
+ [CustomElementCallbacks] Node cloneNode(optional boolean deep);
[CustomElementCallbacks] void normalize();
// Introduced in DOM Level 2:
- [MeasureAs=NodeIsSupported] boolean isSupported([Default=Undefined] optional DOMString feature,
- [TreatNullAs=NullString,Default=Undefined] optional DOMString version); // Removed in DOM4.
-
- [TreatReturnedNullStringAs=Null, PerWorldBindings, MeasureAs=NodeNamespaceURI] readonly attribute DOMString namespaceURI; // Moved to Element and Attr in DOM4.
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, RaisesException=Setter, MeasureAs=NodePrefix] attribute DOMString prefix; // Moved to Element and Attr in DOM4.
- [TreatReturnedNullStringAs=Null, PerWorldBindings, MeasureAs=NodeLocalName] readonly attribute DOMString localName; // Moved to Element and Attr in DOM4.
+ [TreatReturnedNullStringAs=Null, MeasureAs=NodeNamespaceURI] readonly attribute DOMString namespaceURI; // Moved to Element and Attr in DOM4.
+ [TreatReturnedNullStringAs=Null, MeasureAs=NodeLocalName] readonly attribute DOMString localName; // Moved to Element and Attr in DOM4.
// Introduced in DOM Level 3:
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString baseURI;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString baseURI;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, CustomElementCallbacks] attribute DOMString textContent;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, TreatUndefinedAs=NullString, CustomElementCallbacks] attribute DOMString textContent;
[MeasureAs=NodeIsSameNode] boolean isSameNode([Default=Undefined] optional Node other); // Removed in DOM4.
boolean isEqualNode(Node other);
@@ -89,7 +84,7 @@
unsigned short compareDocumentPosition(Node other);
// Introduced in DOM4
- [ImplementedAs=bindingsContains] boolean contains(Node other);
+ boolean contains(Node other);
// IE extensions
[PerWorldBindings] readonly attribute Element parentElement;
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp
index 6fedc7a0f1e..f207378e1c7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp
@@ -27,10 +27,15 @@
namespace WebCore {
-short NodeFilter::acceptNode(ScriptState* state, Node* node) const
+short NodeFilter::acceptNode(Node* node, ExceptionState& exceptionState) const
{
// cast to short silences "enumeral and non-enumeral types in return" warning
- return m_condition ? m_condition->acceptNode(state, node) : static_cast<short>(FILTER_ACCEPT);
+ return m_condition ? m_condition->acceptNode(node, exceptionState) : static_cast<short>(FILTER_ACCEPT);
+}
+
+void NodeFilter::trace(Visitor* visitor)
+{
+ visitor->trace(m_condition);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h
index a811a1325bd..a52520e3806 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h
@@ -27,11 +27,12 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/NodeFilterCondition.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class NodeFilter : public RefCounted<NodeFilter>, public ScriptWrappable {
+class NodeFilter FINAL : public RefCountedWillBeGarbageCollectedFinalized<NodeFilter>, public ScriptWrappable {
public:
/**
* The following constants are returned by the acceptNode()
@@ -65,25 +66,27 @@ public:
SHOW_NOTATION = 0x00000800
};
- static PassRefPtr<NodeFilter> create(PassRefPtr<NodeFilterCondition> condition)
+ static PassRefPtrWillBeRawPtr<NodeFilter> create(PassRefPtrWillBeRawPtr<NodeFilterCondition> condition)
{
- return adoptRef(new NodeFilter(condition));
+ return adoptRefWillBeNoop(new NodeFilter(condition));
}
- static PassRefPtr<NodeFilter> create()
+ static PassRefPtrWillBeRawPtr<NodeFilter> create()
{
- return adoptRef(new NodeFilter());
+ return adoptRefWillBeNoop(new NodeFilter());
}
- short acceptNode(ScriptState*, Node*) const;
+ short acceptNode(Node*, ExceptionState&) const;
- void setCondition(PassRefPtr<NodeFilterCondition> condition)
+ void setCondition(PassRefPtrWillBeRawPtr<NodeFilterCondition> condition)
{
m_condition = condition;
}
+ void trace(Visitor*);
+
private:
- explicit NodeFilter(PassRefPtr<NodeFilterCondition> condition) : m_condition(condition)
+ explicit NodeFilter(PassRefPtrWillBeRawPtr<NodeFilterCondition> condition) : m_condition(condition)
{
ScriptWrappable::init(this);
}
@@ -93,7 +96,7 @@ private:
ScriptWrappable::init(this);
}
- RefPtr<NodeFilterCondition> m_condition;
+ RefPtrWillBeMember<NodeFilterCondition> m_condition;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl
index 58ac22e9407..7d52e408bcd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl
@@ -19,7 +19,8 @@
*/
[
- DependentLifetime
+ DependentLifetime,
+ WillBeGarbageCollected,
] interface NodeFilter {
// Constants returned by acceptNode
const short FILTER_ACCEPT = 1;
@@ -41,7 +42,6 @@
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x00000400;
const unsigned long SHOW_NOTATION = 0x00000800;
- [CallWith=ScriptState] short acceptNode([Default=Undefined] optional Node n);
+ [RaisesException] short acceptNode([Default=Undefined] optional Node n);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp
index aee9f8029ac..18a99b42181 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-short NodeFilterCondition::acceptNode(ScriptState*, Node*) const
+short NodeFilterCondition::acceptNode(Node*, ExceptionState&) const
{
return NodeFilter::FILTER_ACCEPT;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h
index 4c838e9e094..d1248f3b5e1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h
@@ -25,18 +25,21 @@
#ifndef NodeFilterCondition_h
#define NodeFilterCondition_h
-#include "bindings/v8/ScriptState.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
- class Node;
+class ExceptionState;
+class Node;
- class NodeFilterCondition : public RefCounted<NodeFilterCondition> {
- public:
- virtual ~NodeFilterCondition() { }
- virtual short acceptNode(ScriptState*, Node*) const = 0;
- };
+class NodeFilterCondition : public RefCountedWillBeGarbageCollectedFinalized<NodeFilterCondition> {
+public:
+ virtual ~NodeFilterCondition() { }
+ virtual short acceptNode(Node*, ExceptionState&) const = 0;
+
+ virtual void trace(Visitor*) { }
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp
index 35c912fe65a..fd2f9737119 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp
@@ -26,7 +26,6 @@
#include "core/dom/NodeIterator.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
@@ -37,7 +36,7 @@ NodeIterator::NodePointer::NodePointer()
{
}
-NodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b)
+NodeIterator::NodePointer::NodePointer(PassRefPtrWillBeRawPtr<Node> n, bool b)
: node(n)
, isPointerBeforeNode(b)
{
@@ -72,10 +71,9 @@ bool NodeIterator::NodePointer::moveToPrevious(Node* root)
return node;
}
-NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
- : Traversal(rootNode, whatToShow, filter)
+NodeIterator::NodeIterator(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
+ : NodeIteratorBase(rootNode, whatToShow, filter)
, m_referenceNode(root(), true)
- , m_detached(false)
{
ScriptWrappable::init(this);
root()->document().attachNodeIterator(this);
@@ -83,26 +81,23 @@ NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassR
NodeIterator::~NodeIterator()
{
+#if !ENABLE(OILPAN)
root()->document().detachNodeIterator(this);
+#endif
}
-PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NodeIterator::nextNode(ExceptionState& exceptionState)
{
- if (m_detached) {
- exceptionState.throwDOMException(InvalidStateError, "The iterator is detached.");
- return 0;
- }
-
- RefPtr<Node> result;
+ RefPtrWillBeRawPtr<Node> result = nullptr;
m_candidateNode = m_referenceNode;
while (m_candidateNode.moveToNext(root())) {
// NodeIterators treat the DOM tree as a flat list of nodes.
// In other words, FILTER_REJECT does not pass over descendants
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
- RefPtr<Node> provisionalResult = m_candidateNode.node;
- bool nodeWasAccepted = acceptNode(state, provisionalResult.get()) == NodeFilter::FILTER_ACCEPT;
- if (state && state->hadException())
+ RefPtrWillBeRawPtr<Node> provisionalResult = m_candidateNode.node;
+ bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionState) == NodeFilter::FILTER_ACCEPT;
+ if (exceptionState.hadException())
break;
if (nodeWasAccepted) {
m_referenceNode = m_candidateNode;
@@ -115,23 +110,18 @@ PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionState& exce
return result.release();
}
-PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NodeIterator::previousNode(ExceptionState& exceptionState)
{
- if (m_detached) {
- exceptionState.throwDOMException(InvalidStateError, "The iterator is detached.");
- return 0;
- }
-
- RefPtr<Node> result;
+ RefPtrWillBeRawPtr<Node> result = nullptr;
m_candidateNode = m_referenceNode;
while (m_candidateNode.moveToPrevious(root())) {
// NodeIterators treat the DOM tree as a flat list of nodes.
// In other words, FILTER_REJECT does not pass over descendants
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
- RefPtr<Node> provisionalResult = m_candidateNode.node;
- bool nodeWasAccepted = acceptNode(state, provisionalResult.get()) == NodeFilter::FILTER_ACCEPT;
- if (state && state->hadException())
+ RefPtrWillBeRawPtr<Node> provisionalResult = m_candidateNode.node;
+ bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionState) == NodeFilter::FILTER_ACCEPT;
+ if (exceptionState.hadException())
break;
if (nodeWasAccepted) {
m_referenceNode = m_candidateNode;
@@ -146,9 +136,7 @@ PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionState&
void NodeIterator::detach()
{
- root()->document().detachNodeIterator(this);
- m_detached = true;
- m_referenceNode.node.clear();
+ // This is now a no-op as per the DOM specification.
}
void NodeIterator::nodeWillBeRemoved(Node& removedNode)
@@ -159,14 +147,13 @@ void NodeIterator::nodeWillBeRemoved(Node& removedNode)
void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenceNode) const
{
- ASSERT(!m_detached);
ASSERT(root()->document() == removedNode.document());
// Iterator is not affected if the removed node is the reference node and is the root.
// or if removed node is not the reference node, or the ancestor of the reference node.
if (!removedNode.isDescendantOf(root()))
return;
- bool willRemoveReferenceNode = removedNode == referenceNode.node;
+ bool willRemoveReferenceNode = removedNode == referenceNode.node.get();
bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(&removedNode);
if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
return;
@@ -224,5 +211,11 @@ void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenc
}
}
+void NodeIterator::trace(Visitor* visitor)
+{
+ visitor->trace(m_referenceNode);
+ visitor->trace(m_candidateNode);
+ NodeIteratorBase::trace(visitor);
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h
index 1f06a57c3e4..c2c5de1b05f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h
@@ -27,7 +27,8 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/NodeFilter.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -35,16 +36,18 @@ namespace WebCore {
class ExceptionState;
-class NodeIterator : public ScriptWrappable, public RefCounted<NodeIterator>, public Traversal {
+class NodeIterator FINAL : public RefCountedWillBeGarbageCollectedFinalized<NodeIterator>, public ScriptWrappable, public NodeIteratorBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(NodeIterator);
public:
- static PassRefPtr<NodeIterator> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
+ static PassRefPtrWillBeRawPtr<NodeIterator> create(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
{
- return adoptRef(new NodeIterator(rootNode, whatToShow, filter));
+ return adoptRefWillBeNoop(new NodeIterator(rootNode, whatToShow, filter));
}
- ~NodeIterator();
- PassRefPtr<Node> nextNode(ScriptState*, ExceptionState&);
- PassRefPtr<Node> previousNode(ScriptState*, ExceptionState&);
+ virtual ~NodeIterator();
+
+ PassRefPtrWillBeRawPtr<Node> nextNode(ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> previousNode(ExceptionState&);
void detach();
Node* referenceNode() const { return m_referenceNode.node.get(); }
@@ -53,24 +56,34 @@ public:
// This function is called before any node is removed from the document tree.
void nodeWillBeRemoved(Node&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
+ NodeIterator(PassRefPtrWillBeRawPtr<Node>, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>);
- struct NodePointer {
- RefPtr<Node> node;
- bool isPointerBeforeNode;
+ class NodePointer {
+ DISALLOW_ALLOCATION();
+ public:
NodePointer();
- NodePointer(PassRefPtr<Node>, bool);
+ NodePointer(PassRefPtrWillBeRawPtr<Node>, bool);
+
void clear();
bool moveToNext(Node* root);
bool moveToPrevious(Node* root);
+
+ RefPtrWillBeMember<Node> node;
+ bool isPointerBeforeNode;
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(node);
+ }
};
void updateForNodeRemoval(Node& nodeToBeRemoved, NodePointer&) const;
NodePointer m_referenceNode;
NodePointer m_candidateNode;
- bool m_detached;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl
index 9c636c4bdd6..ef46701e401 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl
@@ -18,19 +18,19 @@
* Boston, MA 02110-1301, USA.
*/
-// Introduced in DOM Level 2:
+// Introduced in DOM Level 2
[
- SetReference(NodeFilter filter)
+ SetWrapperReferenceTo(NodeFilter filter),
+ WillBeGarbageCollected,
] interface NodeIterator {
readonly attribute Node root;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter filter;
- readonly attribute boolean expandEntityReferences;
+ [DeprecateAs=NodeIteratorExpandEntityReferences] readonly attribute boolean expandEntityReferences;
readonly attribute Node referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
- [CallWith=ScriptState, RaisesException] Node nextNode();
- [CallWith=ScriptState, RaisesException] Node previousNode();
- void detach();
+ [RaisesException] Node nextNode();
+ [RaisesException] Node previousNode();
+ [DeprecateAs=NodeIteratorDetach] void detach();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/Traversal.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp
index a9262cc934d..8899fc88dce 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Traversal.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp
@@ -23,21 +23,22 @@
*/
#include "config.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
+#include "bindings/v8/ExceptionState.h"
#include "core/dom/Node.h"
#include "core/dom/NodeFilter.h"
namespace WebCore {
-Traversal::Traversal(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter)
+NodeIteratorBase::NodeIteratorBase(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> nodeFilter)
: m_root(rootNode)
, m_whatToShow(whatToShow)
, m_filter(nodeFilter)
{
}
-short Traversal::acceptNode(ScriptState* state, Node* node) const
+short NodeIteratorBase::acceptNode(Node* node, ExceptionState& exceptionState) const
{
// The bit twiddling here is done to map DOM node types, which are given as integers from
// 1 through 14, to whatToShow bit masks.
@@ -45,7 +46,13 @@ short Traversal::acceptNode(ScriptState* state, Node* node) const
return NodeFilter::FILTER_SKIP;
if (!m_filter)
return NodeFilter::FILTER_ACCEPT;
- return m_filter->acceptNode(state, node);
+ return m_filter->acceptNode(node, exceptionState);
+}
+
+void NodeIteratorBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_root);
+ visitor->trace(m_filter);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Traversal.h b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
index 58ef1524eef..18cc6aeb98f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Traversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
@@ -22,37 +22,42 @@
*
*/
-#ifndef Traversal_h
-#define Traversal_h
+#ifndef NodeIteratorBase_h
+#define NodeIteratorBase_h
-#include "bindings/v8/ScriptState.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
- class Node;
- class NodeFilter;
-
- class Traversal {
- public:
- Node* root() const { return m_root.get(); }
- unsigned whatToShow() const { return m_whatToShow; }
- NodeFilter* filter() const { return m_filter.get(); }
- // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
- // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
- // Document.createNodeIterator() and Document.createTreeWalker().
- bool expandEntityReferences() const { return false; }
-
- protected:
- Traversal(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
- short acceptNode(ScriptState*, Node*) const;
-
- private:
- RefPtr<Node> m_root;
- unsigned m_whatToShow;
- RefPtr<NodeFilter> m_filter;
- };
+class ExceptionState;
+class Node;
+class NodeFilter;
+
+class NodeIteratorBase : public WillBeGarbageCollectedMixin {
+public:
+ virtual ~NodeIteratorBase() { }
+
+ Node* root() const { return m_root.get(); }
+ unsigned whatToShow() const { return m_whatToShow; }
+ NodeFilter* filter() const { return m_filter.get(); }
+ // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
+ // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
+ // Document.createNodeIterator() and Document.createTreeWalker().
+ bool expandEntityReferences() const { return false; }
+
+ virtual void trace(Visitor*);
+
+protected:
+ NodeIteratorBase(PassRefPtrWillBeRawPtr<Node>, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>);
+ short acceptNode(Node*, ExceptionState&) const;
+
+private:
+ RefPtrWillBeMember<Node> m_root;
+ unsigned m_whatToShow;
+ RefPtrWillBeMember<NodeFilter> m_filter;
+};
} // namespace WebCore
-#endif // Traversal_h
+#endif // NodeIteratorBase_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeList.h b/chromium/third_party/WebKit/Source/core/dom/NodeList.h
index 1d77043f3f8..1b1643898cb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeList.h
@@ -25,25 +25,27 @@
#define NodeList_h
#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
namespace WebCore {
class Node;
-class NodeList : public ScriptWrappable, public RefCounted<NodeList> {
+class NodeList : public RefCountedWillBeGarbageCollectedFinalized<NodeList>, public ScriptWrappable {
public:
virtual ~NodeList() { }
// DOM methods & attributes for NodeList
virtual unsigned length() const = 0;
virtual Node* item(unsigned index) const = 0;
- virtual Node* namedItem(const AtomicString&) const = 0;
// Other methods (not part of DOM)
- virtual bool isLiveNodeList() const { return false; }
- void anonymousNamedGetter(const AtomicString&, bool&, RefPtr<Node>&, bool&, unsigned&);
+ virtual bool isEmptyNodeList() const { return false; }
+ virtual bool isChildNodeList() const { return false; }
+
+ virtual Node* virtualOwnerNode() const { return 0; }
+
+ virtual void trace(Visitor*) { }
protected:
NodeList()
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeList.idl b/chromium/third_party/WebKit/Source/core/dom/NodeList.idl
index 19ccec64c87..66cc82045c8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeList.idl
@@ -19,14 +19,10 @@
*/
[
- Custom=VisitDOMWrapper,
DependentLifetime,
+ SetWrapperReferenceFrom=virtualOwnerNode,
+ WillBeGarbageCollected,
] interface NodeList {
-
getter Node item(unsigned long index);
- [ImplementedAs=anonymousNamedGetter, OverrideBuiltins, NotEnumerable] getter (Node or unsigned long) (DOMString name);
-
readonly attribute unsigned long length;
-
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp
index bbd863e8c68..e8ea37076c2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp
@@ -30,14 +30,69 @@
#include "config.h"
#include "core/dom/NodeRareData.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementRareData.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
struct SameSizeAsNodeRareData {
- unsigned m_bitfields : 20;
- void* m_pointer[3];
+ void* m_pointer[2];
+ OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData;
+ unsigned m_bitfields;
};
COMPILE_ASSERT(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData), NodeRareDataShouldStaySmall);
+void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
+{
+ NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
+ for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it)
+ it->value->invalidateCacheForAttribute(attrName);
+
+ if (attrName)
+ return;
+
+ TagCollectionCacheNS::iterator tagCacheEnd = m_tagCollectionCacheNS.end();
+ for (TagCollectionCacheNS::iterator it = m_tagCollectionCacheNS.begin(); it != tagCacheEnd; ++it)
+ it->value->invalidateCache();
+}
+
+void NodeListsNodeData::trace(Visitor* visitor)
+{
+ visitor->trace(m_childNodeList);
+ visitor->trace(m_atomicNameCaches);
+ visitor->trace(m_tagCollectionCacheNS);
+}
+
+void NodeRareData::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_mutationObserverData);
+ // Do not keep empty NodeListsNodeData objects around.
+ if (m_nodeLists && m_nodeLists->isEmpty())
+ m_nodeLists.clear();
+ else
+ visitor->trace(m_nodeLists);
+}
+
+void NodeRareData::trace(Visitor* visitor)
+{
+ if (m_isElementRareData)
+ static_cast<ElementRareData*>(this)->traceAfterDispatch(visitor);
+ else
+ traceAfterDispatch(visitor);
+}
+
+void NodeRareData::finalizeGarbageCollectedObject()
+{
+ RELEASE_ASSERT(!renderer());
+ if (m_isElementRareData)
+ static_cast<ElementRareData*>(this)->~ElementRareData();
+ else
+ this->~NodeRareData();
+}
+
+// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
+COMPILE_ASSERT(Page::maxNumberOfFrames < (1 << NodeRareData::ConnectedFrameCountBits), Frame_limit_should_fit_in_rare_data_count);
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h
index 38dd440c6cb..edc3719595f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h
@@ -23,11 +23,13 @@
#define NodeRareData_h
#include "core/dom/ChildNodeList.h"
+#include "core/dom/EmptyNodeList.h"
#include "core/dom/LiveNodeList.h"
#include "core/dom/MutationObserverRegistration.h"
#include "core/dom/QualifiedName.h"
-#include "core/dom/TagNodeList.h"
+#include "core/dom/TagCollection.h"
#include "core/page/Page.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
@@ -40,102 +42,122 @@ class LabelsNodeList;
class RadioNodeList;
class TreeScope;
-class NodeListsNodeData {
- WTF_MAKE_NONCOPYABLE(NodeListsNodeData); WTF_MAKE_FAST_ALLOCATED;
+class NodeListsNodeData FINAL : public NoBaseWillBeGarbageCollectedFinalized<NodeListsNodeData> {
+ WTF_MAKE_NONCOPYABLE(NodeListsNodeData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
void clearChildNodeListCache()
{
+ if (m_childNodeList && m_childNodeList->isChildNodeList())
+ toChildNodeList(m_childNodeList)->invalidateCache();
+ }
+
+ PassRefPtrWillBeRawPtr<ChildNodeList> ensureChildNodeList(ContainerNode& node)
+ {
if (m_childNodeList)
- m_childNodeList->invalidateCache();
+ return toChildNodeList(m_childNodeList);
+ RefPtrWillBeRawPtr<ChildNodeList> list = ChildNodeList::create(node);
+ m_childNodeList = list.get();
+ return list.release();
}
- PassRefPtr<ChildNodeList> ensureChildNodeList(Node* node)
+ PassRefPtrWillBeRawPtr<EmptyNodeList> ensureEmptyChildNodeList(Node& node)
{
if (m_childNodeList)
- return m_childNodeList;
- RefPtr<ChildNodeList> list = ChildNodeList::create(node);
+ return toEmptyNodeList(m_childNodeList);
+ RefPtrWillBeRawPtr<EmptyNodeList> list = EmptyNodeList::create(node);
m_childNodeList = list.get();
return list.release();
}
+#if !ENABLE(OILPAN)
void removeChildNodeList(ChildNodeList* list)
{
ASSERT(m_childNodeList == list);
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
return;
- m_childNodeList = 0;
+ m_childNodeList = nullptr;
}
- template <typename StringType>
- struct NodeListCacheMapEntryHash {
- static unsigned hash(const std::pair<unsigned char, StringType>& entry)
+ void removeEmptyChildNodeList(EmptyNodeList* list)
+ {
+ ASSERT(m_childNodeList == list);
+ if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
+ return;
+ m_childNodeList = nullptr;
+ }
+#endif
+
+ struct NodeListAtomicCacheMapEntryHash {
+ static unsigned hash(const std::pair<unsigned char, StringImpl*>& entry)
{
- return DefaultHash<StringType>::Hash::hash(entry.second) + entry.first;
+ return DefaultHash<StringImpl*>::Hash::hash(entry.second) + entry.first;
}
- static bool equal(const std::pair<unsigned char, StringType>& a, const std::pair<unsigned char, StringType>& b) { return a == b; }
- static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringType>::Hash::safeToCompareToEmptyOrDeleted;
+ static bool equal(const std::pair<unsigned char, StringImpl*>& a, const std::pair<unsigned char, StringImpl*>& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringImpl*>::Hash::safeToCompareToEmptyOrDeleted;
};
- typedef HashMap<std::pair<unsigned char, AtomicString>, LiveNodeListBase*, NodeListCacheMapEntryHash<AtomicString> > NodeListAtomicNameCacheMap;
- typedef HashMap<std::pair<unsigned char, String>, LiveNodeListBase*, NodeListCacheMapEntryHash<String> > NodeListNameCacheMap;
- typedef HashMap<QualifiedName, TagNodeList*> TagNodeListCacheNS;
+ // Oilpan: keep a weak reference to the collection objects.
+ // Explicit object unregistration in a non-Oilpan setting
+ // on object destruction is replaced by the garbage collector
+ // clearing out their weak reference.
+ typedef WillBeHeapHashMap<std::pair<unsigned char, StringImpl*>, RawPtrWillBeWeakMember<LiveNodeListBase>, NodeListAtomicCacheMapEntryHash> NodeListAtomicNameCacheMap;
+ typedef WillBeHeapHashMap<QualifiedName, RawPtrWillBeWeakMember<TagCollection> > TagCollectionCacheNS;
template<typename T>
- PassRefPtr<T> addCacheWithAtomicName(Node* node, CollectionType collectionType, const AtomicString& name)
+ PassRefPtrWillBeRawPtr<T> addCache(ContainerNode& node, CollectionType collectionType, const AtomicString& name)
{
- NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, name), 0);
- if (!result.isNewEntry)
- return static_cast<T*>(result.iterator->value);
+ NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, name), nullptr);
+ if (!result.isNewEntry) {
+#if ENABLE(OILPAN)
+ return static_cast<T*>(result.storedValue->value.get());
+#else
+ return static_cast<T*>(result.storedValue->value);
+#endif
+ }
- RefPtr<T> list = T::create(node, collectionType, name);
- result.iterator->value = list.get();
+ RefPtrWillBeRawPtr<T> list = T::create(node, collectionType, name);
+ result.storedValue->value = list.get();
return list.release();
}
- // FIXME: This function should be renamed since it doesn't have an atomic name.
template<typename T>
- PassRefPtr<T> addCacheWithAtomicName(Node* node, CollectionType collectionType)
+ PassRefPtrWillBeRawPtr<T> addCache(ContainerNode& node, CollectionType collectionType)
{
- NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, starAtom), 0);
- if (!result.isNewEntry)
- return static_cast<T*>(result.iterator->value);
+ NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, starAtom), nullptr);
+ if (!result.isNewEntry) {
+#if ENABLE(OILPAN)
+ return static_cast<T*>(result.storedValue->value.get());
+#else
+ return static_cast<T*>(result.storedValue->value);
+#endif
+ }
- RefPtr<T> list = T::create(node, collectionType);
- result.iterator->value = list.get();
+ RefPtrWillBeRawPtr<T> list = T::create(node, collectionType);
+ result.storedValue->value = list.get();
return list.release();
}
template<typename T>
- T* cacheWithAtomicName(CollectionType collectionType)
+ T* cached(CollectionType collectionType)
{
return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectionType, starAtom)));
}
- template<typename T>
- PassRefPtr<T> addCacheWithName(Node* node, CollectionType collectionType, const String& name)
- {
- NodeListNameCacheMap::AddResult result = m_nameCaches.add(namedNodeListKey(collectionType, name), 0);
- if (!result.isNewEntry)
- return static_cast<T*>(result.iterator->value);
-
- RefPtr<T> list = T::create(node, name);
- result.iterator->value = list.get();
- return list.release();
- }
-
- PassRefPtr<TagNodeList> addCacheWithQualifiedName(Node* node, const AtomicString& namespaceURI, const AtomicString& localName)
+ PassRefPtrWillBeRawPtr<TagCollection> addCache(ContainerNode& node, const AtomicString& namespaceURI, const AtomicString& localName)
{
QualifiedName name(nullAtom, localName, namespaceURI);
- TagNodeListCacheNS::AddResult result = m_tagNodeListCacheNS.add(name, 0);
+ TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name, nullptr);
if (!result.isNewEntry)
- return result.iterator->value;
+ return result.storedValue->value;
- RefPtr<TagNodeList> list = TagNodeList::create(node, namespaceURI, localName);
- result.iterator->value = list.get();
+ RefPtrWillBeRawPtr<TagCollection> list = TagCollection::create(node, namespaceURI, localName);
+ result.storedValue->value = list.get();
return list.release();
}
- void removeCacheWithAtomicName(LiveNodeListBase* list, CollectionType collectionType, const AtomicString& name = starAtom)
+#if !ENABLE(OILPAN)
+ void removeCache(LiveNodeListBase* list, CollectionType collectionType, const AtomicString& name = starAtom)
{
ASSERT(list == m_atomicNameCaches.get(namedNodeListKey(collectionType, name)));
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
@@ -143,32 +165,26 @@ public:
m_atomicNameCaches.remove(namedNodeListKey(collectionType, name));
}
- void removeCacheWithName(LiveNodeListBase* list, CollectionType collectionType, const String& name)
- {
- ASSERT(list == m_nameCaches.get(namedNodeListKey(collectionType, name)));
- if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
- return;
- m_nameCaches.remove(namedNodeListKey(collectionType, name));
- }
-
- void removeCacheWithQualifiedName(LiveNodeList* list, const AtomicString& namespaceURI, const AtomicString& localName)
+ void removeCache(LiveNodeListBase* list, const AtomicString& namespaceURI, const AtomicString& localName)
{
QualifiedName name(nullAtom, localName, namespaceURI);
- ASSERT(list == m_tagNodeListCacheNS.get(name));
+ ASSERT(list == m_tagCollectionCacheNS.get(name));
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
return;
- m_tagNodeListCacheNS.remove(name);
+ m_tagCollectionCacheNS.remove(name);
}
+#endif
- static PassOwnPtr<NodeListsNodeData> create()
+ static PassOwnPtrWillBeRawPtr<NodeListsNodeData> create()
{
- return adoptPtr(new NodeListsNodeData);
+ return adoptPtrWillBeNoop(new NodeListsNodeData);
}
void invalidateCaches(const QualifiedName* attrName = 0);
+
bool isEmpty() const
{
- return m_atomicNameCaches.isEmpty() && m_nameCaches.isEmpty() && m_tagNodeListCacheNS.isEmpty();
+ return !m_childNodeList && m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty();
}
void adoptTreeScope()
@@ -176,76 +192,78 @@ public:
invalidateCaches();
}
- void adoptDocument(Document* oldDocument, Document* newDocument)
+ void adoptDocument(Document& oldDocument, Document& newDocument)
{
- invalidateCaches();
+ ASSERT(oldDocument != newDocument);
- if (oldDocument != newDocument) {
- NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
- for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
- LiveNodeListBase* list = it->value;
- oldDocument->unregisterNodeList(list);
- newDocument->registerNodeList(list);
- }
-
- NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
- for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) {
- LiveNodeListBase* list = it->value;
- oldDocument->unregisterNodeList(list);
- newDocument->registerNodeList(list);
- }
-
- TagNodeListCacheNS::const_iterator tagEnd = m_tagNodeListCacheNS.end();
- for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagEnd; ++it) {
- LiveNodeListBase* list = it->value;
- ASSERT(!list->isRootedAtDocument());
- oldDocument->unregisterNodeList(list);
- newDocument->registerNodeList(list);
- }
+ NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
+ for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
+ LiveNodeListBase* list = it->value;
+ list->didMoveToDocument(oldDocument, newDocument);
+ }
+
+ TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS.end();
+ for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheNS.begin(); it != tagEnd; ++it) {
+ LiveNodeListBase* list = it->value;
+ ASSERT(!list->isRootedAtDocument());
+ list->didMoveToDocument(oldDocument, newDocument);
}
}
+ void trace(Visitor*);
+
private:
NodeListsNodeData()
- : m_childNodeList(0)
+ : m_childNodeList(nullptr)
{ }
- std::pair<unsigned char, AtomicString> namedNodeListKey(CollectionType type, const AtomicString& name)
+ std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name)
{
- return std::pair<unsigned char, AtomicString>(type, name);
+ // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList
+ // is reponsible for removing itself from the cache on deletion.
+ return std::pair<unsigned char, StringImpl*>(type, name.impl());
}
- std::pair<unsigned char, String> namedNodeListKey(CollectionType type, const String& name)
- {
- return std::pair<unsigned char, String>(type, name);
- }
-
- bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node*);
+#if !ENABLE(OILPAN)
+ bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&);
+#endif
- // FIXME: m_childNodeList should be merged into m_atomicNameCaches or at least be shared with HTMLCollection returned by Element::children
- // but it's tricky because invalidateCaches shouldn't invalidate this cache and adoptTreeScope shouldn't call registerNodeList or unregisterNodeList.
- ChildNodeList* m_childNodeList;
+ // Can be a ChildNodeList or an EmptyNodeList.
+ RawPtrWillBeWeakMember<NodeList> m_childNodeList;
NodeListAtomicNameCacheMap m_atomicNameCaches;
- NodeListNameCacheMap m_nameCaches;
- TagNodeListCacheNS m_tagNodeListCacheNS;
+ TagCollectionCacheNS m_tagCollectionCacheNS;
};
-class NodeMutationObserverData {
- WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); WTF_MAKE_FAST_ALLOCATED;
+class NodeMutationObserverData FINAL : public NoBaseWillBeGarbageCollected<NodeMutationObserverData> {
+ WTF_MAKE_NONCOPYABLE(NodeMutationObserverData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- Vector<OwnPtr<MutationObserverRegistration> > registry;
- HashSet<MutationObserverRegistration*> transientRegistry;
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> > registry;
+ WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > transientRegistry;
- static PassOwnPtr<NodeMutationObserverData> create() { return adoptPtr(new NodeMutationObserverData); }
+ static PassOwnPtrWillBeRawPtr<NodeMutationObserverData> create()
+ {
+ return adoptPtrWillBeNoop(new NodeMutationObserverData);
+ }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(registry);
+ visitor->trace(transientRegistry);
+ }
private:
NodeMutationObserverData() { }
};
-class NodeRareData : public NodeRareDataBase {
- WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
+class NodeRareData : public NoBaseWillBeGarbageCollectedFinalized<NodeRareData>, public NodeRareDataBase {
+ WTF_MAKE_NONCOPYABLE(NodeRareData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<NodeRareData> create(RenderObject* renderer) { return adoptPtr(new NodeRareData(renderer)); }
+ static NodeRareData* create(RenderObject* renderer)
+ {
+ return new NodeRareData(renderer);
+ }
void clearNodeLists() { m_nodeLists.clear(); }
NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
@@ -276,31 +294,54 @@ public:
m_connectedFrameCount -= amount;
}
+ bool hasElementFlag(ElementFlags mask) const { return m_elementFlags & mask; }
+ void setElementFlag(ElementFlags mask, bool value) { m_elementFlags = (m_elementFlags & ~mask) | (-(int32_t)value & mask); }
+ void clearElementFlag(ElementFlags mask) { m_elementFlags &= ~mask; }
+
+ bool hasRestyleFlag(DynamicRestyleFlags mask) const { return m_restyleFlags & mask; }
+ void setRestyleFlag(DynamicRestyleFlags mask) { m_restyleFlags |= mask; RELEASE_ASSERT(m_restyleFlags); }
+ bool hasRestyleFlags() const { return m_restyleFlags; }
+ void clearRestyleFlags() { m_restyleFlags = 0; }
+
+ enum {
+ ConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames.
+ };
+
+ void trace(Visitor*);
+
+ void traceAfterDispatch(Visitor*);
+ void finalizeGarbageCollectedObject();
+
protected:
- NodeRareData(RenderObject* renderer)
+ explicit NodeRareData(RenderObject* renderer)
: NodeRareDataBase(renderer)
, m_connectedFrameCount(0)
+ , m_elementFlags(0)
+ , m_restyleFlags(0)
+ , m_isElementRareData(false)
{ }
private:
- unsigned m_connectedFrameCount : 10; // Must fit Page::maxNumberOfFrames.
+ OwnPtrWillBeMember<NodeListsNodeData> m_nodeLists;
+ OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData;
- OwnPtr<NodeListsNodeData> m_nodeLists;
- OwnPtr<NodeMutationObserverData> m_mutationObserverData;
+ unsigned m_connectedFrameCount : ConnectedFrameCountBits;
+ unsigned m_elementFlags : NumberOfElementFlags;
+ unsigned m_restyleFlags : NumberOfDynamicRestyleFlags;
+protected:
+ unsigned m_isElementRareData : 1;
};
-inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node* ownerNode)
+#if !ENABLE(OILPAN)
+inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node& ownerNode)
{
- ASSERT(ownerNode);
- ASSERT(ownerNode->nodeLists() == this);
- if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_nameCaches.size() + m_tagNodeListCacheNS.size() != 1)
+ ASSERT(ownerNode.nodeLists() == this);
+ if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionCacheNS.size() != 1)
return false;
- ownerNode->clearNodeLists();
+ ownerNode.clearNodeLists();
return true;
}
-
-// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
-COMPILE_ASSERT(Page::maxNumberOfFrames < 1024, Frame_limit_should_fit_in_rare_data_count);
+#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h b/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h
index a9487abba62..96b9fab2c72 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h
@@ -27,6 +27,7 @@
#include "core/dom/Node.h"
#include "core/dom/NodeRenderingTraversal.h"
+#include "core/html/HTMLOptGroupElement.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/style/RenderStyle.h"
@@ -34,11 +35,14 @@ namespace WebCore {
inline RenderStyle* Node::renderStyle() const
{
- // Using a ternary here confuses the Solaris Studio 12/12.1/12.2 compilers:
- // Bug is CR 6569194, "Problem with question operator binding in inline function"
if (RenderObject* renderer = this->renderer())
return renderer->style();
- return nonRendererStyle();
+ // <option> and <optgroup> can be styled even though they never get renderers,
+ // so they store their style internally and return it through nonRendererStyle().
+ // We check here explicitly to avoid the virtual call in the common case.
+ if (isHTMLOptGroupElement(*this) || isHTMLOptionElement(this))
+ return nonRendererStyle();
+ return 0;
}
inline RenderStyle* Node::parentRenderStyle() const
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp
deleted file mode 100644
index 2d2b4a4e08d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/dom/NodeRenderingContext.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/ContainerNode.h"
-#include "core/dom/FullscreenElementStack.h"
-#include "core/dom/Node.h"
-#include "core/dom/Text.h"
-#include "core/dom/shadow/InsertionPoint.h"
-#include "core/rendering/FlowThreadController.h"
-#include "core/rendering/RenderFullScreen.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-#include "core/rendering/RenderObject.h"
-#include "core/rendering/RenderText.h"
-#include "core/rendering/RenderView.h"
-
-namespace WebCore {
-
-static bool isRendererReparented(const RenderObject* renderer)
-{
- if (!renderer->node()->isElementNode())
- return false;
- if (renderer->style() && !renderer->style()->flowThread().isEmpty())
- return true;
- if (toElement(renderer->node())->shouldBeReparentedUnderRenderView(renderer->style()))
- return true;
- return false;
-}
-
-RenderObject* NodeRenderingContext::nextRenderer() const
-{
- if (RenderObject* renderer = m_node->renderer())
- return renderer->nextSibling();
-
- Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
- if (element && element->shouldBeReparentedUnderRenderView(m_style.get())) {
- // FIXME: Reparented renderers not in the top layer should probably be
- // ordered in DOM tree order. We don't have a good way to do that yet,
- // since NodeRenderingTraversal isn't aware of reparenting. It's safe to
- // just append for now; it doesn't disrupt the top layer rendering as
- // the layer collection in RenderLayer only requires that top layer
- // renderers are orderered correctly relative to each other.
- if (!element->isInTopLayer())
- return 0;
-
- const Vector<RefPtr<Element> >& topLayerElements = element->document().topLayerElements();
- size_t position = topLayerElements.find(element);
- ASSERT(position != kNotFound);
- for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
- if (RenderObject* renderer = topLayerElements[i]->renderer())
- return renderer;
- }
- return 0;
- }
-
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer->nextRendererForNode(m_node);
-
- // Avoid an O(N^2) walk over the children when reattaching all children of a node.
- if (m_renderingParent && m_renderingParent->needsAttach())
- return 0;
-
- for (Node* sibling = NodeRenderingTraversal::nextSibling(m_node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
- RenderObject* renderer = sibling->renderer();
- if (renderer && !isRendererReparented(renderer))
- return renderer;
- }
-
- return 0;
-}
-
-RenderObject* NodeRenderingContext::previousRenderer() const
-{
- if (RenderObject* renderer = m_node->renderer())
- return renderer->previousSibling();
-
- // FIXME: This doesn't work correctly for reparented elements that are
- // display: none. We'd need to duplicate the logic in nextRenderer, but since
- // nothing needs that yet just assert.
- ASSERT(!m_node->isElementNode() || !toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get()));
-
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer->previousRendererForNode(m_node);
-
- // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
- // however, when I tried adding it, several tests failed.
- for (Node* sibling = NodeRenderingTraversal::previousSibling(m_node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
- RenderObject* renderer = sibling->renderer();
- if (renderer && !isRendererReparented(renderer))
- return renderer;
- }
-
- return 0;
-}
-
-RenderObject* NodeRenderingContext::parentRenderer() const
-{
- if (RenderObject* renderer = m_node->renderer())
- return renderer->parent();
-
- if (m_node->isElementNode() && toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get())) {
- // The parent renderer of reparented elements is the RenderView, but only
- // if the normal parent would have had a renderer.
- // FIXME: This behavior isn't quite right as the spec for top layer
- // only talks about display: none ancestors so putting a <dialog> inside
- // an <optgroup> seems like it should still work even though this check
- // will prevent it.
- if (!m_renderingParent || !m_renderingParent->renderer())
- return 0;
- return m_node->document().renderView();
- }
-
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer;
-
- return m_renderingParent ? m_renderingParent->renderer() : 0;
-}
-
-bool NodeRenderingContext::shouldCreateRenderer() const
-{
- if (!m_renderingParent)
- return false;
- RenderObject* parentRenderer = this->parentRenderer();
- if (!parentRenderer)
- return false;
- if (!parentRenderer->canHaveChildren())
- return false;
- if (!m_renderingParent->childShouldCreateRenderer(*m_node))
- return false;
- return true;
-}
-
-// Check the specific case of elements that are children of regions but are flowed into a flow thread themselves.
-bool NodeRenderingContext::elementInsideRegionNeedsRenderer()
-{
- Element* element = toElement(m_node);
- bool elementInsideRegionNeedsRenderer = false;
- RenderObject* parentRenderer = this->parentRenderer();
- if ((parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderNamedFlowFragmentContainer())
- || (!parentRenderer && element->parentElement() && element->parentElement()->isInsideRegion())) {
-
- if (!m_style)
- m_style = element->styleForRenderer();
-
- elementInsideRegionNeedsRenderer = element->shouldMoveToFlowThread(m_style.get());
-
- // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none.
- if (element->rendererIsNeeded(*m_style))
- element->setIsInsideRegion(true);
- }
-
- return elementInsideRegionNeedsRenderer;
-}
-
-void NodeRenderingContext::moveToFlowThreadIfNeeded()
-{
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return;
-
- Element* element = toElement(m_node);
-
- if (!element->shouldMoveToFlowThread(m_style.get()))
- return;
-
- ASSERT(m_node->document().renderView());
- FlowThreadController* flowThreadController = m_node->document().renderView()->flowThreadController();
- m_parentFlowRenderer = flowThreadController->ensureRenderFlowThreadWithName(m_style->flowThread());
- flowThreadController->registerNamedFlowContentNode(m_node, m_parentFlowRenderer);
-}
-
-void NodeRenderingContext::createRendererForElementIfNeeded()
-{
- ASSERT(!m_node->renderer());
-
- Element* element = toElement(m_node);
-
- element->setIsInsideRegion(false);
-
- if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer())
- return;
-
- if (!m_style)
- m_style = element->styleForRenderer();
-
- moveToFlowThreadIfNeeded();
-
- if (!element->rendererIsNeeded(*m_style))
- return;
-
- RenderObject* newRenderer = element->createRenderer(m_style.get());
- if (!newRenderer)
- return;
-
- RenderObject* parentRenderer = this->parentRenderer();
-
- if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
- newRenderer->destroy();
- return;
- }
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
-
- RenderObject* nextRenderer = this->nextRenderer();
- element->setRenderer(newRenderer);
- newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.
-
- if (FullscreenElementStack::isActiveFullScreenElement(element)) {
- newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &element->document());
- if (!newRenderer)
- return;
- }
-
- // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
- parentRenderer->addChild(newRenderer, nextRenderer);
-}
-
-void NodeRenderingContext::createRendererForTextIfNeeded()
-{
- ASSERT(!m_node->renderer());
-
- Text* textNode = toText(m_node);
-
- if (!shouldCreateRenderer())
- return;
-
- RenderObject* parentRenderer = this->parentRenderer();
-
- if (m_parentDetails.resetStyleInheritance())
- m_style = textNode->document().ensureStyleResolver().defaultStyleForElement();
- else
- m_style = parentRenderer->style();
-
- if (!textNode->textRendererIsNeeded(*this))
- return;
-
- RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
- if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
- newRenderer->destroy();
- return;
- }
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
-
- RenderObject* nextRenderer = this->nextRenderer();
- textNode->setRenderer(newRenderer);
- // Parent takes care of the animations, no need to call setAnimatableStyle.
- newRenderer->setStyle(m_style.release());
- parentRenderer->addChild(newRenderer, nextRenderer);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp
index b30c66aba53..e60ef4f29d7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp
@@ -27,26 +27,31 @@
#include "config.h"
#include "core/dom/NodeRenderingTraversal.h"
+#include "core/HTMLNames.h"
#include "core/dom/PseudoElement.h"
#include "core/dom/shadow/ComposedTreeWalker.h"
+#include "core/rendering/RenderObject.h"
namespace WebCore {
namespace NodeRenderingTraversal {
+static bool isRendererReparented(const RenderObject* renderer)
+{
+ if (!renderer->node()->isElementNode())
+ return false;
+ if (toElement(renderer->node())->isInTopLayer())
+ return true;
+ return false;
+}
+
void ParentDetails::didTraverseInsertionPoint(const InsertionPoint* insertionPoint)
{
if (!m_insertionPoint) {
m_insertionPoint = insertionPoint;
- m_resetStyleInheritance = m_resetStyleInheritance || insertionPoint->resetStyleInheritance();
}
}
-void ParentDetails::didTraverseShadowRoot(const ShadowRoot* root)
-{
- m_resetStyleInheritance = m_resetStyleInheritance || root->resetStyleInheritance();
-}
-
ContainerNode* parent(const Node* node, ParentDetails* details)
{
// FIXME: We should probably ASSERT(!node->document().childNeedsDistributionRecalc()) here, but
@@ -59,6 +64,16 @@ ContainerNode* parent(const Node* node, ParentDetails* details)
return toContainerNode(walker.traverseParent(walker.get(), details));
}
+bool contains(const ContainerNode* container, const Node* node)
+{
+ while (node) {
+ if (node == container)
+ return true;
+ node = NodeRenderingTraversal::parent(node);
+ }
+ return false;
+}
+
Node* nextSibling(const Node* node)
{
ComposedTreeWalker walker(node);
@@ -97,6 +112,149 @@ Node* previousSibling(const Node* node)
return 0;
}
+static Node* lastChild(const Node* node)
+{
+ ComposedTreeWalker walker(node);
+ walker.lastChild();
+ return walker.get();
+}
+
+static Node* pseudoAwarePreviousSibling(const Node* node)
+{
+ Node* previousNode = previousSibling(node);
+ Node* parentNode = parent(node);
+
+ if (parentNode && parentNode->isElementNode() && !previousNode) {
+ if (node->isAfterPseudoElement()) {
+ if (Node* child = lastChild(parentNode))
+ return child;
+ }
+ if (!node->isBeforePseudoElement())
+ return toElement(parentNode)->pseudoElement(BEFORE);
+ }
+ return previousNode;
+}
+
+static Node* pseudoAwareLastChild(const Node* node)
+{
+ if (node->isElementNode()) {
+ const Element* currentElement = toElement(node);
+ Node* last = currentElement->pseudoElement(AFTER);
+ if (last)
+ return last;
+
+ last = lastChild(currentElement);
+ if (!last)
+ last = currentElement->pseudoElement(BEFORE);
+ return last;
+ }
+
+ return lastChild(node);
+}
+
+Node* previous(const Node* node, const Node* stayWithin)
+{
+ if (node == stayWithin)
+ return 0;
+
+ if (Node* previousNode = pseudoAwarePreviousSibling(node)) {
+ while (Node* previousLastChild = pseudoAwareLastChild(previousNode))
+ previousNode = previousLastChild;
+ return previousNode;
+ }
+ return parent(node);
+}
+
+static Node* firstChild(const Node* node)
+{
+ ComposedTreeWalker walker(node);
+ walker.firstChild();
+ return walker.get();
+}
+
+static Node* pseudoAwareNextSibling(const Node* node)
+{
+ Node* parentNode = parent(node);
+ Node* nextNode = nextSibling(node);
+
+ if (parentNode && parentNode->isElementNode() && !nextNode) {
+ if (node->isBeforePseudoElement()) {
+ if (Node* child = firstChild(parentNode))
+ return child;
+ }
+ if (!node->isAfterPseudoElement())
+ return toElement(parentNode)->pseudoElement(AFTER);
+ }
+ return nextNode;
+}
+
+static Node* pseudoAwareFirstChild(const Node* node)
+{
+ if (node->isElementNode()) {
+ const Element* currentElement = toElement(node);
+ Node* first = currentElement->pseudoElement(BEFORE);
+ if (first)
+ return first;
+ first = firstChild(currentElement);
+ if (!first)
+ first = currentElement->pseudoElement(AFTER);
+ return first;
+ }
+
+ return firstChild(node);
+}
+
+Node* next(const Node* node, const Node* stayWithin)
+{
+ if (Node* child = pseudoAwareFirstChild(node))
+ return child;
+ if (node == stayWithin)
+ return 0;
+ if (Node* nextNode = pseudoAwareNextSibling(node))
+ return nextNode;
+ for (Node* parentNode = parent(node); parentNode; parentNode = parent(parentNode)) {
+ if (parentNode == stayWithin)
+ return 0;
+ if (Node* nextNode = pseudoAwareNextSibling(parentNode))
+ return nextNode;
+ }
+ return 0;
+}
+
+RenderObject* nextSiblingRenderer(const Node* node)
+{
+ for (Node* sibling = NodeRenderingTraversal::nextSibling(node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
+ return renderer;
+ }
+ return 0;
+}
+
+RenderObject* previousSiblingRenderer(const Node* node)
+{
+ for (Node* sibling = NodeRenderingTraversal::previousSibling(node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
+ return renderer;
+ }
+ return 0;
+}
+
+RenderObject* nextInTopLayer(const Element* element)
+{
+ if (!element->isInTopLayer())
+ return 0;
+ const WillBeHeapVector<RefPtrWillBeMember<Element> >& topLayerElements = element->document().topLayerElements();
+ size_t position = topLayerElements.find(element);
+ ASSERT(position != kNotFound);
+ for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
+ if (RenderObject* renderer = topLayerElements[i]->renderer())
+ return renderer;
+ }
+ return 0;
+}
+
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h
index 8935ae60a45..0a0bd9c13e5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h
@@ -32,6 +32,7 @@
namespace WebCore {
class InsertionPoint;
+class RenderObject;
namespace NodeRenderingTraversal {
@@ -39,30 +40,31 @@ class ParentDetails {
public:
ParentDetails()
: m_insertionPoint(0)
- , m_resetStyleInheritance(false)
{ }
const InsertionPoint* insertionPoint() const { return m_insertionPoint; }
- bool resetStyleInheritance() const { return m_resetStyleInheritance; }
void didTraverseInsertionPoint(const InsertionPoint*);
- void didTraverseShadowRoot(const ShadowRoot*);
bool operator==(const ParentDetails& other)
{
- return m_insertionPoint == other.m_insertionPoint
- && m_resetStyleInheritance == other.m_resetStyleInheritance;
+ return m_insertionPoint == other.m_insertionPoint;
}
private:
const InsertionPoint* m_insertionPoint;
- bool m_resetStyleInheritance;
};
ContainerNode* parent(const Node*);
ContainerNode* parent(const Node*, ParentDetails*);
+bool contains(const ContainerNode*, const Node*);
Node* nextSibling(const Node*);
Node* previousSibling(const Node*);
+Node* previous(const Node*, const Node* stayWithin);
+Node* next(const Node*, const Node* stayWithin);
+RenderObject* nextSiblingRenderer(const Node*);
+RenderObject* previousSiblingRenderer(const Node*);
+RenderObject* nextInTopLayer(const Element*);
inline ContainerNode* parent(const Node* node)
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp
index 631a8b9c741..6ad5ecd96a8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp
@@ -28,9 +28,8 @@
#include "core/dom/ContainerNode.h"
namespace WebCore {
-namespace NodeTraversal {
-Node* previousIncludingPseudo(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousIncludingPseudo(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -42,7 +41,7 @@ Node* previousIncludingPseudo(const Node& current, const Node* stayWithin)
return current.parentNode();
}
-Node* nextIncludingPseudo(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextIncludingPseudo(const Node& current, const Node* stayWithin)
{
if (Node* next = current.pseudoAwareFirstChild())
return next;
@@ -59,7 +58,7 @@ Node* nextIncludingPseudo(const Node& current, const Node* stayWithin)
return 0;
}
-Node* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -74,7 +73,7 @@ Node* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayW
return 0;
}
-Node* nextAncestorSibling(const Node& current)
+Node* NodeTraversal::nextAncestorSibling(const Node& current)
{
ASSERT(!current.nextSibling());
for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
@@ -84,7 +83,7 @@ Node* nextAncestorSibling(const Node& current)
return 0;
}
-Node* nextAncestorSibling(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextAncestorSibling(const Node& current, const Node* stayWithin)
{
ASSERT(!current.nextSibling());
ASSERT(current != stayWithin);
@@ -97,20 +96,28 @@ Node* nextAncestorSibling(const Node& current, const Node* stayWithin)
return 0;
}
-Node* previous(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::lastWithin(const ContainerNode& current)
+{
+ Node* descendant = current.lastChild();
+ for (Node* child = descendant; child; child = child->lastChild())
+ descendant = child;
+ return descendant;
+}
+
+Node* NodeTraversal::previous(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (current.previousSibling()) {
Node* previous = current.previousSibling();
- while (previous->lastChild())
- previous = previous->lastChild();
+ while (Node* child = previous->lastChild())
+ previous = child;
return previous;
}
return current.parentNode();
}
-Node* previousSkippingChildren(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousSkippingChildren(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -125,15 +132,15 @@ Node* previousSkippingChildren(const Node& current, const Node* stayWithin)
return 0;
}
-Node* nextPostOrder(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextPostOrder(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (!current.nextSibling())
return current.parentNode();
Node* next = current.nextSibling();
- while (next->firstChild())
- next = next->firstChild();
+ while (Node* child = next->firstChild())
+ next = child;
return next;
}
@@ -149,10 +156,10 @@ static Node* previousAncestorSiblingPostOrder(const Node& current, const Node* s
return 0;
}
-Node* previousPostOrder(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousPostOrder(const Node& current, const Node* stayWithin)
{
- if (current.lastChild())
- return current.lastChild();
+ if (Node* lastChild = current.lastChild())
+ return lastChild;
if (current == stayWithin)
return 0;
if (current.previousSibling())
@@ -160,14 +167,4 @@ Node* previousPostOrder(const Node& current, const Node* stayWithin)
return previousAncestorSiblingPostOrder(current, stayWithin);
}
-Node* previousSkippingChildrenPostOrder(const Node& current, const Node* stayWithin)
-{
- if (current == stayWithin)
- return 0;
- if (current.previousSibling())
- return current.previousSibling();
- return previousAncestorSiblingPostOrder(current, stayWithin);
-}
-
-}
-}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h
index 438b0c09a29..e216fa56a2f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h
@@ -4,6 +4,7 @@
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,46 +30,57 @@
namespace WebCore {
-namespace NodeTraversal {
-
-// Does a pre-order traversal of the tree to find the next node after this one.
-// This uses the same order that tags appear in the source file. If the stayWithin
-// argument is non-null, the traversal will stop once the specified node is reached.
-// This can be used to restrict traversal to a particular sub-tree.
-Node* next(const Node&);
-Node* next(const Node&, const Node* stayWithin);
-Node* next(const ContainerNode&);
-Node* next(const ContainerNode&, const Node* stayWithin);
-
-// Like next, but skips children and starts with the next sibling.
-Node* nextSkippingChildren(const Node&);
-Node* nextSkippingChildren(const Node&, const Node* stayWithin);
-Node* nextSkippingChildren(const ContainerNode&);
-Node* nextSkippingChildren(const ContainerNode&, const Node* stayWithin);
-
-// Does a reverse pre-order traversal to find the node that comes before the current one in document order
-Node* previous(const Node&, const Node* stayWithin = 0);
-
-// Like previous, but skips children and starts with the next sibling.
-Node* previousSkippingChildren(const Node&, const Node* stayWithin = 0);
-
-// Like next, but visits parents after their children.
-Node* nextPostOrder(const Node&, const Node* stayWithin = 0);
-
-// Like previous/previousSkippingChildren, but visits parents before their children.
-Node* previousPostOrder(const Node&, const Node* stayWithin = 0);
-Node* previousSkippingChildrenPostOrder(const Node&, const Node* stayWithin = 0);
-
-// Pre-order traversal including the pseudo-elements.
-Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
-
-Node* nextAncestorSibling(const Node&);
-Node* nextAncestorSibling(const Node&, const Node* stayWithin);
+class NodeTraversal {
+public:
+ // Does a pre-order traversal of the tree to find the next node after this one.
+ // This uses the same order that tags appear in the source file. If the stayWithin
+ // argument is non-null, the traversal will stop once the specified node is reached.
+ // This can be used to restrict traversal to a particular sub-tree.
+ static Node* next(const Node& current) { return traverseNextTemplate(current); }
+ static Node* next(const ContainerNode& current) { return traverseNextTemplate(current); }
+ static Node* next(const Node& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
+ static Node* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
+
+ // Like next, but skips children and starts with the next sibling.
+ static Node* nextSkippingChildren(const Node& current) { return traverseNextSkippingChildrenTemplate(current); }
+ static Node* nextSkippingChildren(const ContainerNode& current) { return traverseNextSkippingChildrenTemplate(current); }
+ static Node* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
+ static Node* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
+
+ // Does a reverse pre-order traversal to find the node that comes before the current one in document order
+ static Node* lastWithin(const ContainerNode&);
+ static Node* previous(const Node&, const Node* stayWithin = 0);
+
+ // Like previous, but skips children and starts with the next sibling.
+ static Node* previousSkippingChildren(const Node&, const Node* stayWithin = 0);
+
+ // Like next, but visits parents after their children.
+ static Node* nextPostOrder(const Node&, const Node* stayWithin = 0);
+
+ // Like previous, but visits parents before their children.
+ static Node* previousPostOrder(const Node&, const Node* stayWithin = 0);
+
+ // Pre-order traversal including the pseudo-elements.
+ static Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+
+ static Node* nextAncestorSibling(const Node&);
+ static Node* nextAncestorSibling(const Node&, const Node* stayWithin);
+
+private:
+ template <class NodeType>
+ static Node* traverseNextTemplate(NodeType&);
+ template <class NodeType>
+ static Node* traverseNextTemplate(NodeType&, const Node* stayWithin);
+ template <class NodeType>
+ static Node* traverseNextSkippingChildrenTemplate(NodeType&);
+ template <class NodeType>
+ static Node* traverseNextSkippingChildrenTemplate(NodeType&, const Node* stayWithin);
+};
template <class NodeType>
-inline Node* traverseNextTemplate(NodeType& current)
+inline Node* NodeTraversal::traverseNextTemplate(NodeType& current)
{
if (current.firstChild())
return current.firstChild();
@@ -76,11 +88,9 @@ inline Node* traverseNextTemplate(NodeType& current)
return current.nextSibling();
return nextAncestorSibling(current);
}
-inline Node* next(const Node& current) { return traverseNextTemplate(current); }
-inline Node* next(const ContainerNode& current) { return traverseNextTemplate(current); }
template <class NodeType>
-inline Node* traverseNextTemplate(NodeType& current, const Node* stayWithin)
+inline Node* NodeTraversal::traverseNextTemplate(NodeType& current, const Node* stayWithin)
{
if (current.firstChild())
return current.firstChild();
@@ -90,21 +100,17 @@ inline Node* traverseNextTemplate(NodeType& current, const Node* stayWithin)
return current.nextSibling();
return nextAncestorSibling(current, stayWithin);
}
-inline Node* next(const Node& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
-inline Node* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
template <class NodeType>
-inline Node* traverseNextSkippingChildrenTemplate(NodeType& current)
+inline Node* NodeTraversal::traverseNextSkippingChildrenTemplate(NodeType& current)
{
if (current.nextSibling())
return current.nextSibling();
return nextAncestorSibling(current);
}
-inline Node* nextSkippingChildren(const Node& current) { return traverseNextSkippingChildrenTemplate(current); }
-inline Node* nextSkippingChildren(const ContainerNode& current) { return traverseNextSkippingChildrenTemplate(current); }
template <class NodeType>
-inline Node* traverseNextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+inline Node* NodeTraversal::traverseNextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -112,11 +118,7 @@ inline Node* traverseNextSkippingChildrenTemplate(NodeType& current, const Node*
return current.nextSibling();
return nextAncestorSibling(current, stayWithin);
}
-inline Node* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
-inline Node* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
-}
-
-}
+} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h b/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h
index 8c75ccc8682..7efddfc8aff 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h
@@ -34,28 +34,27 @@ namespace WebCore {
// only want to walk the child list to figure out the index once.
class NodeWithIndex {
public:
- explicit NodeWithIndex(Node* node)
+ explicit NodeWithIndex(Node& node)
: m_node(node)
- , m_haveIndex(false)
+ , m_index(-1)
{
- ASSERT(node);
}
- Node* node() const { return m_node; }
+ Node& node() const { return m_node; }
int index() const
{
- if (!m_haveIndex) {
- m_index = m_node->nodeIndex();
- m_haveIndex = true;
- }
- ASSERT(m_index == static_cast<int>(m_node->nodeIndex()));
+ if (!hasIndex())
+ m_index = m_node.nodeIndex();
+ ASSERT(hasIndex());
+ ASSERT(m_index == static_cast<int>(m_node.nodeIndex()));
return m_index;
}
private:
- Node* m_node;
- mutable bool m_haveIndex;
+ bool hasIndex() const { return m_index >= 0; }
+
+ Node& m_node;
mutable int m_index;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Notation.h b/chromium/third_party/WebKit/Source/core/dom/Notation.h
index 30401f250e4..8ac0250336e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Notation.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Notation.h
@@ -28,11 +28,7 @@ namespace WebCore {
class Notation : public ContainerNode {
private:
- Notation(TreeScope* treeScope) : ContainerNode(treeScope)
- {
- ASSERT_NOT_REACHED();
- ScriptWrappable::init(this);
- }
+ Notation(); // Left unimplemented on purpose.
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ParentNode.h b/chromium/third_party/WebKit/Source/core/dom/ParentNode.h
index 9fb949a35b0..c85feee1d7e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ParentNode.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ParentNode.h
@@ -32,29 +32,44 @@
#define ParentNode_h
#include "core/dom/ContainerNode.h"
+#include "core/dom/ElementTraversal.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class ParentNode {
public:
- static PassRefPtr<HTMLCollection> children(ContainerNode* node)
+ static PassRefPtrWillBeRawPtr<HTMLCollection> children(ContainerNode& node)
{
- return node->children();
+ return node.children();
}
- static Element* firstElementChild(ContainerNode* node)
+ static Element* firstElementChild(ContainerNode& node)
{
- return node->firstElementChild();
+ return ElementTraversal::firstChild(node);
}
- static Element* lastElementChild(ContainerNode* node)
+ static Element* lastElementChild(ContainerNode& node)
{
- return node->lastElementChild();
+ return ElementTraversal::lastChild(node);
}
- static unsigned childElementCount(ContainerNode* node)
+ static unsigned childElementCount(ContainerNode& node)
{
- return node->childElementCount();
+ unsigned count = 0;
+ for (Element* child = ElementTraversal::firstWithin(node); child; child = ElementTraversal::nextSibling(*child))
+ ++count;
+ return count;
+ }
+
+ static PassRefPtrWillBeRawPtr<Element> querySelector(ContainerNode& node, const AtomicString& selectors, ExceptionState& exceptionState)
+ {
+ return node.querySelector(selectors, exceptionState);
+ }
+
+ static PassRefPtrWillBeRawPtr<StaticNodeList> querySelectorAll(ContainerNode& node, const AtomicString& selectors, ExceptionState& exceptionState)
+ {
+ return node.querySelectorAll(selectors, exceptionState);
}
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl b/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl
index 8de54f83d86..dea4bfd282a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl
@@ -1,9 +1,43 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
[
- NoInterfaceObject,
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface ParentNode {
[PerWorldBindings] readonly attribute HTMLCollection children;
[PerWorldBindings] readonly attribute Element firstElementChild;
[PerWorldBindings] readonly attribute Element lastElementChild;
- [PerWorldBindings] readonly attribute unsigned long childElementCount;
-};
+ readonly attribute unsigned long childElementCount;
+ // NodeSelector - Selector API
+ [RaisesException] Element querySelector(DOMString selectors);
+ [RaisesException] NodeList querySelectorAll(DOMString selectors);
+};
diff --git a/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp b/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp
index b448c8bd9bf..d29146cb708 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp
@@ -35,7 +35,7 @@ PendingScript::~PendingScript()
{
}
-PassRefPtr<Element> PendingScript::releaseElementAndClear()
+PassRefPtrWillBeRawPtr<Element> PendingScript::releaseElementAndClear()
{
setScriptResource(0);
m_watchingForLoad = false;
@@ -52,4 +52,9 @@ void PendingScript::notifyFinished(Resource*)
{
}
+void PendingScript::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/PendingScript.h b/chromium/third_party/WebKit/Source/core/dom/PendingScript.h
index a5c5855819c..8237aa9924f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PendingScript.h
+++ b/chromium/third_party/WebKit/Source/core/dom/PendingScript.h
@@ -29,6 +29,7 @@
#include "core/fetch/ResourceClient.h"
#include "core/fetch/ResourceOwner.h"
#include "core/fetch/ScriptResource.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/text/TextPosition.h"
@@ -43,7 +44,8 @@ class ScriptResource;
// A ResourcePtr alone does not prevent the underlying Resource
// from purging its data buffer. This class holds a dummy client open for its
// lifetime in order to guarantee that the data buffer will not be purged.
-class PendingScript : public ResourceOwner<ScriptResource> {
+class PendingScript FINAL : public ResourceOwner<ScriptResource> {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
PendingScript()
: m_watchingForLoad(false)
@@ -90,15 +92,17 @@ public:
Element* element() const { return m_element.get(); }
void setElement(Element* element) { m_element = element; }
- PassRefPtr<Element> releaseElementAndClear();
+ PassRefPtrWillBeRawPtr<Element> releaseElementAndClear();
void setScriptResource(ScriptResource*);
virtual void notifyFinished(Resource*);
+ void trace(Visitor*);
+
private:
bool m_watchingForLoad;
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
TextPosition m_startingPosition; // Only used for inline script tags.
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Position.cpp b/chromium/third_party/WebKit/Source/core/dom/Position.cpp
index f6d9fa115b8..dbff7aa850d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Position.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Position.cpp
@@ -26,8 +26,7 @@
#include "config.h"
#include "core/dom/Position.h"
-#include <stdio.h>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/dom/PositionIterator.h"
#include "core/dom/Text.h"
@@ -35,18 +34,18 @@
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLTableElement.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
-#include "platform/Logging.h"
+#include "core/html/HTMLTableElement.h"
#include "core/rendering/InlineIterator.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderText.h"
+#include "platform/Logging.h"
#include "wtf/text/CString.h"
#include "wtf/unicode/CharacterNames.h"
+#include <stdio.h>
namespace WebCore {
@@ -80,7 +79,7 @@ static Node* previousRenderedEditable(Node* node)
return 0;
}
-Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
+Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffset offset)
: m_anchorNode(anchorNode)
, m_offset(offset.value())
, m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
@@ -89,7 +88,7 @@ Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
}
-Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
+Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType anchorType)
: m_anchorNode(anchorNode)
, m_offset(0)
, m_anchorType(anchorType)
@@ -102,7 +101,7 @@ Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
&& (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
}
-Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
+Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset, AnchorType anchorType)
: m_anchorNode(anchorNode)
, m_offset(offset)
, m_anchorType(anchorType)
@@ -113,7 +112,7 @@ Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorTyp
ASSERT(anchorType == PositionIsOffsetInAnchor);
}
-Position::Position(PassRefPtr<Text> textNode, unsigned offset)
+Position::Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset)
: m_anchorNode(textNode)
, m_offset(static_cast<int>(offset))
, m_anchorType(PositionIsOffsetInAnchor)
@@ -122,7 +121,7 @@ Position::Position(PassRefPtr<Text> textNode, unsigned offset)
ASSERT(m_anchorNode);
}
-void Position::moveToPosition(PassRefPtr<Node> node, int offset)
+void Position::moveToPosition(PassRefPtrWillBeRawPtr<Node> node, int offset)
{
ASSERT(!editingIgnoresContent(node.get()));
ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
@@ -211,15 +210,15 @@ Position Position::parentAnchoredEquivalent() const
// FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
- if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
- return positionInParentBeforeNode(m_anchorNode.get());
+ if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTableElement(m_anchorNode.get())))
+ return positionInParentBeforeNode(*m_anchorNode);
return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
}
if (!m_anchorNode->offsetInCharacters()
- && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount())
- && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get()))
+ && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren())
+ && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTableElement(m_anchorNode.get()))
&& containerNode()) {
- return positionInParentAfterNode(m_anchorNode.get());
+ return positionInParentAfterNode(*m_anchorNode);
}
return Position(containerNode(), computeOffsetInContainerNode(), PositionIsOffsetInAnchor);
@@ -229,14 +228,13 @@ Node* Position::computeNodeBeforePosition() const
{
if (!m_anchorNode)
return 0;
-
switch (anchorType()) {
case PositionIsBeforeChildren:
return 0;
case PositionIsAfterChildren:
return m_anchorNode->lastChild();
case PositionIsOffsetInAnchor:
- return m_anchorNode->childNode(m_offset - 1); // -1 converts to childNode((unsigned)-1) and returns null.
+ return m_anchorNode->traverseToChildAt(m_offset - 1); // -1 converts to traverseToChildAt((unsigned)-1) and returns null.
case PositionIsBeforeAnchor:
return m_anchorNode->previousSibling();
case PositionIsAfterAnchor:
@@ -257,7 +255,7 @@ Node* Position::computeNodeAfterPosition() const
case PositionIsAfterChildren:
return 0;
case PositionIsOffsetInAnchor:
- return m_anchorNode->childNode(m_offset);
+ return m_anchorNode->traverseToChildAt(m_offset);
case PositionIsBeforeAnchor:
return m_anchorNode.get();
case PositionIsAfterAnchor:
@@ -286,11 +284,11 @@ Element* Position::element() const
return toElement(n);
}
-PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
+PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
{
Element* elem = element();
if (!elem)
- return 0;
+ return nullptr;
return CSSComputedStyleDeclaration::create(elem);
}
@@ -305,7 +303,7 @@ Position Position::previous(PositionMoveType moveType) const
ASSERT(offset >= 0);
if (offset > 0) {
- if (Node* child = node->childNode(offset - 1))
+ if (Node* child = node->traverseToChildAt(offset - 1))
return lastPositionInOrAfterNode(child);
// There are two reasons child might be 0:
@@ -340,10 +338,10 @@ Position Position::next(PositionMoveType moveType) const
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(offset >= 0);
- if (Node* child = node->childNode(offset))
+ if (Node* child = node->traverseToChildAt(offset))
return firstPositionInOrBeforeNode(child);
- if (!node->hasChildNodes() && offset < lastOffsetForEditing(node)) {
+ if (!node->hasChildren() && offset < lastOffsetForEditing(node)) {
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
// Going forward one character at a time is correct.
@@ -505,34 +503,6 @@ Position Position::previousCharacterPosition(EAffinity affinity) const
return *this;
}
-// return first following position rendered at a different location, or "this"
-Position Position::nextCharacterPosition(EAffinity affinity) const
-{
- if (isNull())
- return Position();
-
- Node* fromRootEditableElement = deprecatedNode()->rootEditableElement();
-
- bool atEndOfLine = isEndOfLine(VisiblePosition(*this, affinity));
- bool rendered = isCandidate();
-
- Position currentPos = *this;
- while (!currentPos.atEndOfTree()) {
- currentPos = currentPos.next();
-
- if (currentPos.deprecatedNode()->rootEditableElement() != fromRootEditableElement)
- return *this;
-
- if (atEndOfLine || !rendered) {
- if (currentPos.isCandidate())
- return currentPos;
- } else if (rendersInDifferentPosition(currentPos))
- return currentPos;
- }
-
- return *this;
-}
-
// Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
// If true, adjacent candidates are visually distinct.
// FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
@@ -546,9 +516,14 @@ static bool endsOfNodeAreVisuallyDistinctPositions(Node* node)
return true;
// Don't include inline tables.
- if (isHTMLTableElement(node))
+ if (isHTMLTableElement(*node))
return false;
+ // A Marquee elements are moving so we should assume their ends are always
+ // visibily distinct.
+ if (isHTMLMarqueeElement(*node))
+ return true;
+
// There is a VisiblePosition inside an empty inline-block container.
return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild();
}
@@ -635,7 +610,7 @@ Position Position::upstream(EditingBoundaryCrossingRule rule) const
return lastVisible;
// Return position after tables and nodes which have content that can be ignored.
- if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
+ if (editingIgnoresContent(currentNode) || isRenderedTableElement(currentNode)) {
if (currentPos.atEndOfNode())
return positionAfterNode(currentNode);
continue;
@@ -736,7 +711,7 @@ Position Position::downstream(EditingBoundaryCrossingRule rule) const
// stop before going above the body, up into the head
// return the last visible streamer position
- if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
+ if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode())
break;
// Do not move to a visually distinct position.
@@ -763,7 +738,7 @@ Position Position::downstream(EditingBoundaryCrossingRule rule) const
lastVisible = currentPos;
// Return position before tables and nodes which have content that can be ignored.
- if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
+ if (editingIgnoresContent(currentNode) || isRenderedTableElement(currentNode)) {
if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
continue;
@@ -828,7 +803,7 @@ static int boundingBoxLogicalHeight(RenderObject *o, const IntRect &rect)
bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* renderer)
{
RenderObject* stop = renderer->nextInPreOrderAfterChildren();
- for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
+ for (RenderObject *o = renderer->slowFirstChild(); o && o != stop; o = o->nextInPreOrder())
if (o->nonPseudoNode()) {
if ((o->isText() && boundingBoxLogicalHeight(o, toRenderText(o)->linesBoundingBox()))
|| (o->isBox() && toRenderBox(o)->pixelSnappedLogicalHeight())
@@ -889,20 +864,26 @@ bool Position::isCandidate() const
if (renderer->isText())
return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
- if (isTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
+ if (renderer->isSVG()) {
+ // We don't consider SVG elements are contenteditable except for
+ // associated renderer returns isText() true, e.g. RenderSVGInlineText.
+ return false;
+ }
+
+ if (isRenderedTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
- if (isHTMLHtmlElement(m_anchorNode.get()))
+ if (isHTMLHtmlElement(*m_anchorNode))
return false;
if (renderer->isRenderBlockFlow()) {
- if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
+ if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
}
} else {
- Frame* frame = m_anchorNode->document().frame();
+ LocalFrame* frame = m_anchorNode->document().frame();
bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
return (caretBrowsing || m_anchorNode->rendererIsEditable()) && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
}
@@ -977,7 +958,7 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
return false;
if (deprecatedNode() == pos.deprecatedNode()) {
- if (deprecatedNode()->hasTagName(brTag))
+ if (isHTMLBRElement(*deprecatedNode()))
return false;
if (m_offset == pos.deprecatedEditingOffset())
@@ -989,10 +970,10 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
}
}
- if (deprecatedNode()->hasTagName(brTag) && pos.isCandidate())
+ if (isHTMLBRElement(*deprecatedNode()) && pos.isCandidate())
return true;
- if (pos.deprecatedNode()->hasTagName(brTag) && isCandidate())
+ if (isHTMLBRElement(*pos.deprecatedNode()) && isCandidate())
return true;
if (deprecatedNode()->enclosingBlockFlowElement() != pos.deprecatedNode()->enclosingBlockFlowElement())
@@ -1048,11 +1029,11 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
// This assumes that it starts in editable content.
Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
{
- ASSERT(isEditablePosition(*this));
+ ASSERT(isEditablePosition(*this, ContentIsEditable, DoNotUpdateStyle));
if (isNull())
return Position();
- if (upstream().deprecatedNode()->hasTagName(brTag))
+ if (isHTMLBRElement(*upstream().deprecatedNode()))
return Position();
Position prev = previousCharacterPosition(affinity);
@@ -1070,7 +1051,7 @@ Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
// This assumes that it starts in editable content.
Position Position::trailingWhitespacePosition(EAffinity, bool considerNonCollapsibleWhitespace) const
{
- ASSERT(isEditablePosition(*this));
+ ASSERT(isEditablePosition(*this, ContentIsEditable, DoNotUpdateStyle));
if (isNull())
return Position();
@@ -1091,7 +1072,7 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox,
static bool isNonTextLeafChild(RenderObject* object)
{
- if (object->firstChild())
+ if (object->slowFirstChild())
return false;
if (object->isText())
return false;
@@ -1284,7 +1265,10 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi
break;
inlineBox = prevBox;
}
- caretOffset = inlineBox->caretLeftmostOffset();
+ if (m_anchorNode->selfOrAncestorHasDirAutoAttribute())
+ caretOffset = inlineBox->bidiLevel() < level ? inlineBox->caretLeftmostOffset() : inlineBox->caretRightmostOffset();
+ else
+ caretOffset = inlineBox->caretLeftmostOffset();
} else if (nextBox->bidiLevel() > level) {
// Left edge of a "tertiary" run. Set to the right edge of that run.
while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
@@ -1310,6 +1294,10 @@ TextDirection Position::primaryDirection() const
return primaryDirection;
}
+void Position::trace(Visitor* visitor)
+{
+ visitor->trace(m_anchorNode);
+}
void Position::debugPosition(const char* msg) const
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/Position.h b/chromium/third_party/WebKit/Source/core/dom/Position.h
index eea78f644ce..07ad7a195a5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Position.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Position.h
@@ -51,6 +51,7 @@ enum PositionMoveType {
};
class Position {
+ DISALLOW_ALLOCATION();
public:
enum AnchorType {
PositionIsOffsetInAnchor,
@@ -75,19 +76,19 @@ public:
private:
explicit LegacyEditingOffset(int offset) : m_offset(offset) { }
- friend Position createLegacyEditingPosition(PassRefPtr<Node>, int offset);
+ friend Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node>, int offset);
int m_offset;
};
- Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset);
+ Position(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffset);
// For creating before/after positions:
- Position(PassRefPtr<Node> anchorNode, AnchorType);
- Position(PassRefPtr<Text> textNode, unsigned offset);
+ Position(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType);
+ Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset);
// For creating offset positions:
// FIXME: This constructor should eventually go away. See bug 63040.
- Position(PassRefPtr<Node> anchorNode, int offset, AnchorType);
+ Position(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset, AnchorType);
AnchorType anchorType() const { return static_cast<AnchorType>(m_anchorType); }
@@ -137,7 +138,7 @@ public:
// These should only be used for PositionIsOffsetInAnchor positions, unless
// the position is a legacy editing position.
- void moveToPosition(PassRefPtr<Node> anchorNode, int offset);
+ void moveToPosition(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset);
void moveToOffset(int offset);
bool isNull() const { return !m_anchorNode; }
@@ -145,7 +146,7 @@ public:
bool isOrphan() const { return m_anchorNode && !m_anchorNode->inDocument(); }
Element* element() const;
- PassRefPtr<CSSComputedStyleDeclaration> computedStyle() const;
+ PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyle() const;
// Move up or down the DOM by one position.
// Offsets are computed using render text for nodes that have renderers - but note that even when
@@ -203,18 +204,18 @@ public:
void showTreeForThis() const;
#endif
+ void trace(Visitor*);
+
private:
int offsetForPositionAfterAnchor() const;
int renderedOffset() const;
-
Position previousCharacterPosition(EAffinity) const;
- Position nextCharacterPosition(EAffinity) const;
static AnchorType anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset);
- RefPtr<Node> m_anchorNode;
+ RefPtrWillBeMember<Node> m_anchorNode;
// m_offset can be the offset inside m_anchorNode, or if editingIgnoresContent(m_anchorNode)
// returns true, then other places in editing will treat m_offset == 0 as "before the anchor"
// and m_offset > 0 as "after the anchor node". See parentAnchoredEquivalent for more info.
@@ -223,7 +224,7 @@ private:
bool m_isLegacyEditingPosition : 1;
};
-inline Position createLegacyEditingPosition(PassRefPtr<Node> node, int offset)
+inline Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node> node, int offset)
{
return Position(node, Position::LegacyEditingOffset(offset));
}
@@ -244,19 +245,19 @@ inline bool operator!=(const Position& a, const Position& b)
// These are inline to prevent ref-churn when returning a Position object.
// If we ever add a PassPosition we can make these non-inline.
-inline Position positionInParentBeforeNode(const Node* node)
+inline Position positionInParentBeforeNode(const Node& node)
{
- // FIXME: This should ASSERT(node->parentNode())
+ // FIXME: This should ASSERT(node.parentNode())
// At least one caller currently hits this ASSERT though, which indicates
// that the caller is trying to make a position relative to a disconnected node (which is likely an error)
// Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node->parentNode())
- return Position(node->parentNode(), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
+ return Position(node.parentNode(), node.nodeIndex(), Position::PositionIsOffsetInAnchor);
}
-inline Position positionInParentAfterNode(const Node* node)
+inline Position positionInParentAfterNode(const Node& node)
{
- ASSERT(node->parentNode());
- return Position(node->parentNode(), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
+ ASSERT(node.parentNode());
+ return Position(node.parentNode(), node.nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
}
// positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)
@@ -274,10 +275,10 @@ inline Position positionAfterNode(Node* anchorNode)
inline int lastOffsetInNode(Node* node)
{
- return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast<int>(node->childNodeCount());
+ return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast<int>(node->countChildren());
}
-// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to childNodeCount()
+// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to countChildren()
inline Position firstPositionInNode(Node* anchorNode)
{
if (anchorNode->isTextNode())
@@ -318,6 +319,7 @@ inline bool offsetIsBeforeLastNodeOffset(int offset, Node* anchorNode)
}
class PositionWithAffinity {
+ DISALLOW_ALLOCATION();
public:
PositionWithAffinity()
: m_affinity(DOWNSTREAM)
@@ -333,6 +335,11 @@ public:
EAffinity affinity() const { return m_affinity; }
const Position& position() const { return m_position; }
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_position);
+ }
+
private:
Position m_position;
EAffinity m_affinity;
diff --git a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp
index f94c0aee90c..147ab5ef964 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/dom/PositionIterator.h"
-#include "HTMLNames.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/rendering/RenderBlock.h"
@@ -42,9 +41,9 @@ PositionIterator::operator Position() const
// FIXME: This check is inadaquete because any ancestor could be ignored by editing
if (editingIgnoresContent(m_nodeAfterPositionInAnchor->parentNode()))
return positionBeforeNode(m_anchorNode);
- return positionInParentBeforeNode(m_nodeAfterPositionInAnchor);
+ return positionInParentBeforeNode(*m_nodeAfterPositionInAnchor);
}
- if (m_anchorNode->hasChildNodes())
+ if (m_anchorNode->hasChildren())
return lastPositionInOrAfterNode(m_anchorNode);
return createLegacyEditingPosition(m_anchorNode, m_offsetInAnchor);
}
@@ -61,7 +60,7 @@ void PositionIterator::increment()
return;
}
- if (!m_anchorNode->hasChildNodes() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
+ if (!m_anchorNode->hasChildren() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
m_offsetInAnchor = Position::uncheckedNextOffset(m_anchorNode, m_offsetInAnchor);
else {
m_nodeAfterPositionInAnchor = m_anchorNode;
@@ -79,8 +78,8 @@ void PositionIterator::decrement()
if (m_nodeAfterPositionInAnchor) {
m_anchorNode = m_nodeAfterPositionInAnchor->previousSibling();
if (m_anchorNode) {
- m_nodeAfterPositionInAnchor = 0;
- m_offsetInAnchor = m_anchorNode->hasChildNodes() ? 0 : lastOffsetForEditing(m_anchorNode);
+ m_nodeAfterPositionInAnchor = nullptr;
+ m_offsetInAnchor = m_anchorNode->hasChildren() ? 0 : lastOffsetForEditing(m_anchorNode);
} else {
m_nodeAfterPositionInAnchor = m_nodeAfterPositionInAnchor->parentNode();
m_anchorNode = m_nodeAfterPositionInAnchor->parentNode();
@@ -89,9 +88,9 @@ void PositionIterator::decrement()
return;
}
- if (m_anchorNode->hasChildNodes()) {
+ if (m_anchorNode->hasChildren()) {
m_anchorNode = m_anchorNode->lastChild();
- m_offsetInAnchor = m_anchorNode->hasChildNodes()? 0: lastOffsetForEditing(m_anchorNode);
+ m_offsetInAnchor = m_anchorNode->hasChildren()? 0: lastOffsetForEditing(m_anchorNode);
} else {
if (m_offsetInAnchor)
m_offsetInAnchor = Position::uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
@@ -108,7 +107,7 @@ bool PositionIterator::atStart() const
return true;
if (m_anchorNode->parentNode())
return false;
- return (!m_anchorNode->hasChildNodes() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
+ return (!m_anchorNode->hasChildren() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
}
bool PositionIterator::atEnd() const
@@ -117,7 +116,7 @@ bool PositionIterator::atEnd() const
return true;
if (m_nodeAfterPositionInAnchor)
return false;
- return !m_anchorNode->parentNode() && (m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
+ return !m_anchorNode->parentNode() && (m_anchorNode->hasChildren() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
}
bool PositionIterator::atStartOfNode() const
@@ -125,7 +124,7 @@ bool PositionIterator::atStartOfNode() const
if (!m_anchorNode)
return true;
if (!m_nodeAfterPositionInAnchor)
- return !m_anchorNode->hasChildNodes() && !m_offsetInAnchor;
+ return !m_anchorNode->hasChildren() && !m_offsetInAnchor;
return !m_nodeAfterPositionInAnchor->previousSibling();
}
@@ -135,7 +134,7 @@ bool PositionIterator::atEndOfNode() const
return true;
if (m_nodeAfterPositionInAnchor)
return false;
- return m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
+ return m_anchorNode->hasChildren() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
}
bool PositionIterator::isCandidate() const
@@ -150,17 +149,33 @@ bool PositionIterator::isCandidate() const
if (renderer->style()->visibility() != VISIBLE)
return false;
- if (renderer->isBR())
- return !m_offsetInAnchor && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
-
+ if (renderer->isBR()) {
+ // For br element, the condition
+ // |(!m_anchorNode->hasChildren() || m_nodeAfterPositionInAnchor)|
+ // corresponds to the condition
+ // |m_anchorType != PositionIsAfterAnchor| in Position.isCandaite.
+ // Both conditions say this position is not in tail of the element.
+ // If conditions lose consitency, VisiblePosition::canonicalPosition
+ // will fail on |canonicalizeCandidate(previousCandidate(position))|,
+ // because previousCandidate returns a Position converted from
+ // a "Candidate" PositionIterator and cannonicalizeCandidate(Position)
+ // assumes the Position is "Candidate".
+ return !m_offsetInAnchor && (!m_anchorNode->hasChildren() || m_nodeAfterPositionInAnchor) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
+ }
if (renderer->isText())
return !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).inRenderedText();
- if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
+ if (renderer->isSVG()) {
+ // We don't consider SVG elements are contenteditable except for
+ // associated renderer returns isText() true, e.g. RenderSVGInlineText.
+ return false;
+ }
+
+ if (isRenderedTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
- if (!isHTMLHtmlElement(m_anchorNode) && renderer->isRenderBlockFlow()) {
- if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
+ if (!isHTMLHtmlElement(*m_anchorNode) && renderer->isRenderBlockFlow()) {
+ if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
diff --git a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h
index 6587f7eb0a5..b3bcba0a0d0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h
+++ b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h
@@ -35,17 +35,18 @@ namespace WebCore {
// increment, decrement, and several predicates on the Position it is at.
// Conversion to/from Position is O(n) in the offset.
class PositionIterator {
+ STACK_ALLOCATED();
public:
PositionIterator()
- : m_anchorNode(0)
- , m_nodeAfterPositionInAnchor(0)
+ : m_anchorNode(nullptr)
+ , m_nodeAfterPositionInAnchor(nullptr)
, m_offsetInAnchor(0)
{
}
PositionIterator(const Position& pos)
: m_anchorNode(pos.anchorNode())
- , m_nodeAfterPositionInAnchor(m_anchorNode->childNode(pos.deprecatedEditingOffset()))
+ , m_nodeAfterPositionInAnchor(m_anchorNode->traverseToChildAt(pos.deprecatedEditingOffset()))
, m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : pos.deprecatedEditingOffset())
{
}
@@ -64,8 +65,8 @@ public:
bool isCandidate() const;
private:
- Node* m_anchorNode;
- Node* m_nodeAfterPositionInAnchor; // If this is non-null, m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode;
+ RawPtrWillBeMember<Node> m_anchorNode;
+ RawPtrWillBeMember<Node> m_nodeAfterPositionInAnchor; // If this is non-null, m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode;
int m_offsetInAnchor;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp b/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
index e9ced659b29..dc2c1c95d3e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
@@ -31,10 +31,11 @@
#include "config.h"
#include "core/dom/PresentationAttributeStyle.h"
-#include "HTMLNames.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Attribute.h"
#include "core/dom/Element.h"
+#include "core/html/HTMLInputElement.h"
+#include "platform/Timer.h"
#include "wtf/HashFunctions.h"
#include "wtf/HashMap.h"
#include "wtf/text/CString.h"
@@ -87,7 +88,7 @@ public:
m_hitCount++;
if (!m_cleanTimer.isActive())
- m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds);
+ m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds, FROM_HERE);
}
private:
@@ -121,19 +122,19 @@ static void makePresentationAttributeCacheKey(Element& element, PresentationAttr
if (!element.isHTMLElement())
return;
// Interpretation of the size attributes on <input> depends on the type attribute.
- if (element.hasTagName(inputTag))
+ if (isHTMLInputElement(element))
return;
- unsigned size = element.attributeCount();
- for (unsigned i = 0; i < size; ++i) {
- const Attribute* attribute = element.attributeItem(i);
- if (!element.isPresentationAttribute(attribute->name()))
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (!element.isPresentationAttribute(it->name()))
continue;
- if (!attribute->namespaceURI().isNull())
+ if (!it->namespaceURI().isNull())
return;
// FIXME: Background URL may depend on the base URL and can't be shared. Disallow caching.
- if (attribute->name() == backgroundAttr)
+ if (it->name() == backgroundAttr)
return;
- result.attributesAndValues.append(std::make_pair(attribute->localName().impl(), attribute->value()));
+ result.attributesAndValues.append(std::make_pair(it->localName().impl(), it->value()));
}
if (result.attributesAndValues.isEmpty())
return;
@@ -163,29 +164,28 @@ PassRefPtr<StylePropertySet> computePresentationAttributeStyle(Element& element)
unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey);
- PresentationAttributeCache::iterator cacheIterator;
+ PresentationAttributeCache::ValueType* cacheValue;
if (cacheHash) {
- cacheIterator = presentationAttributeCache().add(cacheHash, nullptr).iterator;
- if (cacheIterator->value && cacheIterator->value->key != cacheKey)
+ cacheValue = presentationAttributeCache().add(cacheHash, nullptr).storedValue;
+ if (cacheValue->value && cacheValue->value->key != cacheKey)
cacheHash = 0;
} else {
- cacheIterator = presentationAttributeCache().end();
+ cacheValue = 0;
}
RefPtr<StylePropertySet> style;
- if (cacheHash && cacheIterator->value) {
- style = cacheIterator->value->value;
+ if (cacheHash && cacheValue->value) {
+ style = cacheValue->value->value;
cacheCleaner.didHitPresentationAttributeCache();
} else {
style = MutableStylePropertySet::create(element.isSVGElement() ? SVGAttributeMode : HTMLAttributeMode);
- unsigned size = element.attributeCount();
- for (unsigned i = 0; i < size; ++i) {
- const Attribute* attribute = element.attributeItem(i);
- element.collectStyleForPresentationAttribute(attribute->name(), attribute->value(), toMutableStylePropertySet(style));
- }
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it)
+ element.collectStyleForPresentationAttribute(it->name(), it->value(), toMutableStylePropertySet(style));
}
- if (!cacheHash || cacheIterator->value)
+ if (!cacheHash || cacheValue->value)
return style.release();
OwnPtr<PresentationAttributeCacheEntry> newEntry = adoptPtr(new PresentationAttributeCacheEntry);
@@ -199,7 +199,7 @@ PassRefPtr<StylePropertySet> computePresentationAttributeStyle(Element& element)
presentationAttributeCache().clear();
presentationAttributeCache().set(cacheHash, newEntry.release());
} else {
- cacheIterator->value = newEntry.release();
+ cacheValue->value = newEntry.release();
}
return style.release();
diff --git a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
index bd1bd7b02c6..bff917dafe5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
@@ -21,7 +21,7 @@
#include "config.h"
#include "core/dom/ProcessingInstruction.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
@@ -48,18 +48,27 @@ inline ProcessingInstruction::ProcessingInstruction(Document& document, const St
ScriptWrappable::init(this);
}
-PassRefPtr<ProcessingInstruction> ProcessingInstruction::create(Document& document, const String& target, const String& data)
+PassRefPtrWillBeRawPtr<ProcessingInstruction> ProcessingInstruction::create(Document& document, const String& target, const String& data)
{
- return adoptRef(new ProcessingInstruction(document, target, data));
+ return adoptRefWillBeNoop(new ProcessingInstruction(document, target, data));
}
ProcessingInstruction::~ProcessingInstruction()
{
+#if !ENABLE(OILPAN)
if (m_sheet)
m_sheet->clearOwnerNode();
- if (inDocument())
- document().styleEngine()->removeStyleSheetCandidateNode(this);
+ // FIXME: ProcessingInstruction should not be in document here.
+ // However, if we add ASSERT(!inDocument()), fast/xsl/xslt-entity.xml
+ // crashes. We need to investigate ProcessingInstruction lifetime.
+ if (inDocument()) {
+ if (m_isCSS)
+ document().styleEngine()->removeStyleSheetCandidateNode(this);
+ else if (m_isXSL)
+ document().styleEngine()->removeXSLStyleSheet(this);
+ }
+#endif
}
String ProcessingInstruction::nodeName() const
@@ -72,77 +81,88 @@ Node::NodeType ProcessingInstruction::nodeType() const
return PROCESSING_INSTRUCTION_NODE;
}
-PassRefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
{
// FIXME: Is it a problem that this does not copy m_localHref?
// What about other data members?
return create(document(), m_target, m_data);
}
-void ProcessingInstruction::checkStyleSheet()
+void ProcessingInstruction::didAttributeChanged()
{
- if (m_target == "xml-stylesheet" && document().frame() && parentNode() == document()) {
- // see http://www.w3.org/TR/xml-stylesheet/
- // ### support stylesheet included in a fragment of this (or another) document
- // ### make sure this gets called when adding from javascript
- bool attrsOk;
- const HashMap<String, String> attrs = parseAttributes(m_data, attrsOk);
- if (!attrsOk)
- return;
- HashMap<String, String>::const_iterator i = attrs.find("type");
- String type;
- if (i != attrs.end())
- type = i->value;
-
- m_isCSS = type.isEmpty() || type == "text/css";
- m_isXSL = (type == "text/xml" || type == "text/xsl" || type == "application/xml" ||
- type == "application/xhtml+xml" || type == "application/rss+xml" || type == "application/atom+xml");
- if (!m_isCSS && !m_isXSL)
- return;
-
- String href = attrs.get("href");
- String alternate = attrs.get("alternate");
- m_alternate = alternate == "yes";
- m_title = attrs.get("title");
- m_media = attrs.get("media");
-
- if (m_alternate && m_title.isEmpty())
- return;
-
- if (href.length() > 1 && href[0] == '#') {
- m_localHref = href.substring(1);
- // We need to make a synthetic XSLStyleSheet that is embedded. It needs to be able
- // to kick off import/include loads that can hang off some parent sheet.
- if (m_isXSL) {
- KURL finalURL(ParsedURLString, m_localHref);
- m_sheet = XSLStyleSheet::createEmbedded(this, finalURL);
- m_loading = false;
- }
- } else {
- clearResource();
-
- String url = document().completeURL(href).string();
- if (!dispatchBeforeLoadEvent(url))
- return;
-
- ResourcePtr<StyleSheetResource> resource;
- FetchRequest request(ResourceRequest(document().completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
- if (m_isXSL) {
- resource = document().fetcher()->fetchXSLStyleSheet(request);
- } else {
- String charset = attrs.get("charset");
- if (charset.isEmpty())
- charset = document().charset();
- request.setCharset(charset);
- resource = document().fetcher()->fetchCSSStyleSheet(request);
- }
-
- if (resource) {
- m_loading = true;
- document().styleEngine()->addPendingSheet();
- setResource(resource);
- }
+ ASSERT(!m_sheet);
+ ASSERT(!isLoading());
+ String href;
+ String charset;
+ if (!checkStyleSheet(href, charset))
+ return;
+ process(href, charset);
+}
+
+bool ProcessingInstruction::checkStyleSheet(String& href, String& charset)
+{
+ if (m_target != "xml-stylesheet" || !document().frame() || parentNode() != document())
+ return false;
+
+ // see http://www.w3.org/TR/xml-stylesheet/
+ // ### support stylesheet included in a fragment of this (or another) document
+ // ### make sure this gets called when adding from javascript
+ bool attrsOk;
+ const HashMap<String, String> attrs = parseAttributes(m_data, attrsOk);
+ if (!attrsOk)
+ return false;
+ HashMap<String, String>::const_iterator i = attrs.find("type");
+ String type;
+ if (i != attrs.end())
+ type = i->value;
+
+ m_isCSS = type.isEmpty() || type == "text/css";
+ m_isXSL = (type == "text/xml" || type == "text/xsl" || type == "application/xml" || type == "application/xhtml+xml" || type == "application/rss+xml" || type == "application/atom+xml");
+ if (!m_isCSS && !m_isXSL)
+ return false;
+
+ href = attrs.get("href");
+ charset = attrs.get("charset");
+ String alternate = attrs.get("alternate");
+ m_alternate = alternate == "yes";
+ m_title = attrs.get("title");
+ m_media = attrs.get("media");
+
+ return !m_alternate || !m_title.isEmpty();
+}
+
+void ProcessingInstruction::process(const String& href, const String& charset)
+{
+ if (href.length() > 1 && href[0] == '#') {
+ m_localHref = href.substring(1);
+ // We need to make a synthetic XSLStyleSheet that is embedded.
+ // It needs to be able to kick off import/include loads that
+ // can hang off some parent sheet.
+ if (m_isXSL) {
+ KURL finalURL(ParsedURLString, m_localHref);
+ m_sheet = XSLStyleSheet::createEmbedded(this, finalURL);
+ m_loading = false;
}
+ return;
+ }
+
+ clearResource();
+
+ String url = document().completeURL(href).string();
+
+ ResourcePtr<StyleSheetResource> resource;
+ FetchRequest request(ResourceRequest(document().completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
+ if (m_isXSL) {
+ resource = document().fetcher()->fetchXSLStyleSheet(request);
+ } else {
+ request.setCharset(charset.isEmpty() ? document().charset() : charset);
+ resource = document().fetcher()->fetchCSSStyleSheet(request);
+ }
+
+ if (resource) {
+ m_loading = true;
+ document().styleEngine()->addPendingSheet();
+ setResource(resource);
}
}
@@ -172,11 +192,11 @@ void ProcessingInstruction::setCSSStyleSheet(const String& href, const KURL& bas
}
ASSERT(m_isCSS);
- CSSParserContext parserContext(document(), baseURL, charset);
+ CSSParserContext parserContext(document(), 0, baseURL, charset);
- RefPtr<StyleSheetContents> newSheet = StyleSheetContents::create(href, parserContext);
+ RefPtrWillBeRawPtr<StyleSheetContents> newSheet = StyleSheetContents::create(href, parserContext);
- RefPtr<CSSStyleSheet> cssSheet = CSSStyleSheet::create(newSheet, this);
+ RefPtrWillBeRawPtr<CSSStyleSheet> cssSheet = CSSStyleSheet::create(newSheet, this);
cssSheet->setDisabled(m_alternate);
cssSheet->setTitle(m_title);
cssSheet->setMediaQueries(MediaQuerySet::create(m_media));
@@ -212,7 +232,7 @@ void ProcessingInstruction::parseStyleSheet(const String& sheet)
toXSLStyleSheet(m_sheet.get())->checkLoaded();
}
-void ProcessingInstruction::setCSSStyleSheet(PassRefPtr<CSSStyleSheet> sheet)
+void ProcessingInstruction::setCSSStyleSheet(PassRefPtrWillBeRawPtr<CSSStyleSheet> sheet)
{
ASSERT(!resource());
ASSERT(!m_loading);
@@ -221,21 +241,21 @@ void ProcessingInstruction::setCSSStyleSheet(PassRefPtr<CSSStyleSheet> sheet)
sheet->setDisabled(m_alternate);
}
-void ProcessingInstruction::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- if (!sheet())
- return;
-
- addSubresourceURL(urls, sheet()->baseURL());
-}
-
Node::InsertionNotificationRequest ProcessingInstruction::insertedInto(ContainerNode* insertionPoint)
{
CharacterData::insertedInto(insertionPoint);
if (!insertionPoint->inDocument())
return InsertionDone;
- document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
- checkStyleSheet();
+
+ String href;
+ String charset;
+ bool isValid = checkStyleSheet(href, charset);
+ if (m_isCSS)
+ document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
+ else if (m_isXSL)
+ document().styleEngine()->addXSLStyleSheet(this, m_createdByParser);
+ if (isValid)
+ process(href, charset);
return InsertionDone;
}
@@ -245,14 +265,17 @@ void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
if (!insertionPoint->inDocument())
return;
- document().styleEngine()->removeStyleSheetCandidateNode(this);
+ if (m_isCSS)
+ document().styleEngine()->removeStyleSheetCandidateNode(this);
+ else if (m_isXSL)
+ document().styleEngine()->removeXSLStyleSheet(this);
- RefPtr<StyleSheet> removedSheet = m_sheet;
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet;
if (m_sheet) {
ASSERT(m_sheet->ownerNode() == this);
m_sheet->clearOwnerNode();
- m_sheet = 0;
+ m_sheet = nullptr;
}
// If we're in document teardown, then we don't need to do any notification of our sheet's removal.
@@ -260,10 +283,10 @@ void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
document().removedStyleSheet(removedSheet.get());
}
-void ProcessingInstruction::finishParsingChildren()
+void ProcessingInstruction::trace(Visitor* visitor)
{
- m_createdByParser = false;
- CharacterData::finishParsingChildren();
+ visitor->trace(m_sheet);
+ CharacterData::trace(visitor);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
index 2dec480183e..60528e0e22a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
@@ -34,42 +34,41 @@ class CSSStyleSheet;
class ProcessingInstruction FINAL : public CharacterData, private ResourceOwner<StyleSheetResource> {
public:
- static PassRefPtr<ProcessingInstruction> create(Document&, const String& target, const String& data);
+ static PassRefPtrWillBeRawPtr<ProcessingInstruction> create(Document&, const String& target, const String& data);
virtual ~ProcessingInstruction();
+ virtual void trace(Visitor*) OVERRIDE;
const String& target() const { return m_target; }
void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
- virtual void finishParsingChildren();
-
const String& localHref() const { return m_localHref; }
StyleSheet* sheet() const { return m_sheet.get(); }
- void setCSSStyleSheet(PassRefPtr<CSSStyleSheet>);
+ void setCSSStyleSheet(PassRefPtrWillBeRawPtr<CSSStyleSheet>);
bool isCSS() const { return m_isCSS; }
bool isXSL() const { return m_isXSL; }
+ void didAttributeChanged();
bool isLoading() const;
private:
- friend class CharacterData;
ProcessingInstruction(Document&, const String& target, const String& data);
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- void checkStyleSheet();
- virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*);
- virtual void setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet);
+ bool checkStyleSheet(String& href, String& charset);
+ void process(const String& href, const String& charset);
- virtual bool sheetLoaded();
+ virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*) OVERRIDE;
+ virtual void setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet) OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool sheetLoaded() OVERRIDE;
void parseStyleSheet(const String& sheet);
@@ -77,7 +76,7 @@ private:
String m_localHref;
String m_title;
String m_media;
- RefPtr<StyleSheet> m_sheet;
+ RefPtrWillBeMember<StyleSheet> m_sheet;
bool m_loading;
bool m_alternate;
bool m_createdByParser;
@@ -87,6 +86,11 @@ private:
DEFINE_NODE_TYPE_CASTS(ProcessingInstruction, nodeType() == Node::PROCESSING_INSTRUCTION_NODE);
+inline bool isXSLStyleSheet(const Node& node)
+{
+ return node.nodeType() == Node::PROCESSING_INSTRUCTION_NODE && toProcessingInstruction(node).isXSL();
+}
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Promise.idl b/chromium/third_party/WebKit/Source/core/dom/Promise.idl
deleted file mode 100644
index 45989d44d82..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Promise.idl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-callback PromiseInit = void (any resolve, any reject);
-callback AnyCallback = any (optional any value);
-[
- CustomConstructor(PromiseInit init),
- GlobalContext=Window&WorkerGlobalScope,
-] interface Promise {
- [Custom] Promise then(optional AnyCallback fulfillCallback, optional AnyCallback rejectCallback);
- [Custom] Promise catch(optional AnyCallback rejectCallback);
-
- [Custom] static Promise resolve(any value);
- [Custom] static Promise reject(any value);
-
- [Custom] static Promise cast(any value);
- [Custom] static Promise race(any iterable);
- [Custom] static Promise all(any iterable);
-};
diff --git a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp
index 9512d82defe..30535de0e3b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp
@@ -70,13 +70,15 @@ PassRefPtr<RenderStyle> PseudoElement::customStyleForRenderer()
void PseudoElement::dispose()
{
+ ASSERT(parentOrShadowHostElement());
+
InspectorInstrumentation::pseudoElementDestroyed(this);
ASSERT(!nextSibling());
ASSERT(!previousSibling());
detach();
- RefPtr<Element> parent = parentOrShadowHostElement();
+ RefPtrWillBeRawPtr<Element> parent = parentOrShadowHostElement();
setParentOrShadowHostNode(0);
removedFrom(parent.get());
}
@@ -91,8 +93,6 @@ void PseudoElement::attach(const AttachContext& context)
if (!renderer)
return;
RenderStyle* style = renderer->style();
- if (style->hasFlowFrom())
- return;
if (style->styleType() != BEFORE && style->styleType() != AFTER)
return;
ASSERT(style->contentData());
diff --git a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h
index 6f109333e08..184eb9c537b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h
+++ b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h
@@ -29,25 +29,20 @@
#include "core/dom/Element.h"
#include "core/rendering/style/RenderStyle.h"
-#include "wtf/Forward.h"
namespace WebCore {
class PseudoElement FINAL : public Element {
public:
- static PassRefPtr<PseudoElement> create(Element* parent, PseudoId pseudoId)
+ static PassRefPtrWillBeRawPtr<PseudoElement> create(Element* parent, PseudoId pseudoId)
{
- return adoptRef(new PseudoElement(parent, pseudoId));
+ return adoptRefWillBeNoop(new PseudoElement(parent, pseudoId));
}
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
- // cannot be directly collected into a named flow.
- virtual bool shouldMoveToFlowThread(RenderStyle*) const OVERRIDE { return false; }
-
virtual bool canStartSelection() const OVERRIDE { return false; }
virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
@@ -68,10 +63,10 @@ const QualifiedName& pseudoElementTagName();
inline bool pseudoElementRendererIsNeeded(const RenderStyle* style)
{
- return style && style->display() != NONE && (style->styleType() == BACKDROP || style->contentData() || style->hasFlowFrom());
+ return style && style->display() != NONE && (style->styleType() == BACKDROP || style->contentData());
}
-DEFINE_NODE_TYPE_CASTS(PseudoElement, isPseudoElement());
+DEFINE_ELEMENT_TYPE_CASTS(PseudoElement, isPseudoElement());
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp
index 1912986ead2..c447e8db0a1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp
@@ -25,12 +25,13 @@
#define QNAME_DEFAULT_CONSTRUCTOR
#endif
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
#include "core/dom/QualifiedName.h"
+
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "wtf/Assertions.h"
#include "wtf/HashSet.h"
#include "wtf/MainThread.h"
@@ -59,42 +60,39 @@ static QualifiedNameCache& qualifiedNameCache()
}
struct QNameComponentsTranslator {
- static unsigned hash(const QualifiedNameComponents& components)
+ static unsigned hash(const QualifiedNameData& data)
{
- return hashComponents(components);
+ return hashComponents(data.m_components);
}
- static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameComponents& c)
+ static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameData& data)
{
- return c.m_prefix == name->m_prefix.impl() && c.m_localName == name->m_localName.impl() && c.m_namespace == name->m_namespace.impl();
+ return data.m_components.m_prefix == name->m_prefix.impl()
+ && data.m_components.m_localName == name->m_localName.impl()
+ && data.m_components.m_namespace == name->m_namespace.impl();
}
- static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameComponents& components, unsigned)
+ static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameData& data, unsigned)
{
- location = QualifiedName::QualifiedNameImpl::create(AtomicString(components.m_prefix), AtomicString(components.m_localName), AtomicString(components.m_namespace)).leakRef();
+ const QualifiedNameComponents& components = data.m_components;
+ location = QualifiedName::QualifiedNameImpl::create(AtomicString(components.m_prefix), AtomicString(components.m_localName), AtomicString(components.m_namespace), data.m_isStatic).leakRef();
}
};
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
{
- QualifiedNameComponents components = { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() };
- QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(components);
- m_impl = *addResult.iterator;
- if (!addResult.isNewEntry)
- m_impl->ref();
+ QualifiedNameData data = { { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() }, false };
+ QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
+ m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
}
-QualifiedName::~QualifiedName()
+QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n, bool isStatic)
{
- deref();
+ QualifiedNameData data = { { p.impl(), l.impl(), n.impl() }, isStatic };
+ QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
+ m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
}
-void QualifiedName::deref()
+QualifiedName::~QualifiedName()
{
-#ifdef QNAME_DEFAULT_CONSTRUCTOR
- if (!m_impl)
- return;
-#endif
- ASSERT(!isHashTableDeletedValue());
- m_impl->deref();
}
QualifiedName::QualifiedNameImpl::~QualifiedNameImpl()
@@ -116,12 +114,12 @@ DEFINE_GLOBAL(QualifiedName, anyName, nullAtom, starAtom, starAtom)
void QualifiedName::init()
{
ASSERT(starAtom.impl());
- new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom);
+ new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom, true );
}
-const QualifiedName& nullQName()
+const QualifiedName& QualifiedName::null()
{
- DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom, true));
return nullName;
}
@@ -138,14 +136,14 @@ unsigned QualifiedName::QualifiedNameImpl::computeHash() const
return hashComponents(components);
}
-void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
+void QualifiedName::createStatic(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
{
- new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace);
+ new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace, true);
}
-void createQualifiedName(void* targetAddress, StringImpl* name)
+void QualifiedName::createStatic(void* targetAddress, StringImpl* name)
{
- new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom);
+ new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom, true);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h
index b42f9e45cd2..46d4ad8cd3a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h
+++ b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h
@@ -21,7 +21,6 @@
#ifndef QualifiedName_h
#define QualifiedName_h
-#include "wtf/Forward.h"
#include "wtf/HashTableDeletedValueType.h"
#include "wtf/HashTraits.h"
#include "wtf/RefCounted.h"
@@ -35,47 +34,80 @@ struct QualifiedNameComponents {
StringImpl* m_namespace;
};
+// This struct is used to pass data between QualifiedName and the QNameTranslator.
+// For hashing and equality only the QualifiedNameComponents fields are used.
+struct QualifiedNameData {
+ QualifiedNameComponents m_components;
+ bool m_isStatic;
+};
+
class QualifiedName {
WTF_MAKE_FAST_ALLOCATED;
public:
class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
public:
- static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
+ static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic)
{
- return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI));
+ return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI, isStatic));
}
~QualifiedNameImpl();
unsigned computeHash() const;
- mutable unsigned m_existingHash;
+ bool hasOneRef() const
+ {
+ return m_isStatic || RefCounted<QualifiedNameImpl>::hasOneRef();
+ }
+
+ void ref()
+ {
+ if (m_isStatic)
+ return;
+ RefCounted<QualifiedNameImpl>::ref();
+ }
+
+ void deref()
+ {
+ if (m_isStatic)
+ return;
+ RefCounted<QualifiedNameImpl>::deref();
+ }
+
const AtomicString m_prefix;
const AtomicString m_localName;
const AtomicString m_namespace;
mutable AtomicString m_localNameUpper;
+ // We rely on StringHasher's hashMemory clearing out the top 8 bits when
+ // doing hashing and use one of the bits for the m_isStatic value.
+ mutable unsigned m_existingHash : 24;
+ unsigned m_isStatic : 1;
private:
- QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
- : m_existingHash(0)
- , m_prefix(prefix)
+ QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic)
+ : m_prefix(prefix)
, m_localName(localName)
, m_namespace(namespaceURI)
+ , m_existingHash(0)
+ , m_isStatic(isStatic)
+
{
ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull());
}
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
- QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { }
- bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
~QualifiedName();
#ifdef QNAME_DEFAULT_CONSTRUCTOR
- QualifiedName() : m_impl(0) { }
+ QualifiedName() { }
#endif
- QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); }
- const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; }
+ QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { }
+ const QualifiedName& operator=(const QualifiedName& other) { m_impl = other.m_impl; return *this; }
+
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ QualifiedName(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
+ bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; }
bool operator!=(const QualifiedName& other) const { return !(*this == other); }
@@ -96,18 +128,22 @@ public:
String toString() const;
- QualifiedNameImpl* impl() const { return m_impl; }
+ QualifiedNameImpl* impl() const { return m_impl.get(); }
// Init routine for globals
static void init();
-private:
- void ref() const { m_impl->ref(); }
- void deref();
+ static const QualifiedName& null();
- static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); }
+ // The below methods are only for creating static global QNames that need no ref counting.
+ static void createStatic(void* targetAddress, StringImpl* name);
+ static void createStatic(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace);
- QualifiedNameImpl* m_impl;
+private:
+ // This constructor is used only to create global/static QNames that don't require any ref counting.
+ QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic);
+
+ RefPtr<QualifiedNameImpl> m_impl;
};
#ifndef WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS
@@ -115,8 +151,6 @@ extern const QualifiedName anyName;
inline const QualifiedName& anyQName() { return anyName; }
#endif
-const QualifiedName& nullQName();
-
inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); }
inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); }
inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
@@ -143,9 +177,6 @@ struct QualifiedNameHash {
static const bool safeToCompareToEmptyOrDeleted = false;
};
-void createQualifiedName(void* targetAddress, StringImpl* name);
-void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace);
-
}
namespace WTF {
@@ -158,7 +189,7 @@ namespace WTF {
template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> {
static const bool emptyValueIsZero = false;
- static WebCore::QualifiedName emptyValue() { return WebCore::nullQName(); }
+ static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName::null(); }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/Range.cpp b/chromium/third_party/WebKit/Source/core/dom/Range.cpp
index 5b75ea2bab4..af875e7afd1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Range.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Range.cpp
@@ -25,7 +25,6 @@
#include "config.h"
#include "core/dom/Range.h"
-#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/ClientRect.h"
#include "core/dom/ClientRectList.h"
@@ -35,12 +34,12 @@
#include "core/dom/NodeTraversal.h"
#include "core/dom/NodeWithIndex.h"
#include "core/dom/ProcessingInstruction.h"
-#include "core/events/ScopedEventQueue.h"
#include "core/dom/Text.h"
#include "core/editing/TextIterator.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/markup.h"
+#include "core/events/ScopedEventQueue.h"
#include "core/html/HTMLElement.h"
#include "core/rendering/RenderBoxModelObject.h"
#include "core/rendering/RenderText.h"
@@ -54,7 +53,6 @@
namespace WebCore {
-using namespace std;
using namespace HTMLNames;
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range"));
@@ -72,9 +70,9 @@ inline Range::Range(Document& ownerDocument)
m_ownerDocument->attachRange(this);
}
-PassRefPtr<Range> Range::create(Document& ownerDocument)
+PassRefPtrWillBeRawPtr<Range> Range::create(Document& ownerDocument)
{
- return adoptRef(new Range(ownerDocument));
+ return adoptRefWillBeNoop(new Range(ownerDocument));
}
inline Range::Range(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
@@ -95,20 +93,22 @@ inline Range::Range(Document& ownerDocument, Node* startContainer, int startOffs
setEnd(endContainer, endOffset);
}
-PassRefPtr<Range> Range::create(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
+PassRefPtrWillBeRawPtr<Range> Range::create(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
{
- return adoptRef(new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
+ return adoptRefWillBeNoop(new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
}
-PassRefPtr<Range> Range::create(Document& ownerDocument, const Position& start, const Position& end)
+PassRefPtrWillBeRawPtr<Range> Range::create(Document& ownerDocument, const Position& start, const Position& end)
{
- return adoptRef(new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
+ return adoptRefWillBeNoop(new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
}
Range::~Range()
{
+#if !ENABLE(OILPAN)
// Always detach (even if we've already detached) to fix https://bugs.webkit.org/show_bug.cgi?id=26044
m_ownerDocument->detachRange(this);
+#endif
#ifndef NDEBUG
rangeCounter.decrement();
@@ -121,58 +121,13 @@ void Range::setDocument(Document& document)
ASSERT(m_ownerDocument);
m_ownerDocument->detachRange(this);
m_ownerDocument = &document;
- m_start.setToStartOfNode(&document);
- m_end.setToStartOfNode(&document);
+ m_start.setToStartOfNode(document);
+ m_end.setToStartOfNode(document);
m_ownerDocument->attachRange(this);
}
-Node* Range::startContainer(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_start.container();
-}
-
-int Range::startOffset(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_start.offset();
-}
-
-Node* Range::endContainer(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_end.container();
-}
-
-int Range::endOffset(ExceptionState& exceptionState) const
+Node* Range::commonAncestorContainer() const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_end.offset();
-}
-
-Node* Range::commonAncestorContainer(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
return commonAncestorContainer(m_start.container(), m_end.container());
}
@@ -187,16 +142,6 @@ Node* Range::commonAncestorContainer(Node* containerA, Node* containerB)
return 0;
}
-bool Range::collapsed(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_start == m_end;
-}
-
static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& start, const RangeBoundaryPoint& end)
{
Node* endRootContainer = end.container();
@@ -209,15 +154,10 @@ static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& star
return startRootContainer != endRootContainer || (Range::compareBoundaryPoints(start, end, ASSERT_NO_EXCEPTION) > 0);
}
-void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& exceptionState)
+void Range::setStart(PassRefPtrWillBeRawPtr<Node> refNode, int offset, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
return;
}
@@ -234,18 +174,13 @@ void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& excep
m_start.set(refNode, offset, childNode);
if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end))
- collapse(true, exceptionState);
+ collapse(true);
}
-void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& exceptionState)
+void Range::setEnd(PassRefPtrWillBeRawPtr<Node> refNode, int offset, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
return;
}
@@ -262,7 +197,7 @@ void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& excepti
m_end.set(refNode, offset, childNode);
if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end))
- collapse(false, exceptionState);
+ collapse(false);
}
void Range::setStart(const Position& start, ExceptionState& exceptionState)
@@ -277,13 +212,8 @@ void Range::setEnd(const Position& end, ExceptionState& exceptionState)
setEnd(parentAnchored.containerNode(), parentAnchored.offsetInContainerNode(), exceptionState);
}
-void Range::collapse(bool toStart, ExceptionState& exceptionState)
+void Range::collapse(bool toStart)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (toStart)
m_end = m_start;
else
@@ -292,13 +222,8 @@ void Range::collapse(bool toStart, ExceptionState& exceptionState)
bool Range::isPointInRange(Node* refNode, int offset, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return false;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided was null.");
return false;
}
@@ -320,18 +245,18 @@ short Range::comparePoint(Node* refNode, int offset, ExceptionState& exceptionSt
// This method returns -1, 0 or 1 depending on if the point described by the
// refNode node and an offset within the node is before, same as, or after the range respectively.
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+ if (!refNode) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided was null.");
return 0;
}
- if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (!refNode->inActiveDocument()) {
+ exceptionState.throwDOMException(WrongDocumentError, "The node provided is not in an active document.");
return 0;
}
- if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) {
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ if (refNode->document() != m_ownerDocument) {
+ exceptionState.throwDOMException(WrongDocumentError, "The node provided is not in this Range's Document.");
return 0;
}
@@ -361,16 +286,11 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionState& exceptio
// before and after(surrounds), or inside the range, respectively
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
return NODE_BEFORE;
}
- if (!m_start.container() && refNode->inActiveDocument()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return NODE_BEFORE;
- }
-
- if (m_start.container() && !refNode->inActiveDocument()) {
+ if (!refNode->inActiveDocument()) {
// Firefox doesn't throw an exception for this case; it returns 0.
return NODE_BEFORE;
}
@@ -386,7 +306,7 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionState& exceptio
if (!parentNode) {
// if the node is the top document we should return NODE_BEFORE_AND_AFTER
// but we throw to match firefox behavior
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The provided node has no parent.");
return NODE_BEFORE;
}
@@ -403,25 +323,15 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionState& exceptio
short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionState& exceptionState) const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
if (!sourceRange) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The source range provided was null.");
return 0;
}
- Node* thisCont = commonAncestorContainer(exceptionState);
- if (exceptionState.hadException())
- return 0;
- Node* sourceCont = sourceRange->commonAncestorContainer(exceptionState);
- if (exceptionState.hadException())
- return 0;
-
+ Node* thisCont = commonAncestorContainer();
+ Node* sourceCont = sourceRange->commonAncestorContainer();
if (thisCont->document() != sourceCont->document()) {
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ exceptionState.throwDOMException(WrongDocumentError, "The source range is in a different document than this range.");
return 0;
}
@@ -432,7 +342,7 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
while (sourceTop->parentNode())
sourceTop = sourceTop->parentNode();
if (thisTop != sourceTop) { // in different DocumentFragments
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ exceptionState.throwDOMException(WrongDocumentError, "The source range is in a different document than this range.");
return 0;
}
@@ -447,7 +357,7 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
return compareBoundaryPoints(m_start, sourceRange->m_end, exceptionState);
}
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The comparison method provided must be one of 'START_TO_START', 'START_TO_END', 'END_TO_END', or 'END_TO_START'.");
return 0;
}
@@ -513,7 +423,7 @@ short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containe
// ### we need to do a traversal here instead
Node* commonAncestor = commonAncestorContainer(containerA, containerB);
if (!commonAncestor) {
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ exceptionState.throwDOMException(WrongDocumentError, "The two ranges are in separate documents.");
return 0;
}
Node* childA = containerA;
@@ -552,7 +462,7 @@ short Range::compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const Ra
bool Range::boundaryPointsValid() const
{
TrackExceptionState exceptionState;
- return m_start.container() && compareBoundaryPoints(m_start, m_end, exceptionState) <= 0 && !exceptionState.hadException();
+ return compareBoundaryPoints(m_start, m_end, exceptionState) <= 0 && !exceptionState.hadException();
}
void Range::deleteContents(ExceptionState& exceptionState)
@@ -561,21 +471,18 @@ void Range::deleteContents(ExceptionState& exceptionState)
if (exceptionState.hadException())
return;
- processContents(DELETE_CONTENTS, exceptionState);
+ {
+ EventQueueScope eventQueueScope;
+ processContents(DELETE_CONTENTS, exceptionState);
+ }
}
bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState)
{
// http://developer.mozilla.org/en/docs/DOM:range.intersectsNode
// Returns a bool if the node intersects the range.
-
- // Throw exception if the range is already detached.
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return false;
- }
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return false;
}
@@ -590,7 +497,7 @@ bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState)
if (!parentNode) {
// if the node is the top document we should return NODE_BEFORE_AND_AFTER
// but we throw to match firefox behavior
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided has no parent.");
return false;
}
@@ -640,46 +547,18 @@ static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offs
return container;
}
-static inline unsigned lengthOfContentsInNode(Node* node)
-{
- // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
- switch (node->nodeType()) {
- case Node::TEXT_NODE:
- case Node::CDATA_SECTION_NODE:
- case Node::COMMENT_NODE:
- return toCharacterData(node)->length();
- case Node::PROCESSING_INSTRUCTION_NODE:
- return toProcessingInstruction(node)->data().length();
- case Node::ELEMENT_NODE:
- case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
- case Node::DOCUMENT_NODE:
- case Node::DOCUMENT_TYPE_NODE:
- case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- return node->childNodeCount();
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionState& exceptionState)
{
- typedef Vector<RefPtr<Node> > NodeVector;
+ typedef WillBeHeapVector<RefPtrWillBeMember<Node> > NodeVector;
- RefPtr<DocumentFragment> fragment;
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = nullptr;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
fragment = DocumentFragment::create(*m_ownerDocument.get());
- if (collapsed(exceptionState))
+ if (collapsed())
return fragment.release();
- if (exceptionState.hadException())
- return 0;
- RefPtr<Node> commonRoot = commonAncestorContainer(exceptionState);
- if (exceptionState.hadException())
- return 0;
+ RefPtrWillBeRawPtr<Node> commonRoot = commonAncestorContainer();
ASSERT(commonRoot);
if (m_start.container() == m_end.container()) {
@@ -692,8 +571,8 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
RangeBoundaryPoint originalEnd(m_end);
// what is the highest node that partially selects the start / end of the range?
- RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(originalStart.container(), commonRoot.get());
- RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(originalEnd.container(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> partialStart = highestAncestorUnderCommonRoot(originalStart.container(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> partialEnd = highestAncestorUnderCommonRoot(originalEnd.container(), commonRoot.get());
// Start and end containers are different.
// There are three possibilities here:
@@ -715,23 +594,23 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
// Note that we are verifying that our common root hierarchy is still intact
// after any DOM mutation event, at various stages below. See webkit bug 60350.
- RefPtr<Node> leftContents;
+ RefPtrWillBeRawPtr<Node> leftContents = nullptr;
if (originalStart.container() != commonRoot && commonRoot->contains(originalStart.container())) {
- leftContents = processContentsBetweenOffsets(action, 0, originalStart.container(), originalStart.offset(), lengthOfContentsInNode(originalStart.container()), exceptionState);
+ leftContents = processContentsBetweenOffsets(action, nullptr, originalStart.container(), originalStart.offset(), originalStart.container()->lengthOfContents(), exceptionState);
leftContents = processAncestorsAndTheirSiblings(action, originalStart.container(), ProcessContentsForward, leftContents, commonRoot.get(), exceptionState);
}
- RefPtr<Node> rightContents;
+ RefPtrWillBeRawPtr<Node> rightContents = nullptr;
if (m_end.container() != commonRoot && commonRoot->contains(originalEnd.container())) {
- rightContents = processContentsBetweenOffsets(action, 0, originalEnd.container(), 0, originalEnd.offset(), exceptionState);
+ rightContents = processContentsBetweenOffsets(action, nullptr, originalEnd.container(), 0, originalEnd.offset(), exceptionState);
rightContents = processAncestorsAndTheirSiblings(action, originalEnd.container(), ProcessContentsBackward, rightContents, commonRoot.get(), exceptionState);
}
// delete all children of commonRoot between the start and end container
- RefPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.container(), originalStart.offset(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.container(), originalStart.offset(), commonRoot.get());
if (processStart && originalStart.container() != commonRoot) // processStart contains nodes before m_start.
processStart = processStart->nextSibling();
- RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.container(), originalEnd.offset(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.container(), originalEnd.offset(), commonRoot.get());
// Collapse the range, making sure that the result is not within a node that was partially selected.
if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
@@ -745,7 +624,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), exceptionState);
}
if (exceptionState.hadException())
- return 0;
+ return nullptr;
m_end = m_start;
}
@@ -771,7 +650,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
return fragment.release();
}
-static inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionState& exceptionState)
+static inline void deleteCharacterData(PassRefPtrWillBeRawPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionState& exceptionState)
{
if (data->length() - endOffset)
data->deleteData(endOffset, data->length() - endOffset, exceptionState);
@@ -779,21 +658,21 @@ static inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned
data->deleteData(0, startOffset, exceptionState);
}
-PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtr<DocumentFragment> fragment,
+PassRefPtrWillBeRawPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtrWillBeRawPtr<DocumentFragment> fragment,
Node* container, unsigned startOffset, unsigned endOffset, ExceptionState& exceptionState)
{
ASSERT(container);
ASSERT(startOffset <= endOffset);
- // This switch statement must be consistent with that of lengthOfContentsInNode.
- RefPtr<Node> result;
+ // This switch statement must be consistent with that of Node::lengthOfContents.
+ RefPtrWillBeRawPtr<Node> result = nullptr;
switch (container->nodeType()) {
case Node::TEXT_NODE:
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
endOffset = std::min(endOffset, toCharacterData(container)->length());
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
+ RefPtrWillBeRawPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
deleteCharacterData(c, startOffset, endOffset, exceptionState);
if (fragment) {
result = fragment;
@@ -807,7 +686,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
case Node::PROCESSING_INSTRUCTION_NODE:
endOffset = std::min(endOffset, toProcessingInstruction(container)->data().length());
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
+ RefPtrWillBeRawPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
c->setData(c->data().substring(startOffset, endOffset - startOffset));
if (fragment) {
result = fragment;
@@ -824,12 +703,9 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
break;
case Node::ELEMENT_NODE:
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
// FIXME: Should we assert that some nodes never appear here?
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
if (fragment)
@@ -839,7 +715,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
}
Node* n = container->firstChild();
- Vector<RefPtr<Node> > nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
for (unsigned i = startOffset; n && i; i--)
n = n->nextSibling();
for (unsigned i = startOffset; n && i < endOffset; i++, n = n->nextSibling())
@@ -852,7 +728,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
return result.release();
}
-void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionState& exceptionState)
+void Range::processNodes(ActionType action, WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes, PassRefPtrWillBeRawPtr<Node> oldContainer, PassRefPtrWillBeRawPtr<Node> newContainer, ExceptionState& exceptionState)
{
for (unsigned i = 0; i < nodes.size(); i++) {
switch (action) {
@@ -869,20 +745,20 @@ void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRe
}
}
-PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtrWillBeRawPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionState& exceptionState)
{
- typedef Vector<RefPtr<Node> > NodeVector;
+ typedef WillBeHeapVector<RefPtrWillBeMember<Node> > NodeVector;
- RefPtr<Node> clonedContainer = passedClonedContainer;
- Vector<RefPtr<Node> > ancestors;
+ RefPtrWillBeRawPtr<Node> clonedContainer = passedClonedContainer;
+ NodeVector ancestors;
for (ContainerNode* n = container->parentNode(); n && n != commonRoot; n = n->parentNode())
ancestors.append(n);
- RefPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
- for (Vector<RefPtr<Node> >::const_iterator it = ancestors.begin(); it != ancestors.end(); it++) {
- RefPtr<Node> ancestor = *it;
+ RefPtrWillBeRawPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
+ for (NodeVector::const_iterator it = ancestors.begin(); it != ancestors.end(); ++it) {
+ RefPtrWillBeRawPtr<Node> ancestor = *it;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- if (RefPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
+ if (RefPtrWillBeRawPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
clonedAncestor->appendChild(clonedContainer, exceptionState);
clonedContainer = clonedAncestor;
}
@@ -898,11 +774,14 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node
child = (direction == ProcessContentsForward) ? child->nextSibling() : child->previousSibling())
nodes.append(child);
- for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) {
+ for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
Node* child = it->get();
switch (action) {
case DELETE_CONTENTS:
- ancestor->removeChild(child, exceptionState);
+ // Prior call of ancestor->removeChild() may cause a tree change due to DOMSubtreeModified event.
+ // Therefore, we need to make sure |ancestor| is still |child|'s parent.
+ if (ancestor == child->parentNode())
+ ancestor->removeChild(child, exceptionState);
break;
case EXTRACT_CONTENTS: // will remove child from ancestor
if (direction == ProcessContentsForward)
@@ -924,36 +803,26 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node
return clonedContainer.release();
}
-PassRefPtr<DocumentFragment> Range::extractContents(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::extractContents(ExceptionState& exceptionState)
{
checkDeleteExtract(exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
return processContents(EXTRACT_CONTENTS, exceptionState);
}
-PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
return processContents(CLONE_CONTENTS, exceptionState);
}
-void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionState)
+void Range::insertNode(PassRefPtrWillBeRawPtr<Node> prpNewNode, ExceptionState& exceptionState)
{
- RefPtr<Node> newNode = prpNewNode;
-
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
+ RefPtrWillBeRawPtr<Node> newNode = prpNewNode;
if (!newNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -963,7 +832,7 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
// an extra one here - if a text node is going to split, it must have a parent to insert into
bool startIsText = m_start.container()->isTextNode();
if (startIsText && !m_start.container()->parentNode()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "This operation would split a text node, but there's no parent into which to insert.");
return;
}
@@ -980,9 +849,9 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE && !newNode->isShadowRoot()) {
// check each child node, not the DocumentFragment itself
numNewChildren = 0;
- for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) {
+ for (Node* c = toDocumentFragment(newNode)->firstChild(); c; c = c->nextSibling()) {
if (!checkAgainst->childTypeAllowed(c->nodeType())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node to be inserted contains a '" + c->nodeName() + "' node, which may not be inserted here.");
return;
}
++numNewChildren;
@@ -990,14 +859,14 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
} else {
numNewChildren = 1;
if (!checkAgainst->childTypeAllowed(newNodeType)) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node to be inserted is a '" + newNode->nodeName() + "' node, which may not be inserted here.");
return;
}
}
for (Node* n = m_start.container(); n; n = n->parentNode()) {
if (n == newNode) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node to be inserted contains the insertion point; it may not be inserted into itself.");
return;
}
}
@@ -1005,14 +874,12 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
// InvalidNodeTypeError: Raised if newNode is an Attr, Entity, Notation, ShadowRoot or Document node.
switch (newNodeType) {
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
case Node::DOCUMENT_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node to be inserted is a '" + newNode->nodeName() + "' node, which may not be inserted here.");
return;
default:
if (newNode->isShadowRoot()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node to be inserted is a shadow root, which may not be inserted here.");
return;
}
break;
@@ -1020,10 +887,10 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
EventQueueScope scope;
bool collapsed = m_start == m_end;
- RefPtr<Node> container;
+ RefPtrWillBeRawPtr<Node> container = nullptr;
if (startIsText) {
container = m_start.container();
- RefPtr<Text> newText = toText(container)->splitText(m_start.offset(), exceptionState);
+ RefPtrWillBeRawPtr<Text> newText = toText(container)->splitText(m_start.offset(), exceptionState);
if (exceptionState.hadException())
return;
@@ -1035,18 +902,18 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
if (collapsed)
m_end.setToBeforeChild(*newText);
} else {
- RefPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;
+ RefPtrWillBeRawPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? toDocumentFragment(newNode)->lastChild() : newNode.get();
if (lastChild && lastChild == m_start.childBefore()) {
// The insertion will do nothing, but we need to extend the range to include
// the inserted nodes.
- Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->firstChild() : newNode.get();
+ Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? toDocumentFragment(newNode)->firstChild() : newNode.get();
ASSERT(firstChild);
m_start.setToBeforeChild(*firstChild);
return;
}
container = m_start.container();
- container->insertBefore(newNode.release(), container->childNode(m_start.offset()), exceptionState);
+ container->insertBefore(newNode.release(), container->traverseToChildAt(m_start.offset()), exceptionState);
if (exceptionState.hadException())
return;
@@ -1057,22 +924,18 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
}
}
-String Range::toString(ExceptionState& exceptionState) const
+String Range::toString() const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return String();
- }
-
StringBuilder builder;
Node* pastLast = pastLastNode();
for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
- if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {
+ Node::NodeType type = n->nodeType();
+ if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
String data = toCharacterData(n)->data();
int length = data.length();
- int start = (n == m_start.container()) ? min(max(0, m_start.offset()), length) : 0;
- int end = (n == m_end.container()) ? min(max(start, m_end.offset()), length) : length;
+ int start = (n == m_start.container()) ? std::min(std::max(0, m_start.offset()), length) : 0;
+ int end = (n == m_end.container()) ? std::min(std::max(start, m_end.offset()), length) : length;
builder.append(data, start, end - start);
}
}
@@ -1087,79 +950,59 @@ String Range::toHTML() const
String Range::text() const
{
- if (!m_start.container())
- return String();
-
// We need to update layout, since plainText uses line boxes in the render tree.
// FIXME: As with innerText, we'd like this to work even if there are no render objects.
m_start.container()->document().updateLayout();
- return plainText(this);
+ return plainText(this, TextIteratorEmitsObjectReplacementCharacter);
}
-PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();
if (!element || !element->isHTMLElement()) {
exceptionState.throwDOMException(NotSupportedError, "The range's container must be an HTML element.");
- return 0;
+ return nullptr;
}
- RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState);
if (!fragment)
- return 0;
+ return nullptr;
return fragment.release();
}
-void Range::detach(ExceptionState& exceptionState)
+void Range::detach()
{
- // Check first to see if we've already detached:
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
- m_ownerDocument->detachRange(this);
-
- m_start.clear();
- m_end.clear();
+ // This is now a no-op as per the DOM specification.
}
Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionState& exceptionState) const
{
switch (n->nodeType()) {
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + n->nodeName() + "'.");
return 0;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::TEXT_NODE:
if (static_cast<unsigned>(offset) > toCharacterData(n)->length())
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than or equal to the node's length (" + String::number(toCharacterData(n)->length()) + ").");
return 0;
case Node::PROCESSING_INSTRUCTION_NODE:
if (static_cast<unsigned>(offset) > toProcessingInstruction(n)->data().length())
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than or equal to than the node's length (" + String::number(toProcessingInstruction(n)->data().length()) + ").");
return 0;
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
- case Node::ELEMENT_NODE:
- case Node::XPATH_NAMESPACE_NODE: {
+ case Node::ELEMENT_NODE: {
if (!offset)
return 0;
- Node* childBefore = n->childNode(offset - 1);
+ Node* childBefore = n->traverseToChildAt(offset - 1);
if (!childBefore)
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "There is no child at offset " + String::number(offset) + ".");
return childBefore;
}
}
@@ -1169,13 +1012,8 @@ Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionState& exceptionStat
void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!n) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1192,9 +1030,7 @@ void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + n->nodeName() + "'.");
return;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
@@ -1202,7 +1038,6 @@ void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
}
@@ -1219,23 +1054,15 @@ void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + n->nodeName() + "'.");
return;
}
}
-PassRefPtr<Range> Range::cloneRange(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<Range> Range::cloneRange() const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
}
@@ -1268,13 +1095,8 @@ void Range::setEndAfter(Node* refNode, ExceptionState& exceptionState)
void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1296,12 +1118,9 @@ void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided has an ancestor of type '" + anc->nodeName() + "'.");
return;
}
}
@@ -1313,14 +1132,11 @@ void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + refNode->nodeName() + "'.");
return;
}
@@ -1333,13 +1149,8 @@ void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1355,12 +1166,9 @@ void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + refNode->nodeName() + "'.");
return;
}
}
@@ -1368,21 +1176,15 @@ void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
if (m_ownerDocument != refNode->document())
setDocument(refNode->document());
- m_start.setToStartOfNode(refNode);
- m_end.setToEndOfNode(refNode);
+ m_start.setToStartOfNode(*refNode);
+ m_end.setToEndOfNode(*refNode);
}
-void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exceptionState)
+void Range::surroundContents(PassRefPtrWillBeRawPtr<Node> passNewParent, ExceptionState& exceptionState)
{
- RefPtr<Node> newParent = passNewParent;
-
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
+ RefPtrWillBeRawPtr<Node> newParent = passNewParent;
if (!newParent) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1393,16 +1195,13 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + newParent->nodeName() + "'.");
return;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
}
@@ -1414,13 +1213,19 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
// although this will fail below for another reason).
if (parentOfNewParent->isCharacterDataNode())
parentOfNewParent = parentOfNewParent->parentNode();
- if (!parentOfNewParent || !parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+
+ if (!parentOfNewParent) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The container node is a detached character data node; no parent node is available for insertion.");
+ return;
+ }
+
+ if (!parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is of type '" + newParent->nodeName() + "', which may not be inserted here.");
return;
}
if (newParent->contains(m_start.container())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided contains the insertion point; it may not be inserted into itself.");
return;
}
@@ -1435,7 +1240,7 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
if (endNonTextContainer->nodeType() == Node::TEXT_NODE)
endNonTextContainer = endNonTextContainer->parentNode();
if (startNonTextContainer != endNonTextContainer) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "The Range has partially selected a non-Text node.");
return;
}
@@ -1444,7 +1249,7 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
if (exceptionState.hadException())
return;
}
- RefPtr<DocumentFragment> fragment = extractContents(exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = extractContents(exceptionState);
if (exceptionState.hadException())
return;
insertNode(newParent, exceptionState);
@@ -1467,18 +1272,15 @@ void Range::setStartBefore(Node* refNode, ExceptionState& exceptionState)
void Range::checkDeleteExtract(ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
+ ASSERT(boundaryPointsValid());
- if (!commonAncestorContainer(exceptionState) || exceptionState.hadException())
+ if (!commonAncestorContainer())
return;
Node* pastLast = pastLastNode();
for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
- if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (n->isDocumentTypeNode()) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The Range contains a doctype node.");
return;
}
}
@@ -1486,11 +1288,9 @@ void Range::checkDeleteExtract(ExceptionState& exceptionState)
Node* Range::firstNode() const
{
- if (!m_start.container())
- return 0;
if (m_start.container()->offsetInCharacters())
return m_start.container();
- if (Node* child = m_start.container()->childNode(m_start.offset()))
+ if (Node* child = m_start.container()->traverseToChildAt(m_start.offset()))
return child;
if (!m_start.offset())
return m_start.container();
@@ -1504,11 +1304,9 @@ ShadowRoot* Range::shadowRoot() const
Node* Range::pastLastNode() const
{
- if (!m_start.container() || !m_end.container())
- return 0;
if (m_end.container()->offsetInCharacters())
return NodeTraversal::nextSkippingChildren(*m_end.container());
- if (Node* child = m_end.container()->childNode(m_end.offset()))
+ if (Node* child = m_end.container()->traverseToChildAt(m_end.offset()))
return child;
return NodeTraversal::nextSkippingChildren(*m_end.container());
}
@@ -1527,13 +1325,9 @@ IntRect Range::boundingBox() const
void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
{
Node* startContainer = m_start.container();
+ ASSERT(startContainer);
Node* endContainer = m_end.container();
-
- if (!startContainer || !endContainer) {
- if (inFixed)
- *inFixed = NotFixedPosition;
- return;
- }
+ ASSERT(endContainer);
bool allFixed = true;
bool someFixed = false;
@@ -1545,7 +1339,7 @@ void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFi
continue;
RenderText* renderText = toRenderText(r);
int startOffset = node == startContainer ? m_start.offset() : 0;
- int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+ int endOffset = node == endContainer ? m_end.offset() : std::numeric_limits<int>::max();
bool isFixed = false;
renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight, &isFixed);
allFixed &= isFixed;
@@ -1559,13 +1353,9 @@ void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFi
void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
{
Node* startContainer = m_start.container();
+ ASSERT(startContainer);
Node* endContainer = m_end.container();
-
- if (!startContainer || !endContainer) {
- if (inFixed)
- *inFixed = NotFixedPosition;
- return;
- }
+ ASSERT(endContainer);
bool allFixed = true;
bool someFixed = false;
@@ -1577,7 +1367,7 @@ void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeIn
continue;
RenderText* renderText = toRenderText(r);
int startOffset = node == startContainer ? m_start.offset() : 0;
- int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+ int endOffset = node == endContainer ? m_end.offset() : std::numeric_limits<int>::max();
bool isFixed = false;
renderText->absoluteQuadsForRange(quads, startOffset, endOffset, useSelectionHeight, &isFixed);
allFixed &= isFixed;
@@ -1592,24 +1382,19 @@ void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeIn
void Range::formatForDebugger(char* buffer, unsigned length) const
{
StringBuilder result;
- String s;
-
- if (!m_start.container() || !m_end.container())
- result.appendLiteral("<empty>");
- else {
- const int FormatBufferSize = 1024;
- char s[FormatBufferSize];
- result.appendLiteral("from offset ");
- result.appendNumber(m_start.offset());
- result.appendLiteral(" of ");
- m_start.container()->formatForDebugger(s, FormatBufferSize);
- result.append(s);
- result.appendLiteral(" to offset ");
- result.appendNumber(m_end.offset());
- result.appendLiteral(" of ");
- m_end.container()->formatForDebugger(s, FormatBufferSize);
- result.append(s);
- }
+
+ const int FormatBufferSize = 1024;
+ char s[FormatBufferSize];
+ result.appendLiteral("from offset ");
+ result.appendNumber(m_start.offset());
+ result.appendLiteral(" of ");
+ m_start.container()->formatForDebugger(s, FormatBufferSize);
+ result.append(s);
+ result.appendLiteral(" to offset ");
+ result.appendNumber(m_end.offset());
+ result.appendLiteral(" of ");
+ m_end.container()->formatForDebugger(s, FormatBufferSize);
+ result.append(s);
strncpy(buffer, result.toString().utf8().data(), length - 1);
}
@@ -1624,32 +1409,14 @@ bool areRangesEqual(const Range* a, const Range* b)
return a->startPosition() == b->startPosition() && a->endPosition() == b->endPosition();
}
-PassRefPtr<Range> rangeOfContents(Node* node)
+PassRefPtrWillBeRawPtr<Range> rangeOfContents(Node* node)
{
ASSERT(node);
- RefPtr<Range> range = Range::create(node->document());
+ RefPtrWillBeRawPtr<Range> range = Range::create(node->document());
range->selectNodeContents(node, IGNORE_EXCEPTION);
return range.release();
}
-int Range::maxStartOffset() const
-{
- if (!m_start.container())
- return 0;
- if (!m_start.container()->offsetInCharacters())
- return m_start.container()->childNodeCount();
- return m_start.container()->maxCharacterOffset();
-}
-
-int Range::maxEndOffset() const
-{
- if (!m_end.container())
- return 0;
- if (!m_end.container()->offsetInCharacters())
- return m_end.container()->childNodeCount();
- return m_end.container()->maxCharacterOffset();
-}
-
static inline void boundaryNodeChildrenChanged(RangeBoundaryPoint& boundary, ContainerNode* container)
{
if (!boundary.childBefore())
@@ -1667,9 +1434,9 @@ void Range::nodeChildrenChanged(ContainerNode* container)
boundaryNodeChildrenChanged(m_end, container);
}
-static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode* container)
+static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode& container)
{
- for (Node* nodeToBeRemoved = container->firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
+ for (Node* nodeToBeRemoved = container.firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
if (boundary.childBefore() == nodeToBeRemoved) {
boundary.setToStartOfNode(container);
return;
@@ -1684,10 +1451,9 @@ static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundar
}
}
-void Range::nodeChildrenWillBeRemoved(ContainerNode* container)
+void Range::nodeChildrenWillBeRemoved(ContainerNode& container)
{
- ASSERT(container);
- ASSERT(container->document() == m_ownerDocument);
+ ASSERT(container.document() == m_ownerDocument);
boundaryNodeChildrenWillBeRemoved(m_start, container);
boundaryNodeChildrenWillBeRemoved(m_end, container);
}
@@ -1710,7 +1476,7 @@ static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node&
void Range::nodeWillBeRemoved(Node& node)
{
ASSERT(node.document() == m_ownerDocument);
- ASSERT(node != m_ownerDocument);
+ ASSERT(node != m_ownerDocument.get());
// FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we
// should change following if-statement to ASSERT(!node->parentNode).
@@ -1759,46 +1525,58 @@ void Range::didRemoveText(Node* text, unsigned offset, unsigned length)
boundaryTextRemoved(m_end, text, offset, length);
}
-static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, NodeWithIndex& oldNode, unsigned offset)
+static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, const NodeWithIndex& oldNode, unsigned offset)
{
if (boundary.container() == oldNode.node())
- boundary.set(oldNode.node()->previousSibling(), boundary.offset() + offset, 0);
- else if (boundary.container() == oldNode.node()->parentNode() && boundary.offset() == oldNode.index())
- boundary.set(oldNode.node()->previousSibling(), offset, 0);
+ boundary.set(oldNode.node().previousSibling(), boundary.offset() + offset, 0);
+ else if (boundary.container() == oldNode.node().parentNode() && boundary.offset() == oldNode.index())
+ boundary.set(oldNode.node().previousSibling(), offset, 0);
}
-void Range::didMergeTextNodes(NodeWithIndex& oldNode, unsigned offset)
+void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset)
{
- ASSERT(oldNode.node());
- ASSERT(oldNode.node()->document() == m_ownerDocument);
- ASSERT(oldNode.node()->parentNode());
- ASSERT(oldNode.node()->isTextNode());
- ASSERT(oldNode.node()->previousSibling());
- ASSERT(oldNode.node()->previousSibling()->isTextNode());
+ ASSERT(oldNode.node().document() == m_ownerDocument);
+ ASSERT(oldNode.node().parentNode());
+ ASSERT(oldNode.node().isTextNode());
+ ASSERT(oldNode.node().previousSibling());
+ ASSERT(oldNode.node().previousSibling()->isTextNode());
boundaryTextNodesMerged(m_start, oldNode, offset);
boundaryTextNodesMerged(m_end, oldNode, offset);
}
-static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text* oldNode)
+void Range::updateOwnerDocumentIfNeeded()
{
- if (boundary.container() != oldNode)
+ ASSERT(m_start.container());
+ ASSERT(m_end.container());
+ Document& newDocument = m_start.container()->document();
+ ASSERT(newDocument == m_end.container()->document());
+ if (newDocument == m_ownerDocument)
return;
+ m_ownerDocument->detachRange(this);
+ m_ownerDocument = &newDocument;
+ m_ownerDocument->attachRange(this);
+}
+
+static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text& oldNode)
+{
+ Node* boundaryContainer = boundary.container();
unsigned boundaryOffset = boundary.offset();
- if (boundaryOffset <= oldNode->length())
- return;
- boundary.set(oldNode->nextSibling(), boundaryOffset - oldNode->length(), 0);
+ if (boundary.childBefore() == &oldNode)
+ boundary.set(boundaryContainer, boundaryOffset + 1, oldNode.nextSibling());
+ else if (boundary.container() == &oldNode && boundaryOffset > oldNode.length())
+ boundary.set(oldNode.nextSibling(), boundaryOffset - oldNode.length(), 0);
}
-void Range::didSplitTextNode(Text* oldNode)
+void Range::didSplitTextNode(Text& oldNode)
{
- ASSERT(oldNode);
- ASSERT(oldNode->document() == m_ownerDocument);
- ASSERT(oldNode->parentNode());
- ASSERT(oldNode->isTextNode());
- ASSERT(oldNode->nextSibling());
- ASSERT(oldNode->nextSibling()->isTextNode());
+ ASSERT(oldNode.document() == m_ownerDocument);
+ ASSERT(oldNode.parentNode());
+ ASSERT(oldNode.isTextNode());
+ ASSERT(oldNode.nextSibling());
+ ASSERT(oldNode.nextSibling()->isTextNode());
boundaryTextNodeSplit(m_start, oldNode);
boundaryTextNodeSplit(m_end, oldNode);
+ ASSERT(boundaryPointsValid());
}
void Range::expand(const String& unit, ExceptionState& exceptionState)
@@ -1823,11 +1601,8 @@ void Range::expand(const String& unit, ExceptionState& exceptionState)
setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), exceptionState);
}
-PassRefPtr<ClientRectList> Range::getClientRects() const
+PassRefPtrWillBeRawPtr<ClientRectList> Range::getClientRects() const
{
- if (!m_start.container())
- return ClientRectList::create();
-
m_ownerDocument->updateLayoutIgnorePendingStylesheets();
Vector<FloatQuad> quads;
@@ -1836,7 +1611,7 @@ PassRefPtr<ClientRectList> Range::getClientRects() const
return ClientRectList::create(quads);
}
-PassRefPtr<ClientRect> Range::getBoundingClientRect() const
+PassRefPtrWillBeRawPtr<ClientRect> Range::getBoundingClientRect() const
{
return ClientRect::create(boundingRect());
}
@@ -1861,7 +1636,7 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
renderBoxModelObject->absoluteQuads(elementQuads);
m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(elementQuads, *renderBoxModelObject);
- quads.append(elementQuads);
+ quads.appendVector(elementQuads);
}
}
} else if (node->isTextNode()) {
@@ -1874,7 +1649,7 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
renderText.absoluteQuadsForRange(textQuads, startOffset, endOffset);
m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(textQuads, renderText);
- quads.append(textQuads);
+ quads.appendVector(textQuads);
}
}
}
@@ -1882,9 +1657,6 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
FloatRect Range::boundingRect() const
{
- if (!m_start.container())
- return FloatRect();
-
m_ownerDocument->updateLayoutIgnorePendingStylesheets();
Vector<FloatQuad> quads;
@@ -1899,6 +1671,13 @@ FloatRect Range::boundingRect() const
return result;
}
+void Range::trace(Visitor* visitor)
+{
+ visitor->trace(m_ownerDocument);
+ visitor->trace(m_start);
+ visitor->trace(m_end);
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/dom/Range.h b/chromium/third_party/WebKit/Source/core/dom/Range.h
index 3a662f19cb0..bb0f7691761 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Range.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Range.h
@@ -30,9 +30,9 @@
#include "core/dom/RangeBoundaryPoint.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
namespace WebCore {
@@ -47,11 +47,11 @@ class Node;
class NodeWithIndex;
class Text;
-class Range : public RefCounted<Range>, public ScriptWrappable {
+class Range FINAL : public RefCountedWillBeGarbageCollectedFinalized<Range>, public ScriptWrappable {
public:
- static PassRefPtr<Range> create(Document&);
- static PassRefPtr<Range> create(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
- static PassRefPtr<Range> create(Document&, const Position&, const Position&);
+ static PassRefPtrWillBeRawPtr<Range> create(Document&);
+ static PassRefPtrWillBeRawPtr<Range> create(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
+ static PassRefPtrWillBeRawPtr<Range> create(Document&, const Position&, const Position&);
~Range();
Document& ownerDocument() const { ASSERT(m_ownerDocument); return *m_ownerDocument.get(); }
@@ -60,17 +60,13 @@ public:
Node* endContainer() const { return m_end.container(); }
int endOffset() const { return m_end.offset(); }
- Node* startContainer(ExceptionState&) const;
- int startOffset(ExceptionState&) const;
- Node* endContainer(ExceptionState&) const;
- int endOffset(ExceptionState&) const;
- bool collapsed(ExceptionState&) const;
+ bool collapsed() const { return m_start == m_end; }
- Node* commonAncestorContainer(ExceptionState&) const;
+ Node* commonAncestorContainer() const;
static Node* commonAncestorContainer(Node* containerA, Node* containerB);
- void setStart(PassRefPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
- void setEnd(PassRefPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
- void collapse(bool toStart, ExceptionState&);
+ void setStart(PassRefPtrWillBeRawPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void setEnd(PassRefPtrWillBeRawPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void collapse(bool toStart);
bool isPointInRange(Node* refNode, int offset, ExceptionState&);
short comparePoint(Node* refNode, int offset, ExceptionState&) const;
enum CompareResults { NODE_BEFORE, NODE_AFTER, NODE_BEFORE_AND_AFTER, NODE_INSIDE };
@@ -82,25 +78,25 @@ public:
bool boundaryPointsValid() const;
bool intersectsNode(Node* refNode, ExceptionState&);
void deleteContents(ExceptionState&);
- PassRefPtr<DocumentFragment> extractContents(ExceptionState&);
- PassRefPtr<DocumentFragment> cloneContents(ExceptionState&);
- void insertNode(PassRefPtr<Node>, ExceptionState&);
- String toString(ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<DocumentFragment> extractContents(ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> cloneContents(ExceptionState&);
+ void insertNode(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
+ String toString() const;
String toHTML() const;
String text() const;
- PassRefPtr<DocumentFragment> createContextualFragment(const String& html, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String& html, ExceptionState&);
- void detach(ExceptionState&);
- PassRefPtr<Range> cloneRange(ExceptionState&) const;
+ void detach();
+ PassRefPtrWillBeRawPtr<Range> cloneRange() const;
void setStartAfter(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void setEndBefore(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void setEndAfter(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void selectNode(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void selectNodeContents(Node*, ExceptionState&);
- void surroundContents(PassRefPtr<Node>, ExceptionState&);
+ void surroundContents(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
void setStartBefore(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
const Position startPosition() const { return m_start.toPosition(); }
@@ -129,26 +125,29 @@ public:
FloatRect boundingRect() const;
void nodeChildrenChanged(ContainerNode*);
- void nodeChildrenWillBeRemoved(ContainerNode*);
+ void nodeChildrenWillBeRemoved(ContainerNode&);
void nodeWillBeRemoved(Node&);
void didInsertText(Node*, unsigned offset, unsigned length);
void didRemoveText(Node*, unsigned offset, unsigned length);
- void didMergeTextNodes(NodeWithIndex& oldNode, unsigned offset);
- void didSplitTextNode(Text* oldNode);
+ void didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset);
+ void didSplitTextNode(Text& oldNode);
+ void updateOwnerDocumentIfNeeded();
// Expand range to a unit (word or sentence or block or document) boundary.
// Please refer to https://bugs.webkit.org/show_bug.cgi?id=27632 comment #5
// for details.
void expand(const String&, ExceptionState&);
- PassRefPtr<ClientRectList> getClientRects() const;
- PassRefPtr<ClientRect> getBoundingClientRect() const;
+ PassRefPtrWillBeRawPtr<ClientRectList> getClientRects() const;
+ PassRefPtrWillBeRawPtr<ClientRect> getBoundingClientRect() const;
#ifndef NDEBUG
void formatForDebugger(char* buffer, unsigned length) const;
#endif
+ void trace(Visitor*);
+
private:
explicit Range(Document&);
Range(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
@@ -158,22 +157,20 @@ private:
Node* checkNodeWOffset(Node*, int offset, ExceptionState&) const;
void checkNodeBA(Node*, ExceptionState&) const;
void checkDeleteExtract(ExceptionState&);
- int maxStartOffset() const;
- int maxEndOffset() const;
enum ActionType { DELETE_CONTENTS, EXTRACT_CONTENTS, CLONE_CONTENTS };
- PassRefPtr<DocumentFragment> processContents(ActionType, ExceptionState&);
- static PassRefPtr<Node> processContentsBetweenOffsets(ActionType, PassRefPtr<DocumentFragment>, Node*, unsigned startOffset, unsigned endOffset, ExceptionState&);
- static void processNodes(ActionType, Vector<RefPtr<Node> >&, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> processContents(ActionType, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Node> processContentsBetweenOffsets(ActionType, PassRefPtrWillBeRawPtr<DocumentFragment>, Node*, unsigned startOffset, unsigned endOffset, ExceptionState&);
+ static void processNodes(ActionType, WillBeHeapVector<RefPtrWillBeMember<Node> >&, PassRefPtrWillBeRawPtr<Node> oldContainer, PassRefPtrWillBeRawPtr<Node> newContainer, ExceptionState&);
enum ContentsProcessDirection { ProcessContentsForward, ProcessContentsBackward };
- static PassRefPtr<Node> processAncestorsAndTheirSiblings(ActionType, Node* container, ContentsProcessDirection, PassRefPtr<Node> clonedContainer, Node* commonRoot, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Node> processAncestorsAndTheirSiblings(ActionType, Node* container, ContentsProcessDirection, PassRefPtrWillBeRawPtr<Node> clonedContainer, Node* commonRoot, ExceptionState&);
- RefPtr<Document> m_ownerDocument; // Cannot be null.
+ RefPtrWillBeMember<Document> m_ownerDocument; // Cannot be null.
RangeBoundaryPoint m_start;
RangeBoundaryPoint m_end;
};
-PassRefPtr<Range> rangeOfContents(Node*);
+PassRefPtrWillBeRawPtr<Range> rangeOfContents(Node*);
bool areRangesEqual(const Range*, const Range*);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Range.idl b/chromium/third_party/WebKit/Source/core/dom/Range.idl
index d3dd1eb2f0e..e73f6d37add 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Range.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Range.idl
@@ -22,14 +22,15 @@
[
Constructor,
ConstructorCallWith=Document,
+ WillBeGarbageCollected,
] interface Range {
- [RaisesException=Getter] readonly attribute Node startContainer;
- [RaisesException=Getter] readonly attribute long startOffset;
- [RaisesException=Getter] readonly attribute Node endContainer;
- [RaisesException=Getter] readonly attribute long endOffset;
- [RaisesException=Getter] readonly attribute boolean collapsed;
- [RaisesException=Getter] readonly attribute Node commonAncestorContainer;
+ readonly attribute Node startContainer;
+ readonly attribute long startOffset;
+ readonly attribute Node endContainer;
+ readonly attribute long endOffset;
+ readonly attribute boolean collapsed;
+ readonly attribute Node commonAncestorContainer;
[RaisesException] void setStart(Node refNode, long offset);
[RaisesException] void setEnd(Node refNode, long offset);
@@ -37,7 +38,7 @@
[RaisesException] void setStartAfter(Node refNode);
[RaisesException] void setEndBefore(Node refNode);
[RaisesException] void setEndAfter(Node refNode);
- [RaisesException] void collapse([Default=Undefined] optional boolean toStart);
+ void collapse([Default=Undefined] optional boolean toStart);
[RaisesException] void selectNode(Node refNode);
[RaisesException] void selectNodeContents(Node refNode);
@@ -54,10 +55,10 @@
[RaisesException, CustomElementCallbacks] DocumentFragment cloneContents();
[RaisesException, CustomElementCallbacks] void insertNode(Node newNode);
[RaisesException, CustomElementCallbacks] void surroundContents(Node newParent);
- [RaisesException] Range cloneRange();
- [RaisesException] DOMString toString();
+ Range cloneRange();
+ DOMString toString();
- [RaisesException] void detach();
+ [DeprecateAs=RangeDetach] void detach();
[RaisesException] boolean isPointInRange(Node refNode, long offset);
[RaisesException] short comparePoint(Node refNode, long offset);
@@ -81,7 +82,7 @@
const unsigned short NODE_BEFORE_AND_AFTER = 2;
const unsigned short NODE_INSIDE = 3;
- [RaisesException] short compareNode([Default=Undefined] optional Node refNode);
+ [RaisesException, MeasureAs=RangeCompareNode] short compareNode([Default=Undefined] optional Node refNode);
- [RaisesException] void expand([Default=Undefined] optional DOMString unit);
+ [RaisesException, MeasureAs=RangeExpand] void expand([Default=Undefined] optional DOMString unit);
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h b/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
index 7574a89ef48..4df553bbff0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
@@ -32,8 +32,9 @@
namespace WebCore {
class RangeBoundaryPoint {
+ DISALLOW_ALLOCATION();
public:
- explicit RangeBoundaryPoint(PassRefPtr<Node> container);
+ explicit RangeBoundaryPoint(PassRefPtrWillBeRawPtr<Node> container);
explicit RangeBoundaryPoint(const RangeBoundaryPoint&);
@@ -45,29 +46,31 @@ public:
void clear();
- void set(PassRefPtr<Node> container, int offset, Node* childBefore);
+ void set(PassRefPtrWillBeRawPtr<Node> container, int offset, Node* childBefore);
void setOffset(int offset);
void setToBeforeChild(Node&);
- void setToStartOfNode(PassRefPtr<Node>);
- void setToEndOfNode(PassRefPtr<Node>);
+ void setToStartOfNode(Node&);
+ void setToEndOfNode(Node&);
void childBeforeWillBeRemoved();
void invalidateOffset() const;
void ensureOffsetIsValid() const;
+ void trace(Visitor*);
+
private:
static const int invalidOffset = -1;
- RefPtr<Node> m_containerNode;
+ RefPtrWillBeMember<Node> m_containerNode;
mutable int m_offsetInContainer;
- RefPtr<Node> m_childBeforeBoundary;
+ RefPtrWillBeMember<Node> m_childBeforeBoundary;
};
-inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
+inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtrWillBeRawPtr<Node> container)
: m_containerNode(container)
, m_offsetInContainer(0)
- , m_childBeforeBoundary(0)
+ , m_childBeforeBoundary(nullptr)
{
ASSERT(m_containerNode);
}
@@ -114,14 +117,14 @@ inline void RangeBoundaryPoint::clear()
{
m_containerNode.clear();
m_offsetInContainer = 0;
- m_childBeforeBoundary = 0;
+ m_childBeforeBoundary = nullptr;
}
-inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node* childBefore)
+inline void RangeBoundaryPoint::set(PassRefPtrWillBeRawPtr<Node> container, int offset, Node* childBefore)
{
ASSERT(container);
ASSERT(offset >= 0);
- ASSERT(childBefore == (offset ? container->childNode(offset - 1) : 0));
+ ASSERT(childBefore == (offset ? container->traverseToChildAt(offset - 1) : 0));
m_containerNode = container;
m_offsetInContainer = offset;
m_childBeforeBoundary = childBefore;
@@ -144,21 +147,19 @@ inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
}
-inline void RangeBoundaryPoint::setToStartOfNode(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToStartOfNode(Node& container)
{
- ASSERT(container);
- m_containerNode = container;
+ m_containerNode = &container;
m_offsetInContainer = 0;
- m_childBeforeBoundary = 0;
+ m_childBeforeBoundary = nullptr;
}
-inline void RangeBoundaryPoint::setToEndOfNode(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToEndOfNode(Node& container)
{
- ASSERT(container);
- m_containerNode = container;
+ m_containerNode = &container;
if (m_containerNode->offsetInCharacters()) {
m_offsetInContainer = m_containerNode->maxCharacterOffset();
- m_childBeforeBoundary = 0;
+ m_childBeforeBoundary = nullptr;
} else {
m_childBeforeBoundary = m_containerNode->lastChild();
m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
@@ -180,6 +181,12 @@ inline void RangeBoundaryPoint::invalidateOffset() const
m_offsetInContainer = invalidOffset;
}
+inline void RangeBoundaryPoint::trace(Visitor* visitor)
+{
+ visitor->trace(m_containerNode);
+ visitor->trace(m_childBeforeBoundary);
+}
+
inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
{
if (a.container() != b.container())
diff --git a/chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp b/chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp
new file mode 100644
index 00000000000..f27f44de1ba
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp
@@ -0,0 +1,144 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/Range.h"
+
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/Element.h"
+#include "core/dom/NodeList.h"
+#include "core/dom/Text.h"
+#include "core/html/HTMLBodyElement.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLElement.h"
+#include "core/html/HTMLHtmlElement.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Compiler.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicString.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class RangeTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ HTMLDocument& document() const;
+
+private:
+ RefPtrWillBePersistent<HTMLDocument> m_document;
+};
+
+void RangeTest::SetUp()
+{
+ m_document = HTMLDocument::create();
+ RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*m_document);
+ html->appendChild(HTMLBodyElement::create(*m_document));
+ m_document->appendChild(html.release());
+}
+
+HTMLDocument& RangeTest::document() const
+{
+ return *m_document;
+}
+
+TEST_F(RangeTest, SplitTextNodeRangeWithinText)
+{
+ document().body()->setInnerHTML("1234", ASSERT_NO_EXCEPTION);
+ Text* oldText = toText(document().body()->firstChild());
+
+ RefPtrWillBeRawPtr<Range> range04 = Range::create(document(), oldText, 0, oldText, 4);
+ RefPtrWillBeRawPtr<Range> range02 = Range::create(document(), oldText, 0, oldText, 2);
+ RefPtrWillBeRawPtr<Range> range22 = Range::create(document(), oldText, 2, oldText, 2);
+ RefPtrWillBeRawPtr<Range> range24 = Range::create(document(), oldText, 2, oldText, 4);
+
+ oldText->splitText(2, ASSERT_NO_EXCEPTION);
+ Text* newText = toText(oldText->nextSibling());
+
+ EXPECT_TRUE(range04->boundaryPointsValid());
+ EXPECT_EQ(oldText, range04->startContainer());
+ EXPECT_EQ(0, range04->startOffset());
+ EXPECT_EQ(newText, range04->endContainer());
+ EXPECT_EQ(2, range04->endOffset());
+
+ EXPECT_TRUE(range02->boundaryPointsValid());
+ EXPECT_EQ(oldText, range02->startContainer());
+ EXPECT_EQ(0, range02->startOffset());
+ EXPECT_EQ(oldText, range02->endContainer());
+ EXPECT_EQ(2, range02->endOffset());
+
+ // Our implementation always moves the boundary point at the separation point to the end of the original text node.
+ EXPECT_TRUE(range22->boundaryPointsValid());
+ EXPECT_EQ(oldText, range22->startContainer());
+ EXPECT_EQ(2, range22->startOffset());
+ EXPECT_EQ(oldText, range22->endContainer());
+ EXPECT_EQ(2, range22->endOffset());
+
+ EXPECT_TRUE(range24->boundaryPointsValid());
+ EXPECT_EQ(oldText, range24->startContainer());
+ EXPECT_EQ(2, range24->startOffset());
+ EXPECT_EQ(newText, range24->endContainer());
+ EXPECT_EQ(2, range24->endOffset());
+}
+
+TEST_F(RangeTest, SplitTextNodeRangeOutsideText)
+{
+ document().body()->setInnerHTML("<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span id=\"inner-right\">2</span>3</span>", ASSERT_NO_EXCEPTION);
+
+ Element* outer = document().getElementById(AtomicString::fromUTF8("outer"));
+ Element* innerLeft = document().getElementById(AtomicString::fromUTF8("inner-left"));
+ Element* innerRight = document().getElementById(AtomicString::fromUTF8("inner-right"));
+ Text* oldText = toText(outer->childNodes()->item(2));
+
+ RefPtrWillBeRawPtr<Range> rangeOuterOutside = Range::create(document(), outer, 0, outer, 5);
+ RefPtrWillBeRawPtr<Range> rangeOuterInside = Range::create(document(), outer, 1, outer, 4);
+ RefPtrWillBeRawPtr<Range> rangeOuterSurroundingText = Range::create(document(), outer, 2, outer, 3);
+ RefPtrWillBeRawPtr<Range> rangeInnerLeft = Range::create(document(), innerLeft, 0, innerLeft, 1);
+ RefPtrWillBeRawPtr<Range> rangeInnerRight = Range::create(document(), innerRight, 0, innerRight, 1);
+ RefPtrWillBeRawPtr<Range> rangeFromTextToMiddleOfElement = Range::create(document(), oldText, 6, outer, 3);
+
+ oldText->splitText(3, ASSERT_NO_EXCEPTION);
+ Text* newText = toText(oldText->nextSibling());
+
+ EXPECT_TRUE(rangeOuterOutside->boundaryPointsValid());
+ EXPECT_EQ(outer, rangeOuterOutside->startContainer());
+ EXPECT_EQ(0, rangeOuterOutside->startOffset());
+ EXPECT_EQ(outer, rangeOuterOutside->endContainer());
+ EXPECT_EQ(6, rangeOuterOutside->endOffset()); // Increased by 1 since a new node is inserted.
+
+ EXPECT_TRUE(rangeOuterInside->boundaryPointsValid());
+ EXPECT_EQ(outer, rangeOuterInside->startContainer());
+ EXPECT_EQ(1, rangeOuterInside->startOffset());
+ EXPECT_EQ(outer, rangeOuterInside->endContainer());
+ EXPECT_EQ(5, rangeOuterInside->endOffset());
+
+ EXPECT_TRUE(rangeOuterSurroundingText->boundaryPointsValid());
+ EXPECT_EQ(outer, rangeOuterSurroundingText->startContainer());
+ EXPECT_EQ(2, rangeOuterSurroundingText->startOffset());
+ EXPECT_EQ(outer, rangeOuterSurroundingText->endContainer());
+ EXPECT_EQ(4, rangeOuterSurroundingText->endOffset());
+
+ EXPECT_TRUE(rangeInnerLeft->boundaryPointsValid());
+ EXPECT_EQ(innerLeft, rangeInnerLeft->startContainer());
+ EXPECT_EQ(0, rangeInnerLeft->startOffset());
+ EXPECT_EQ(innerLeft, rangeInnerLeft->endContainer());
+ EXPECT_EQ(1, rangeInnerLeft->endOffset());
+
+ EXPECT_TRUE(rangeInnerRight->boundaryPointsValid());
+ EXPECT_EQ(innerRight, rangeInnerRight->startContainer());
+ EXPECT_EQ(0, rangeInnerRight->startOffset());
+ EXPECT_EQ(innerRight, rangeInnerRight->endContainer());
+ EXPECT_EQ(1, rangeInnerRight->endOffset());
+
+ EXPECT_TRUE(rangeFromTextToMiddleOfElement->boundaryPointsValid());
+ EXPECT_EQ(newText, rangeFromTextToMiddleOfElement->startContainer());
+ EXPECT_EQ(3, rangeFromTextToMiddleOfElement->startOffset());
+ EXPECT_EQ(outer, rangeFromTextToMiddleOfElement->endContainer());
+ EXPECT_EQ(4, rangeFromTextToMiddleOfElement->endOffset());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h
index f2adeed32f8..ade8afe00b6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h
@@ -38,7 +38,7 @@ protected:
{
}
- virtual void finish()
+ virtual void finish() OVERRIDE
{
if (!isStopped())
document()->finishedParsing();
@@ -51,11 +51,11 @@ private:
appendBytes(0, 0);
}
- virtual void insert(const SegmentedString&)
+ virtual void insert(const SegmentedString&) OVERRIDE
{
}
- virtual void append(PassRefPtr<StringImpl>)
+ virtual void append(PassRefPtr<StringImpl>) OVERRIDE
{
ASSERT_NOT_REACHED();
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp
new file mode 100644
index 00000000000..974a1fa5c53
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/RenderTreeBuilder.h"
+
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/FullscreenElementStack.h"
+#include "core/dom/Node.h"
+#include "core/dom/Text.h"
+#include "core/rendering/RenderFullScreen.h"
+#include "core/rendering/RenderObject.h"
+#include "core/rendering/RenderText.h"
+#include "core/rendering/RenderView.h"
+#include "core/svg/SVGElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
+namespace WebCore {
+
+RenderObject* RenderTreeBuilder::nextRenderer() const
+{
+ ASSERT(m_renderingParent);
+
+ Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
+
+ if (element && element->isInTopLayer())
+ return NodeRenderingTraversal::nextInTopLayer(element);
+
+ // Avoid an O(N^2) walk over the children when reattaching all children of a node.
+ if (m_renderingParent->needsAttach())
+ return 0;
+
+ return NodeRenderingTraversal::nextSiblingRenderer(m_node);
+}
+
+RenderObject* RenderTreeBuilder::parentRenderer() const
+{
+ ASSERT(m_renderingParent);
+
+ Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
+
+ if (element && m_renderingParent->renderer()) {
+ // FIXME: Guarding this by m_renderingParent->renderer() isn't quite right as the spec for
+ // top layer only talks about display: none ancestors so putting a <dialog> inside an
+ // <optgroup> seems like it should still work even though this check will prevent it.
+ if (element->isInTopLayer())
+ return m_node->document().renderView();
+ }
+
+ return m_renderingParent->renderer();
+}
+
+bool RenderTreeBuilder::shouldCreateRenderer() const
+{
+ if (!m_renderingParent)
+ return false;
+ if (m_node->isSVGElement()) {
+ // SVG elements only render when inside <svg>, or if the element is an <svg> itself.
+ if (!isSVGSVGElement(*m_node) && !m_renderingParent->isSVGElement())
+ return false;
+ if (!toSVGElement(m_node)->isValid())
+ return false;
+ }
+ RenderObject* parentRenderer = this->parentRenderer();
+ if (!parentRenderer)
+ return false;
+ if (!parentRenderer->canHaveChildren())
+ return false;
+ return true;
+}
+
+RenderStyle& RenderTreeBuilder::style() const
+{
+ if (!m_style)
+ m_style = toElement(m_node)->styleForRenderer();
+ return *m_style;
+}
+
+void RenderTreeBuilder::createRendererForElementIfNeeded()
+{
+ ASSERT(!m_node->renderer());
+
+ if (!shouldCreateRenderer())
+ return;
+
+ Element* element = toElement(m_node);
+ RenderStyle& style = this->style();
+
+ if (!element->rendererIsNeeded(style))
+ return;
+
+ RenderObject* newRenderer = element->createRenderer(&style);
+ if (!newRenderer)
+ return;
+
+ RenderObject* parentRenderer = this->parentRenderer();
+
+ if (!parentRenderer->isChildAllowed(newRenderer, &style)) {
+ newRenderer->destroy();
+ return;
+ }
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
+
+ RenderObject* nextRenderer = this->nextRenderer();
+ element->setRenderer(newRenderer);
+ newRenderer->setStyle(&style); // setStyle() can depend on renderer() already being set.
+
+ if (FullscreenElementStack::isActiveFullScreenElement(element)) {
+ newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &element->document());
+ if (!newRenderer)
+ return;
+ }
+
+ // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
+ parentRenderer->addChild(newRenderer, nextRenderer);
+}
+
+void RenderTreeBuilder::createRendererForTextIfNeeded()
+{
+ ASSERT(!m_node->renderer());
+
+ if (!shouldCreateRenderer())
+ return;
+
+ Text* textNode = toText(m_node);
+ RenderObject* parentRenderer = this->parentRenderer();
+
+ m_style = parentRenderer->style();
+
+ if (!textNode->textRendererIsNeeded(*m_style, *parentRenderer))
+ return;
+
+ RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
+ if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
+ newRenderer->destroy();
+ return;
+ }
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
+
+ RenderObject* nextRenderer = this->nextRenderer();
+ textNode->setRenderer(newRenderer);
+ // Parent takes care of the animations, no need to call setAnimatableStyle.
+ newRenderer->setStyle(m_style.release());
+ parentRenderer->addChild(newRenderer, nextRenderer);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h
index ac2bab3b580..b92b1af8a94 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h
@@ -23,52 +23,54 @@
*
*/
-#ifndef NodeRenderingContext_h
-#define NodeRenderingContext_h
+#ifndef RenderTreeBuilder_h
+#define RenderTreeBuilder_h
+#include "core/dom/Document.h"
+#include "core/dom/Node.h"
#include "core/dom/NodeRenderingTraversal.h"
-
#include "wtf/RefPtr.h"
namespace WebCore {
class ContainerNode;
-class Node;
-class RenderNamedFlowThread;
class RenderObject;
class RenderStyle;
-class NodeRenderingContext {
+class RenderTreeBuilder {
+ STACK_ALLOCATED();
public:
- explicit NodeRenderingContext(Node* node, RenderStyle* style = 0)
+ RenderTreeBuilder(Node* node, RenderStyle* style)
: m_node(node)
- , m_renderingParent(0)
+ , m_renderingParent(nullptr)
, m_style(style)
- , m_parentFlowRenderer(0)
{
+ ASSERT(!node->renderer());
+ ASSERT(node->needsAttach());
+ ASSERT(node->document().inStyleRecalc());
+
+ // FIXME: We should be able to ASSERT(node->inActiveDocument()) but childrenChanged is called
+ // before ChildNodeInsertionNotifier in ContainerNode's methods and some implementations
+ // will trigger a layout inside childrenChanged.
+ // Mainly HTMLTextAreaElement::childrenChanged calls HTMLTextFormControlElement::setSelectionRange
+ // which does an updateLayoutIgnorePendingStylesheets.
+
m_renderingParent = NodeRenderingTraversal::parent(node, &m_parentDetails);
}
void createRendererForTextIfNeeded();
void createRendererForElementIfNeeded();
- Node* node() const { return m_node; }
+private:
RenderObject* parentRenderer() const;
RenderObject* nextRenderer() const;
- RenderObject* previousRenderer() const;
-
- const RenderStyle* style() const { return m_style.get(); }
-
-private:
bool shouldCreateRenderer() const;
- void moveToFlowThreadIfNeeded();
- bool elementInsideRegionNeedsRenderer();
+ RenderStyle& style() const;
- Node* m_node;
- ContainerNode* m_renderingParent;
+ RawPtrWillBeMember<Node> m_node;
+ RawPtrWillBeMember<ContainerNode> m_renderingParent;
NodeRenderingTraversal::ParentDetails m_parentDetails;
- RefPtr<RenderStyle> m_style;
- RenderNamedFlowThread* m_parentFlowRenderer;
+ mutable RefPtr<RenderStyle> m_style;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h b/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h
index 9e6966a225f..2fd4b50bf5e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h
@@ -62,11 +62,15 @@ inline void RenderedDocumentMarker::invalidate(const LayoutRect& r)
invalidate();
}
-inline RenderedDocumentMarker* toRenderedDocumentMarker(DocumentMarker* marker)
-{
- return static_cast<RenderedDocumentMarker*>(marker);
-}
+DEFINE_TYPE_CASTS(RenderedDocumentMarker, DocumentMarker, marker, true, true);
} // namespace
+namespace WTF {
+
+template<>
+struct VectorTraits<WebCore::RenderedDocumentMarker> : SimpleClassVectorTraits<WebCore::RenderedDocumentMarker> { };
+
+} // namespace WTF
+
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp
index 1ebd0c3fe66..8d8e01c2f79 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp
@@ -65,6 +65,8 @@ SandboxFlags parseSandboxPolicy(const String& policy, String& invalidTokensError
flags &= ~SandboxPopups;
} else if (equalIgnoringCase(sandboxToken, "allow-pointer-lock")) {
flags &= ~SandboxPointerLock;
+ } else if (equalIgnoringCase(sandboxToken, "allow-orientation-lock")) {
+ flags &= ~SandboxOrientationLock;
} else {
if (numberOfTokenErrors)
tokenErrors.appendLiteral(", '");
diff --git a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h
index fa072d1ea9e..3e980d9d610 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h
+++ b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h
@@ -42,9 +42,9 @@ enum SandboxFlag {
SandboxTopNavigation = 1 << 5,
SandboxPopups = 1 << 6, // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=12393
SandboxAutomaticFeatures = 1 << 7,
- SandboxSeamlessIframes = 1 << 8,
- SandboxPointerLock = 1 << 9,
- SandboxDocumentDomain = 1 << 10,
+ SandboxPointerLock = 1 << 8,
+ SandboxDocumentDomain = 1 << 9,
+ SandboxOrientationLock = 1 << 10, // See https://w3c.github.io/screen-orientation/#dfn-sandboxed-orientation-lock-browsing-context-flag.
SandboxAll = -1 // Mask with all bits set to 1.
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp
new file mode 100644
index 00000000000..81540dcb6f3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/ScriptForbiddenScope.h"
+
+#include "wtf/Assertions.h"
+#include "wtf/MainThread.h"
+
+namespace WebCore {
+
+#if ASSERT_ENABLED
+
+static unsigned s_scriptForbiddenCount = 0;
+
+ScriptForbiddenScope::ScriptForbiddenScope()
+{
+ ASSERT(isMainThread());
+ ++s_scriptForbiddenCount;
+}
+
+ScriptForbiddenScope::~ScriptForbiddenScope()
+{
+ ASSERT(isMainThread());
+ --s_scriptForbiddenCount;
+}
+
+bool ScriptForbiddenScope::isScriptForbidden()
+{
+ return isMainThread() && s_scriptForbiddenCount;
+}
+
+ScriptForbiddenScope::AllowUserAgentScript::AllowUserAgentScript()
+ : m_change(s_scriptForbiddenCount, 0)
+{
+}
+
+ScriptForbiddenScope::AllowUserAgentScript::~AllowUserAgentScript()
+{
+ ASSERT(!s_scriptForbiddenCount);
+}
+
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h
new file mode 100644
index 00000000000..7425b6cb943
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ScriptForbiddenScope_h
+#define ScriptForbiddenScope_h
+
+#include "wtf/Assertions.h"
+#include "wtf/TemporaryChange.h"
+
+namespace WebCore {
+
+#if ASSERT_ENABLED
+
+class ScriptForbiddenScope {
+public:
+ ScriptForbiddenScope();
+ ~ScriptForbiddenScope();
+
+ class AllowUserAgentScript {
+ public:
+ AllowUserAgentScript();
+ ~AllowUserAgentScript();
+ private:
+ TemporaryChange<unsigned> m_change;
+ };
+
+ static bool isScriptForbidden();
+};
+
+#else
+
+class ScriptForbiddenScope {
+public:
+ ScriptForbiddenScope() { }
+ class AllowUserAgentScript {
+ public:
+ AllowUserAgentScript() { }
+ };
+ static bool isScriptForbidden() { return false; }
+};
+
+#endif
+
+} // namespace WebCore
+
+#endif // ScriptForbiddenScope_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index eaa0e45da91..e5b9a3be4bb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -24,10 +24,10 @@
#include "config.h"
#include "core/dom/ScriptLoader.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
@@ -38,11 +38,11 @@
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ScriptResource.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLScriptElement.h"
+#include "core/html/imports/HTMLImport.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/svg/SVGScriptElement.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -65,7 +65,6 @@ ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt
, m_willExecuteWhenDocumentFinishedParsing(false)
, m_forceAsync(!parserInserted)
, m_willExecuteInOrder(false)
- , m_isPotentiallyCORSEnabled(false)
{
ASSERT(m_element);
if (parserInserted && element->document().scriptableDocumentParser() && !element->document().isInDocumentWrite())
@@ -116,7 +115,6 @@ static bool isLegacySupportedJavaScriptLanguage(const String& language)
DEFINE_STATIC_LOCAL(LanguageSet, languages, ());
if (languages.isEmpty()) {
languages.add("javascript");
- languages.add("javascript");
languages.add("javascript1.0");
languages.add("javascript1.1");
languages.add("javascript1.2");
@@ -159,7 +157,7 @@ bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) c
type = "text/" + language.lower();
if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
return true;
- } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
+ } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
return true;
}
@@ -227,7 +225,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
m_willBeParserExecuted = true;
} else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) {
m_willBeParserExecuted = true;
- } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.haveStylesheetsAndImportsLoaded()) {
+ } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.isRenderingReady()) {
m_willBeParserExecuted = true;
m_readyToBeParserExecuted = true;
} else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
@@ -241,8 +239,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
// Reset line numbering for nested writes.
TextPosition position = elementDocument.isInDocumentWrite() ? TextPosition() : scriptStartPosition;
KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) ? elementDocument.url() : KURL();
- if (!executePotentiallyCrossOriginScript(ScriptSourceCode(scriptContent(), scriptURL, position)))
- return false;
+ executeScript(ScriptSourceCode(scriptContent(), scriptURL, position));
}
return true;
@@ -252,9 +249,7 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
{
ASSERT(m_element);
- RefPtr<Document> elementDocument(m_element->document());
- if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
- return false;
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
if (!m_element->inDocument() || m_element->document() != elementDocument)
return false;
@@ -262,12 +257,9 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName());
- String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
- if (!crossOriginMode.isNull()) {
- StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- request.setCrossOriginAccessControl(elementDocument->securityOrigin(), allowCredentials);
- m_isPotentiallyCORSEnabled = true;
- }
+ AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull())
+ request.setCrossOriginAccessControl(elementDocument->securityOrigin(), crossOriginMode);
request.setCharset(scriptCharset());
bool isValidScriptNonce = elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
@@ -287,12 +279,14 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
bool isHTMLScriptLoader(Element* element)
{
- return element->hasTagName(HTMLNames::scriptTag);
+ ASSERT(element);
+ return isHTMLScriptElement(*element);
}
bool isSVGScriptLoader(Element* element)
{
- return element->hasTagName(SVGNames::scriptTag);
+ ASSERT(element);
+ return isSVGScriptElement(*element);
}
void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
@@ -302,31 +296,37 @@ void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
if (sourceCode.isEmpty())
return;
- RefPtr<Document> elementDocument(m_element->document());
- RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
+ RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
if (!contextDocument)
return;
- Frame* frame = contextDocument->frame();
+ LocalFrame* frame = contextDocument->frame();
bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script().shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)) || elementDocument->contentSecurityPolicy()->allowScriptHash(sourceCode.source());
if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url(), m_startLineNumber)))
return;
- if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosniff()) {
- contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_resource->url().elidedString() + "' because its MIME type ('" + m_resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
- return;
+ if (m_isExternalScript) {
+ ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.resource();
+ if (resource && !resource->mimeTypeAllowedByNosniff()) {
+ contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->url().elidedString() + "' because its MIME type ('" + resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
+ return;
+ }
}
if (frame) {
- IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? contextDocument.get() : 0);
+ const bool isImportedScript = contextDocument != elementDocument;
+ // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block step 2.3
+ // with additional support for HTML imports.
+ IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_isExternalScript || isImportedScript ? contextDocument.get() : 0);
if (isHTMLScriptLoader(m_element))
contextDocument->pushCurrentScript(toHTMLScriptElement(m_element));
AccessControlStatus corsCheck = NotSharableCrossOrigin;
- if (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin()))
+ if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin())))
corsCheck = SharableCrossOrigin;
// Create a script from the script element node, using the script
@@ -363,24 +363,12 @@ void ScriptLoader::execute(ScriptResource* resource)
resource->removeClient(this);
}
-bool ScriptLoader::executePotentiallyCrossOriginScript(const ScriptSourceCode& sourceCode)
-{
- if (sourceCode.resource()
- && isPotentiallyCORSEnabled()
- && !m_element->document().fetcher()->canAccess(sourceCode.resource(), PotentiallyCORSEnabled)) {
- dispatchErrorEvent();
- return false;
- }
- executeScript(sourceCode);
- return true;
-}
-
void ScriptLoader::notifyFinished(Resource* resource)
{
ASSERT(!m_willBeParserExecuted);
- RefPtr<Document> elementDocument(m_element->document());
- RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
+ RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
if (!contextDocument)
return;
@@ -391,13 +379,11 @@ void ScriptLoader::notifyFinished(Resource* resource)
ASSERT_UNUSED(resource, resource == m_resource);
if (!m_resource)
return;
- CORSEnabled corsEnabled = isPotentiallyCORSEnabled() ? PotentiallyCORSEnabled : NotCORSEnabled;
- if (!elementDocument->fetcher()->canAccess(m_resource.get(), corsEnabled)) {
+ if (m_resource->errorOccurred()) {
dispatchErrorEvent();
contextDocument->scriptRunner()->notifyScriptLoadError(this, m_willExecuteInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION);
return;
}
-
if (m_willExecuteInOrder)
contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
else
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h
index 72f51972005..83acaecfe42 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h
@@ -35,7 +35,7 @@ class ScriptLoaderClient;
class ScriptSourceCode;
-class ScriptLoader : private ResourceClient {
+class ScriptLoader FINAL : private ResourceClient {
public:
static PassOwnPtr<ScriptLoader> create(Element*, bool createdByParser, bool isEvaluated);
virtual ~ScriptLoader();
@@ -50,12 +50,6 @@ public:
void executeScript(const ScriptSourceCode&);
void execute(ScriptResource*);
- // Check if potentially cross-origin enabled script is accessible
- // prior to execution. Returns 'false' if not accessible, signalling
- // that callers must not dispatch load events as the cross-origin
- // fetch failed.
- bool executePotentiallyCrossOriginScript(const ScriptSourceCode&);
-
// XML parser calls these
void dispatchLoadEvent();
void dispatchErrorEvent();
@@ -71,7 +65,6 @@ public:
bool isParserInserted() const { return m_parserInserted; }
bool alreadyStarted() const { return m_alreadyStarted; }
bool forceAsync() const { return m_forceAsync; }
- bool isPotentiallyCORSEnabled() const { return m_isPotentiallyCORSEnabled; }
// Helper functions used by our parent classes.
void didNotifySubtreeInsertionsToDocument();
@@ -105,7 +98,6 @@ private:
bool m_willExecuteWhenDocumentFinishedParsing : 1;
bool m_forceAsync : 1;
bool m_willExecuteInOrder : 1;
- bool m_isPotentiallyCORSEnabled : 1;
String m_characterEncoding;
String m_fallbackCharacterEncoding;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
index 2fbf959c598..21798469eed 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
@@ -31,6 +31,7 @@
#include "core/dom/PendingScript.h"
#include "core/dom/ScriptLoader.h"
#include "core/fetch/ScriptResource.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -43,12 +44,6 @@ ScriptRunner::ScriptRunner(Document* document)
ScriptRunner::~ScriptRunner()
{
- for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i)
- m_document->decrementLoadEventDelayCount();
- for (size_t i = 0; i < m_scriptsToExecuteInOrder.size(); ++i)
- m_document->decrementLoadEventDelayCount();
- for (size_t i = 0; i < m_pendingAsyncScripts.size(); ++i)
- m_document->decrementLoadEventDelayCount();
}
void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, ResourcePtr<ScriptResource> resource, ExecutionType executionType)
@@ -81,7 +76,7 @@ void ScriptRunner::suspend()
void ScriptRunner::resume()
{
if (hasPendingScripts())
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
}
void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType executionType)
@@ -96,7 +91,7 @@ void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType e
ASSERT(!m_scriptsToExecuteInOrder.isEmpty());
break;
}
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
}
void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, ExecutionType executionType)
@@ -118,7 +113,7 @@ void ScriptRunner::timerFired(Timer<ScriptRunner>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
- RefPtr<Document> protect(m_document);
+ RefPtrWillBeRawPtr<Document> protect(m_document.get());
Vector<PendingScript> scripts;
scripts.swap(m_scriptsToExecuteSoon);
@@ -132,10 +127,18 @@ void ScriptRunner::timerFired(Timer<ScriptRunner>* timer)
size_t size = scripts.size();
for (size_t i = 0; i < size; ++i) {
ScriptResource* resource = scripts[i].resource();
- RefPtr<Element> element = scripts[i].releaseElementAndClear();
+ RefPtrWillBeRawPtr<Element> element = scripts[i].releaseElementAndClear();
toScriptLoaderIfPossible(element.get())->execute(resource);
m_document->decrementLoadEventDelayCount();
}
}
+void ScriptRunner::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_scriptsToExecuteInOrder);
+ visitor->trace(m_scriptsToExecuteSoon);
+ visitor->trace(m_pendingAsyncScripts);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h
index b47139c8629..a24ca26a090 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h
@@ -28,6 +28,7 @@
#include "core/fetch/ResourcePtr.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
@@ -40,10 +41,13 @@ class Document;
class PendingScript;
class ScriptLoader;
-class ScriptRunner {
- WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED;
+class ScriptRunner FINAL : public NoBaseWillBeGarbageCollectedFinalized<ScriptRunner> {
+ WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ScriptRunner> create(Document* document) { return adoptPtr(new ScriptRunner(document)); }
+ static PassOwnPtrWillBeRawPtr<ScriptRunner> create(Document* document)
+ {
+ return adoptPtrWillBeNoop(new ScriptRunner(document));
+ }
~ScriptRunner();
enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
@@ -54,12 +58,16 @@ public:
void notifyScriptReady(ScriptLoader*, ExecutionType);
void notifyScriptLoadError(ScriptLoader*, ExecutionType);
+ void trace(Visitor*);
+
private:
explicit ScriptRunner(Document*);
void timerFired(Timer<ScriptRunner>*);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
+ // FIXME: Oilpan: consider using heap vectors and hash map here;
+ // PendingScript does have a (trivial) destructor, however.
Vector<PendingScript> m_scriptsToExecuteInOrder;
Vector<PendingScript> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
HashMap<ScriptLoader*, PendingScript> m_pendingAsyncScripts;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp
index 5e8f2f39a2b..6d00efb4b66 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp
@@ -31,12 +31,12 @@
namespace WebCore {
-ScriptableDocumentParser::ScriptableDocumentParser(Document* document, ParserContentPolicy parserContentPolicy)
+ScriptableDocumentParser::ScriptableDocumentParser(Document& document, ParserContentPolicy parserContentPolicy)
: DecodedDataDocumentParser(document)
, m_wasCreatedByScript(false)
, m_parserContentPolicy(parserContentPolicy)
{
- if (!pluginContentIsAllowed(m_parserContentPolicy) && (!document->settings() || document->settings()->unsafePluginPastingEnabled()))
+ if (!pluginContentIsAllowed(m_parserContentPolicy) && (!document.settings() || document.settings()->unsafePluginPastingEnabled()))
m_parserContentPolicy = allowPluginContent(m_parserContentPolicy);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h
index 18a2f93310f..f5c3867d4d9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h
@@ -54,10 +54,10 @@ public:
ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
protected:
- explicit ScriptableDocumentParser(Document*, ParserContentPolicy = AllowScriptingContent);
+ explicit ScriptableDocumentParser(Document&, ParserContentPolicy = AllowScriptingContent);
private:
- virtual ScriptableDocumentParser* asScriptableDocumentParser() { return this; }
+ virtual ScriptableDocumentParser* asScriptableDocumentParser() OVERRIDE FINAL { return this; }
// http://www.whatwg.org/specs/web-apps/current-work/#script-created-parser
bool m_wasCreatedByScript;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
index 27a7f6b463f..3f5f9b9e410 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
@@ -29,9 +29,10 @@
#include "core/dom/Document.h"
#include "core/dom/RequestAnimationFrameCallback.h"
#include "core/events/Event.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/DocumentLoader.h"
namespace WebCore {
@@ -52,6 +53,15 @@ ScriptedAnimationController::~ScriptedAnimationController()
{
}
+void ScriptedAnimationController::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_eventQueue);
+#if ENABLE(OILPAN)
+ visitor->trace(m_perFrameEvents);
+#endif
+}
+
void ScriptedAnimationController::suspend()
{
++m_suspendCount;
@@ -74,6 +84,9 @@ ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCal
m_callbacks.append(callback);
scheduleAnimationIfNeeded();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RequestAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, id));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didRequestAnimationFrame(m_document, id);
return id;
@@ -83,6 +96,9 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
{
for (size_t i = 0; i < m_callbacks.size(); ++i) {
if (m_callbacks[i]->m_id == id) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "CancelAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, id));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didCancelAnimationFrame(m_document, id);
m_callbacks.remove(i);
return;
@@ -90,6 +106,9 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
}
for (size_t i = 0; i < m_callbacksToInvoke.size(); ++i) {
if (m_callbacksToInvoke[i]->m_id == id) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "CancelAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, id));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didCancelAnimationFrame(m_document, id);
m_callbacksToInvoke[i]->m_cancelled = true;
// will be removed at the end of executeCallbacks()
@@ -100,7 +119,7 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
void ScriptedAnimationController::dispatchEvents()
{
- Vector<RefPtr<Event> > events;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > events;
events.swap(m_eventQueue);
m_perFrameEvents.clear();
@@ -109,10 +128,12 @@ void ScriptedAnimationController::dispatchEvents()
// FIXME: we should figure out how to make dispatchEvent properly virtual to avoid
// special casting window.
// FIXME: We should not fire events for nodes that are no longer in the tree.
- if (DOMWindow* window = eventTarget->toDOMWindow())
- window->dispatchEvent(events[i], 0);
+ if (LocalDOMWindow* window = eventTarget->toDOMWindow())
+ window->dispatchEvent(events[i], nullptr);
else
eventTarget->dispatchEvent(events[i]);
+
+ InspectorInstrumentation::didRemoveEvent(eventTarget, events[i].get());
}
}
@@ -133,12 +154,15 @@ void ScriptedAnimationController::executeCallbacks(double monotonicTimeNow)
for (size_t i = 0; i < m_callbacksToInvoke.size(); ++i) {
RequestAnimationFrameCallback* callback = m_callbacksToInvoke[i].get();
if (!callback->m_cancelled) {
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FireAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, callback->m_id));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id);
if (callback->m_useLegacyTimeBase)
callback->handleEvent(legacyHighResNowMs);
else
callback->handleEvent(highResNowMs);
InspectorInstrumentation::didFireAnimationFrame(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
}
@@ -153,7 +177,7 @@ void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTime
if (m_suspendCount)
return;
- RefPtr<ScriptedAnimationController> protect(this);
+ RefPtrWillBeRawPtr<ScriptedAnimationController> protect(this);
dispatchEvents();
executeCallbacks(monotonicTimeNow);
@@ -161,13 +185,14 @@ void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTime
scheduleAnimationIfNeeded();
}
-void ScriptedAnimationController::enqueueEvent(PassRefPtr<Event> event)
+void ScriptedAnimationController::enqueueEvent(PassRefPtrWillBeRawPtr<Event> event)
{
+ InspectorInstrumentation::didEnqueueEvent(event->target(), event.get());
m_eventQueue.append(event);
scheduleAnimationIfNeeded();
}
-void ScriptedAnimationController::enqueuePerFrameEvent(PassRefPtr<Event> event)
+void ScriptedAnimationController::enqueuePerFrameEvent(PassRefPtrWillBeRawPtr<Event> event)
{
if (!m_perFrameEvents.add(eventTargetKey(event.get())).isNewEntry)
return;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
index 5f7efb887e9..c148a2f77cb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
@@ -26,6 +26,7 @@
#ifndef ScriptedAnimationController_h
#define ScriptedAnimationController_h
+#include "platform/heap/Handle.h"
#include "wtf/ListHashSet.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -39,14 +40,15 @@ class Event;
class EventTarget;
class RequestAnimationFrameCallback;
-class ScriptedAnimationController : public RefCounted<ScriptedAnimationController> {
+class ScriptedAnimationController : public RefCountedWillBeGarbageCollectedFinalized<ScriptedAnimationController> {
public:
- static PassRefPtr<ScriptedAnimationController> create(Document* document)
+ static PassRefPtrWillBeRawPtr<ScriptedAnimationController> create(Document* document)
{
- return adoptRef(new ScriptedAnimationController(document));
+ return adoptRefWillBeNoop(new ScriptedAnimationController(document));
}
~ScriptedAnimationController();
- void clearDocumentPointer() { m_document = 0; }
+ void trace(Visitor*);
+ void clearDocumentPointer() { m_document = nullptr; }
typedef int CallbackId;
@@ -54,8 +56,8 @@ public:
void cancelCallback(CallbackId);
void serviceScriptedAnimations(double monotonicTimeNow);
- void enqueueEvent(PassRefPtr<Event>);
- void enqueuePerFrameEvent(PassRefPtr<Event>);
+ void enqueueEvent(PassRefPtrWillBeRawPtr<Event>);
+ void enqueuePerFrameEvent(PassRefPtrWillBeRawPtr<Event>);
void suspend();
void resume();
@@ -72,11 +74,11 @@ private:
CallbackList m_callbacks;
CallbackList m_callbacksToInvoke; // only non-empty while inside executeCallbacks
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
CallbackId m_nextCallbackId;
int m_suspendCount;
- Vector<RefPtr<Event> > m_eventQueue;
- ListHashSet<std::pair<const EventTarget*, const StringImpl*> > m_perFrameEvents;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > m_eventQueue;
+ WillBeHeapListHashSet<std::pair<RawPtrWillBeMember<const EventTarget>, const StringImpl*> > m_perFrameEvents;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp
index d0c35303076..9767bf15540 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "core/dom/SecurityContext.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
@@ -47,7 +47,7 @@ void SecurityContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securityOrigi
m_haveInitializedSecurityOrigin = true;
}
-void SecurityContext::setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy> contentSecurityPolicy)
+void SecurityContext::setContentSecurityPolicy(PassRefPtr<ContentSecurityPolicy> contentSecurityPolicy)
{
m_contentSecurityPolicy = contentSecurityPolicy;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h
index b47c6f4906c..07f62ad223a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h
@@ -53,7 +53,7 @@ protected:
SecurityContext();
virtual ~SecurityContext();
- void setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy>);
+ void setContentSecurityPolicy(PassRefPtr<ContentSecurityPolicy>);
void didFailToInitializeSecurityOrigin() { m_haveInitializedSecurityOrigin = false; }
bool haveInitializedSecurityOrigin() const { return m_haveInitializedSecurityOrigin; }
@@ -61,7 +61,7 @@ protected:
private:
bool m_haveInitializedSecurityOrigin;
RefPtr<SecurityOrigin> m_securityOrigin;
- OwnPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
+ RefPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
index 5fcf2ac55a2..9ed695de994 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,94 +28,65 @@
#include "core/dom/SelectorQuery.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/SelectorChecker.h"
-#include "core/css/SelectorCheckerFastPath.h"
#include "core/css/SiblingTraversalStrategies.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/Node.h"
#include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
-class SimpleNodeList {
-public:
- virtual ~SimpleNodeList() { }
- virtual bool isEmpty() const = 0;
- virtual Node* next() = 0;
-};
-
-class SingleNodeList : public SimpleNodeList {
-public:
- explicit SingleNodeList(Node* rootNode) : m_currentNode(rootNode) { }
-
- bool isEmpty() const { return !m_currentNode; }
-
- Node* next()
+struct SingleElementSelectorQueryTrait {
+ typedef Element* OutputType;
+ static const bool shouldOnlyMatchFirstElement = true;
+ ALWAYS_INLINE static void appendElement(OutputType& output, Element& element)
{
- Node* current = m_currentNode;
- m_currentNode = 0;
- return current;
+ ASSERT(!output);
+ output = &element;
}
-
-private:
- Node* m_currentNode;
};
-class ClassRootNodeList : public SimpleNodeList {
-public:
- ClassRootNodeList(Node& rootNode, const AtomicString& className)
- : m_className(className)
- , m_rootNode(rootNode)
- , m_currentElement(nextInternal(ElementTraversal::firstWithin(m_rootNode))) { }
-
- bool isEmpty() const { return !m_currentElement; }
-
- Node* next()
+struct AllElementsSelectorQueryTrait {
+ typedef WillBeHeapVector<RefPtrWillBeMember<Node> > OutputType;
+ static const bool shouldOnlyMatchFirstElement = false;
+ ALWAYS_INLINE static void appendElement(OutputType& output, Node& element)
{
- Node* current = m_currentElement;
- ASSERT(current);
- m_currentElement = nextInternal(ElementTraversal::nextSkippingChildren(*m_currentElement, &m_rootNode));
- return current;
+ output.append(&element);
}
-
-private:
- Element* nextInternal(Element* element)
- {
- for (; element; element = ElementTraversal::next(*element, &m_rootNode)) {
- if (element->hasClass() && element->classNames().contains(m_className))
- return element;
- }
- return 0;
- }
-
- const AtomicString& m_className;
- Node& m_rootNode;
- Element* m_currentElement;
};
-class ClassElementList : public SimpleNodeList {
+enum ClassElementListBehavior { AllElements, OnlyRoots };
+
+template <ClassElementListBehavior onlyRoots>
+class ClassElementList {
+ STACK_ALLOCATED();
public:
- ClassElementList(Node& rootNode, const AtomicString& className)
+ ClassElementList(ContainerNode& rootNode, const AtomicString& className)
: m_className(className)
- , m_rootNode(rootNode)
+ , m_rootNode(&rootNode)
, m_currentElement(nextInternal(ElementTraversal::firstWithin(rootNode))) { }
bool isEmpty() const { return !m_currentElement; }
- Node* next()
+ Element* next()
{
- Node* current = m_currentElement;
+ Element* current = m_currentElement;
ASSERT(current);
- m_currentElement = nextInternal(ElementTraversal::next(*m_currentElement, &m_rootNode));
+ if (onlyRoots)
+ m_currentElement = nextInternal(ElementTraversal::nextSkippingChildren(*m_currentElement, m_rootNode));
+ else
+ m_currentElement = nextInternal(ElementTraversal::next(*m_currentElement, m_rootNode));
return current;
}
private:
Element* nextInternal(Element* element)
{
- for (; element; element = ElementTraversal::next(*element, &m_rootNode)) {
+ for (; element; element = ElementTraversal::next(*element, m_rootNode)) {
if (element->hasClass() && element->classNames().contains(m_className))
return element;
}
@@ -122,8 +94,8 @@ private:
}
const AtomicString& m_className;
- Node& m_rootNode;
- Element* m_currentElement;
+ RawPtrWillBeMember<ContainerNode> m_rootNode;
+ RawPtrWillBeMember<Element> m_currentElement;
};
void SelectorDataList::initialize(const CSSSelectorList& selectorList)
@@ -131,27 +103,26 @@ void SelectorDataList::initialize(const CSSSelectorList& selectorList)
ASSERT(m_selectors.isEmpty());
unsigned selectorCount = 0;
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
selectorCount++;
+ m_crossesTreeBoundary = false;
m_selectors.reserveInitialCapacity(selectorCount);
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
- m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPath::canUse(selector)));
+ unsigned index = 0;
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) {
+ m_selectors.uncheckedAppend(selector);
+ m_crossesTreeBoundary |= selectorList.selectorCrossesTreeScopes(index);
+ }
}
-inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element& element, const Node& rootNode) const
+inline bool SelectorDataList::selectorMatches(const CSSSelector& selector, Element& element, const ContainerNode& rootNode) const
{
- if (selectorData.isFastCheckable && !element.isSVGElement()) {
- SelectorCheckerFastPath selectorCheckerFastPath(selectorData.selector, element);
- if (!selectorCheckerFastPath.matchesRightmostSelector(SelectorChecker::VisitedMatchDisabled))
- return false;
- return selectorCheckerFastPath.matches();
- }
-
SelectorChecker selectorChecker(element.document(), SelectorChecker::QueryingRules);
- SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, &element, SelectorChecker::VisitedMatchDisabled);
+ SelectorChecker::SelectorCheckingContext selectorCheckingContext(selector, &element, SelectorChecker::VisitedMatchDisabled);
selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTreeScope;
- selectorCheckingContext.scope = !rootNode.isDocumentNode() && rootNode.isContainerNode() ? &toContainerNode(rootNode) : 0;
+ selectorCheckingContext.scope = !rootNode.isDocumentNode() ? &rootNode : 0;
+ if (selectorCheckingContext.scope)
+ selectorCheckingContext.behaviorAtBoundary = static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::StaysWithinTreeScope | SelectorChecker::ScopeContainsLastMatchedElement);
return selectorChecker.match(selectorCheckingContext, DOMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches;
}
@@ -159,65 +130,57 @@ bool SelectorDataList::matches(Element& targetElement) const
{
unsigned selectorCount = m_selectors.size();
for (unsigned i = 0; i < selectorCount; ++i) {
- if (selectorMatches(m_selectors[i], targetElement, targetElement))
+ if (selectorMatches(*m_selectors[i], targetElement, targetElement))
return true;
}
return false;
}
-PassRefPtr<NodeList> SelectorDataList::queryAll(Node& rootNode) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SelectorDataList::queryAll(ContainerNode& rootNode) const
{
- Vector<RefPtr<Node> > result;
- executeQueryAll(rootNode, result);
+ WillBeHeapVector<RefPtrWillBeMember<Node> > result;
+ execute<AllElementsSelectorQueryTrait>(rootNode, result);
return StaticNodeList::adopt(result);
}
-PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const
+PassRefPtrWillBeRawPtr<Element> SelectorDataList::queryFirst(ContainerNode& rootNode) const
{
- return executeQueryFirst(rootNode);
+ Element* matchedElement = 0;
+ execute<SingleElementSelectorQueryTrait>(rootNode, matchedElement);
+ return matchedElement;
}
-void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >& traversalRoots) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::collectElementsByClassName(ContainerNode& rootNode, const AtomicString& className, typename SelectorQueryTrait::OutputType& output) const
{
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (element->hasClass() && element->classNames().contains(className))
- traversalRoots.append(element);
- }
-}
-
-void SelectorDataList::collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >& traversalRoots) const
-{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (SelectorChecker::tagMatches(*element, tagName))
- traversalRoots.append(element);
- }
-}
-
-Element* SelectorDataList::findElementByClassName(Node& rootNode, const AtomicString& className) const
-{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (element->hasClass() && element->classNames().contains(className))
- return element;
+ if (element->hasClass() && element->classNames().contains(className)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
- return 0;
}
-Element* SelectorDataList::findElementByTagName(Node& rootNode, const QualifiedName& tagName) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::collectElementsByTagName(ContainerNode& rootNode, const QualifiedName& tagName, typename SelectorQueryTrait::OutputType& output) const
{
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (SelectorChecker::tagMatches(*element, tagName))
- return element;
+ if (SelectorChecker::tagMatches(*element, tagName)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
- return 0;
}
-inline bool SelectorDataList::canUseFastQuery(const Node& rootNode) const
+inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) const
{
- return m_selectors.size() == 1 && rootNode.inDocument() && !rootNode.document().inQuirksMode();
+ return m_selectors.size() == 1 && !m_crossesTreeBoundary && rootNode.inDocument() && !rootNode.document().inQuirksMode();
}
-inline bool ancestorHasClassName(Node& rootNode, const AtomicString& className)
+inline bool ancestorHasClassName(ContainerNode& rootNode, const AtomicString& className)
{
if (!rootNode.isElementNode())
return false;
@@ -237,48 +200,53 @@ inline bool ancestorHasClassName(Node& rootNode, const AtomicString& className)
//
// The travseralRoots may be empty, regardless of the returned bool value, if this method finds that the selectors won't
// match any element.
-PassOwnPtr<SimpleNodeList> SelectorDataList::findTraverseRoots(Node& rootNode, bool& matchTraverseRoots) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
// We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches
// we would need to sort the results. For now, just traverse the document in that case.
ASSERT(m_selectors.size() == 1);
- ASSERT(m_selectors[0].selector);
bool isRightmostSelector = true;
bool startFromParent = false;
- for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
- if (selector->m_match == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
+ for (const CSSSelector* selector = m_selectors[0]; selector; selector = selector->tagHistory()) {
+ if (selector->match() == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
Element* element = rootNode.treeScope().getElementById(selector->value());
- Node* adjustedNode = &rootNode;
+ ContainerNode* adjustedNode = &rootNode;
if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
adjustedNode = element;
else if (!element || isRightmostSelector)
adjustedNode = 0;
if (isRightmostSelector) {
- matchTraverseRoots = true;
- return adoptPtr(new SingleNodeList(adjustedNode));
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjustedNode, MatchesTraverseRoots, rootNode, output);
+ return;
}
+
if (startFromParent && adjustedNode)
adjustedNode = adjustedNode->parentNode();
- matchTraverseRoots = false;
- return adoptPtr(new SingleNodeList(adjustedNode));
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjustedNode, DoesNotMatchTraverseRoots, rootNode, output);
+ return;
}
// If we have both CSSSelector::Id and CSSSelector::Class at the same time, we should use Id
// to find traverse root.
- if (!startFromParent && selector->m_match == CSSSelector::Class) {
+ if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && selector->match() == CSSSelector::Class) {
if (isRightmostSelector) {
- matchTraverseRoots = true;
- return adoptPtr(new ClassElementList(rootNode, selector->value()));
+ ClassElementList<AllElements> traverseRoots(rootNode, selector->value());
+ executeForTraverseRoots<SelectorQueryTrait>(*m_selectors[0], traverseRoots, MatchesTraverseRoots, rootNode, output);
+ return;
}
- matchTraverseRoots = false;
// Since there exists some ancestor element which has the class name, we need to see all children of rootNode.
- if (ancestorHasClassName(rootNode, selector->value()))
- return adoptPtr(new SingleNodeList(&rootNode));
+ if (ancestorHasClassName(rootNode, selector->value())) {
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output);
+ return;
+ }
- return adoptPtr(new ClassRootNodeList(rootNode, selector->value()));
+ ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value());
+ executeForTraverseRoots<SelectorQueryTrait>(*m_selectors[0], traverseRoots, DoesNotMatchTraverseRoots, rootNode, output);
+ return;
}
if (selector->relation() == CSSSelector::SubSelector)
@@ -290,187 +258,223 @@ PassOwnPtr<SimpleNodeList> SelectorDataList::findTraverseRoots(Node& rootNode, b
startFromParent = false;
}
- matchTraverseRoots = false;
- return adoptPtr(new SingleNodeList(&rootNode));
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output);
}
-void SelectorDataList::executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeForTraverseRoot(const CSSSelector& selector, ContainerNode* traverseRoot, MatchTraverseRootState matchTraverseRoot, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- for (unsigned i = 0; i < m_selectors.size(); ++i) {
- if (selectorMatches(m_selectors[i], *element, rootNode)) {
- matchedElements.append(element);
- break;
- }
- }
- }
-}
+ if (!traverseRoot)
+ return;
-void SelectorDataList::executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
-{
- if (!canUseFastQuery(rootNode))
- return executeSlowQueryAll(rootNode, matchedElements);
+ if (matchTraverseRoot) {
+ if (selectorMatches(selector, toElement(*traverseRoot), rootNode))
+ SelectorQueryTrait::appendElement(output, toElement(*traverseRoot));
+ return;
+ }
- ASSERT(m_selectors.size() == 1);
- ASSERT(m_selectors[0].selector);
-
- const CSSSelector* firstSelector = m_selectors[0].selector;
-
- if (!firstSelector->tagHistory()) {
- // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and querySelectorAll('div').
- switch (firstSelector->m_match) {
- case CSSSelector::Id:
- {
- if (rootNode.document().containsMultipleElementsWithId(firstSelector->value()))
- break;
-
- // Just the same as getElementById.
- Element* element = rootNode.treeScope().getElementById(firstSelector->value());
- if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
- matchedElements.append(element);
+ for (Element* element = ElementTraversal::firstWithin(*traverseRoot); element; element = ElementTraversal::next(*element, traverseRoot)) {
+ if (selectorMatches(selector, *element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
return;
- }
- case CSSSelector::Class:
- return collectElementsByClassName(rootNode, firstSelector->value(), matchedElements);
- case CSSSelector::Tag:
- return collectElementsByTagName(rootNode, firstSelector->tagQName(), matchedElements);
- default:
- break; // If we need another fast path, add here.
}
}
+}
- bool matchTraverseRoots;
- OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(rootNode, matchTraverseRoots);
- if (traverseRoots->isEmpty())
+template <typename SelectorQueryTrait, typename SimpleElementListType>
+void SelectorDataList::executeForTraverseRoots(const CSSSelector& selector, SimpleElementListType& traverseRoots, MatchTraverseRootState matchTraverseRoots, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
+{
+ if (traverseRoots.isEmpty())
return;
- const SelectorData& selector = m_selectors[0];
if (matchTraverseRoots) {
- while (!traverseRoots->isEmpty()) {
- Node& node = *traverseRoots->next();
- Element& element = toElement(node);
- if (selectorMatches(selector, element, rootNode))
- matchedElements.append(&element);
+ while (!traverseRoots.isEmpty()) {
+ Element& element = *traverseRoots.next();
+ if (selectorMatches(selector, element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
return;
}
- while (!traverseRoots->isEmpty()) {
- Node* traverseRoot = traverseRoots->next();
- ASSERT(traverseRoot);
- for (Element* element = ElementTraversal::firstWithin(*traverseRoot); element; element = ElementTraversal::next(*element, traverseRoot)) {
- if (selectorMatches(selector, *element, rootNode))
- matchedElements.append(element);
+ while (!traverseRoots.isEmpty()) {
+ Element& traverseRoot = *traverseRoots.next();
+ for (Element* element = ElementTraversal::firstWithin(traverseRoot); element; element = ElementTraversal::next(*element, &traverseRoot)) {
+ if (selectorMatches(selector, *element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
}
}
-// If matchTraverseRoot is true, the returned Node is the single Element that may match the selector query.
-//
-// If matchTraverseRoot is false, the returned Node is the rootNode parameter or a descendant of rootNode representing
-// the subtree for which we can limit the querySelector traversal.
-//
-// The returned Node may be 0, regardless of matchTraverseRoot, if this method finds that the selectors won't
-// match any element.
-Node* SelectorDataList::findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const
+template <typename SelectorQueryTrait>
+bool SelectorDataList::selectorListMatches(ContainerNode& rootNode, Element& element, typename SelectorQueryTrait::OutputType& output) const
{
- // We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches
- // we would need to sort the results. For now, just traverse the document in that case.
- ASSERT(m_selectors.size() == 1);
- ASSERT(m_selectors[0].selector);
-
- bool matchSingleNode = true;
- bool startFromParent = false;
- for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
- if (selector->m_match == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
- Element* element = rootNode.treeScope().getElementById(selector->value());
- Node* adjustedRootNode = &rootNode;
- if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
- adjustedRootNode = element;
- else if (!element || matchSingleNode)
- adjustedRootNode = 0;
- if (matchSingleNode) {
- matchTraverseRoot = true;
- return adjustedRootNode;
- }
- if (startFromParent && adjustedRootNode)
- adjustedRootNode = adjustedRootNode->parentNode();
- matchTraverseRoot = false;
- return adjustedRootNode;
+ for (unsigned i = 0; i < m_selectors.size(); ++i) {
+ if (selectorMatches(*m_selectors[i], element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, element);
+ return true;
}
- if (selector->relation() == CSSSelector::SubSelector)
- continue;
- matchSingleNode = false;
- if (selector->relation() == CSSSelector::DirectAdjacent || selector->relation() == CSSSelector::IndirectAdjacent)
- startFromParent = true;
- else
- startFromParent = false;
}
- matchTraverseRoot = false;
- return &rootNode;
+ return false;
}
-Element* SelectorDataList::executeSlowQueryFirst(Node& rootNode) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- for (unsigned i = 0; i < m_selectors.size(); ++i) {
- if (selectorMatches(m_selectors[i], *element, rootNode))
- return element;
+ if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
+}
+
+// FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTraversingShadowTree,
+// nextTraversingShadowTree to the best place, e.g. NodeTraversal.
+static ShadowRoot* authorShadowRootOf(const ContainerNode& node)
+{
+ if (!node.isElementNode() || !isShadowHost(&node))
+ return 0;
+
+ ElementShadow* shadow = toElement(node).shadow();
+ ASSERT(shadow);
+ for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) {
+ if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
+ return shadowRoot;
+ }
+ return 0;
+}
+
+static ContainerNode* firstWithinTraversingShadowTree(const ContainerNode& rootNode)
+{
+ if (ShadowRoot* shadowRoot = authorShadowRootOf(rootNode))
+ return shadowRoot;
+ return ElementTraversal::firstWithin(rootNode);
+}
+
+static ContainerNode* nextTraversingShadowTree(const ContainerNode& node, const ContainerNode* rootNode)
+{
+ if (ShadowRoot* shadowRoot = authorShadowRootOf(node))
+ return shadowRoot;
+
+ const ContainerNode* current = &node;
+ while (current) {
+ if (Element* next = ElementTraversal::next(*current, rootNode))
+ return next;
+
+ if (!current->isInShadowTree())
+ return 0;
+
+ ShadowRoot* shadowRoot = current->containingShadowRoot();
+ if (shadowRoot == rootNode)
+ return 0;
+ if (ShadowRoot* youngerShadowRoot = shadowRoot->youngerShadowRoot()) {
+ // Should not obtain any elements in user-agent shadow root.
+ ASSERT(youngerShadowRoot->type() == ShadowRoot::AuthorShadowRoot);
+ return youngerShadowRoot;
}
+
+ current = shadowRoot->host();
+ }
+ return 0;
+}
+
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
+{
+ for (ContainerNode* node = firstWithinTraversingShadowTree(rootNode); node; node = nextTraversingShadowTree(*node, &rootNode)) {
+ if (!node->isElementNode())
+ continue;
+ Element* element = toElement(node);
+ if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
+}
+
+const CSSSelector* SelectorDataList::selectorForIdLookup(const CSSSelector& firstSelector) const
+{
+ for (const CSSSelector* selector = &firstSelector; selector; selector = selector->tagHistory()) {
+ if (selector->match() == CSSSelector::Id)
+ return selector;
+ if (selector->relation() != CSSSelector::SubSelector)
+ break;
}
return 0;
}
-Element* SelectorDataList::executeQueryFirst(Node& rootNode) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
- if (!canUseFastQuery(rootNode))
- return executeSlowQueryFirst(rootNode);
-
-
- const CSSSelector* selector = m_selectors[0].selector;
- ASSERT(selector);
-
- if (!selector->tagHistory()) {
- // Fast path for querySelector('#id'), querySelector('.foo'), and querySelector('div').
- // Many web developers uses querySelector with these simple selectors.
- switch (selector->m_match) {
- case CSSSelector::Id:
- {
- if (rootNode.document().containsMultipleElementsWithId(selector->value()))
- break;
- Element* element = rootNode.treeScope().getElementById(selector->value());
- return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)) ? element : 0;
+ if (!canUseFastQuery(rootNode)) {
+ if (m_crossesTreeBoundary) {
+ rootNode.document().updateDistributionForNodeIfNeeded(&rootNode);
+ executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output);
+ } else {
+ executeSlow<SelectorQueryTrait>(rootNode, output);
+ }
+ return;
+ }
+
+ ASSERT(m_selectors.size() == 1);
+
+ const CSSSelector& selector = *m_selectors[0];
+ const CSSSelector& firstSelector = selector;
+
+ // Fast path for querySelector*('#id'), querySelector*('tag#id').
+ if (const CSSSelector* idSelector = selectorForIdLookup(firstSelector)) {
+ const AtomicString& idToMatch = idSelector->value();
+ if (rootNode.treeScope().containsMultipleElementsWithId(idToMatch)) {
+ const Vector<Element*>& elements = rootNode.treeScope().getAllElementsById(idToMatch);
+ size_t count = elements.size();
+ for (size_t i = 0; i < count; ++i) {
+ Element& element = *elements[i];
+ if (!(isTreeScopeRoot(rootNode) || element.isDescendantOf(&rootNode)))
+ continue;
+ if (selectorMatches(selector, element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
+ return;
+ }
+ Element* element = rootNode.treeScope().getElementById(idToMatch);
+ if (!element || !(isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
+ return;
+ if (selectorMatches(selector, *element, rootNode))
+ SelectorQueryTrait::appendElement(output, *element);
+ return;
+ }
+
+ if (!firstSelector.tagHistory()) {
+ // Fast path for querySelector*('.foo'), and querySelector*('div').
+ switch (firstSelector.match()) {
case CSSSelector::Class:
- return findElementByClassName(rootNode, selector->value());
+ collectElementsByClassName<SelectorQueryTrait>(rootNode, firstSelector.value(), output);
+ return;
case CSSSelector::Tag:
- return findElementByTagName(rootNode, selector->tagQName());
+ collectElementsByTagName<SelectorQueryTrait>(rootNode, firstSelector.tagQName(), output);
+ return;
default:
break; // If we need another fast path, add here.
}
}
- bool matchTraverseRoot;
- Node* traverseRootNode = findTraverseRoot(rootNode, matchTraverseRoot);
- if (!traverseRootNode)
- return 0;
- if (matchTraverseRoot) {
- ASSERT(m_selectors.size() == 1);
- ASSERT(traverseRootNode->isElementNode());
- Element& element = toElement(*traverseRootNode);
- return selectorMatches(m_selectors[0], element, rootNode) ? &element : 0;
- }
+ findTraverseRootsAndExecute<SelectorQueryTrait>(rootNode, output);
+}
- for (Element* element = ElementTraversal::firstWithin(*traverseRootNode); element; element = ElementTraversal::next(*element, traverseRootNode)) {
- if (selectorMatches(m_selectors[0], *element, rootNode))
- return element;
- }
- return 0;
+PassOwnPtr<SelectorQuery> SelectorQuery::adopt(CSSSelectorList& selectorList)
+{
+ return adoptPtr(new SelectorQuery(selectorList));
}
-SelectorQuery::SelectorQuery(const CSSSelectorList& selectorList)
- : m_selectorList(selectorList)
+SelectorQuery::SelectorQuery(CSSSelectorList& selectorList)
{
+ m_selectorList.adopt(selectorList);
m_selectors.initialize(m_selectorList);
}
@@ -479,12 +483,12 @@ bool SelectorQuery::matches(Element& element) const
return m_selectors.matches(element);
}
-PassRefPtr<NodeList> SelectorQuery::queryAll(Node& rootNode) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SelectorQuery::queryAll(ContainerNode& rootNode) const
{
return m_selectors.queryAll(rootNode);
}
-PassRefPtr<Element> SelectorQuery::queryFirst(Node& rootNode) const
+PassRefPtrWillBeRawPtr<Element> SelectorQuery::queryFirst(ContainerNode& rootNode) const
{
return m_selectors.queryFirst(rootNode);
}
@@ -495,7 +499,7 @@ SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Docu
if (it != m_entries.end())
return it->value.get();
- CSSParser parser(document);
+ BisonCSSParser parser(CSSParserContext(document, 0));
CSSSelectorList selectorList;
parser.parseSelector(selectors, selectorList);
@@ -514,10 +518,7 @@ SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Docu
if (m_entries.size() == maximumSelectorQueryCacheSize)
m_entries.remove(m_entries.begin());
- OwnPtr<SelectorQuery> selectorQuery = adoptPtr(new SelectorQuery(selectorList));
- SelectorQuery* rawSelectorQuery = selectorQuery.get();
- m_entries.add(selectors, selectorQuery.release());
- return rawSelectorQuery;
+ return m_entries.add(selectors, SelectorQuery::adopt(selectorList)).storedValue->value.get();
}
void SelectorQueryCache::invalidate()
diff --git a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h
index fb787ab9787..63edd158402 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h
+++ b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +28,7 @@
#define SelectorQuery_h
#include "core/css/CSSSelectorList.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicStringHash.h"
@@ -34,53 +36,66 @@
namespace WebCore {
class CSSSelector;
+class ContainerNode;
class Document;
class Element;
class ExceptionState;
class Node;
-class NodeList;
class SimpleNodeList;
+class StaticNodeList;
class SpaceSplitString;
class SelectorDataList {
public:
void initialize(const CSSSelectorList&);
bool matches(Element&) const;
- PassRefPtr<NodeList> queryAll(Node& rootNode) const;
- PassRefPtr<Element> queryFirst(Node& rootNode) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> queryAll(ContainerNode& rootNode) const;
+ PassRefPtrWillBeRawPtr<Element> queryFirst(ContainerNode& rootNode) const;
private:
- struct SelectorData {
- SelectorData(const CSSSelector* selector, bool isFastCheckable) : selector(selector), isFastCheckable(isFastCheckable) { }
- const CSSSelector* selector;
- bool isFastCheckable;
- };
-
- bool canUseFastQuery(const Node& rootNode) const;
- bool selectorMatches(const SelectorData&, Element&, const Node&) const;
- void collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >&) const;
- Element* findElementByClassName(Node& rootNode, const AtomicString& className) const;
- void collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >&) const;
- Element* findElementByTagName(Node& rootNode, const QualifiedName& tagName) const;
- PassOwnPtr<SimpleNodeList> findTraverseRoots(Node& rootNode, bool& matchTraverseRoots) const;
- void executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
- void executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
- Node* findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const;
- Element* executeSlowQueryFirst(Node& rootNode) const;
- Element* executeQueryFirst(Node& rootNode) const;
-
- Vector<SelectorData> m_selectors;
+ bool canUseFastQuery(const ContainerNode& rootNode) const;
+ bool selectorMatches(const CSSSelector&, Element&, const ContainerNode&) const;
+
+ template <typename SelectorQueryTrait>
+ void collectElementsByClassName(ContainerNode& rootNode, const AtomicString& className, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void collectElementsByTagName(ContainerNode& rootNode, const QualifiedName& tagName, typename SelectorQueryTrait::OutputType&) const;
+
+ template <typename SelectorQueryTrait>
+ void findTraverseRootsAndExecute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+
+ enum MatchTraverseRootState { DoesNotMatchTraverseRoots, MatchesTraverseRoots };
+ template <typename SelectorQueryTrait>
+ void executeForTraverseRoot(const CSSSelector&, ContainerNode* traverseRoot, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait, typename SimpleElementListType>
+ void executeForTraverseRoots(const CSSSelector&, SimpleElementListType& traverseRoots, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+
+ template <typename SelectorQueryTrait>
+ bool selectorListMatches(ContainerNode& rootNode, Element&, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ const CSSSelector* selectorForIdLookup(const CSSSelector&) const;
+
+ Vector<const CSSSelector*> m_selectors;
+ bool m_crossesTreeBoundary;
};
class SelectorQuery {
WTF_MAKE_NONCOPYABLE(SelectorQuery);
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit SelectorQuery(const CSSSelectorList&);
+ static PassOwnPtr<SelectorQuery> adopt(CSSSelectorList&);
+
bool matches(Element&) const;
- PassRefPtr<NodeList> queryAll(Node& rootNode) const;
- PassRefPtr<Element> queryFirst(Node& rootNode) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> queryAll(ContainerNode& rootNode) const;
+ PassRefPtrWillBeRawPtr<Element> queryFirst(ContainerNode& rootNode) const;
private:
+ explicit SelectorQuery(CSSSelectorList&);
+
SelectorDataList m_selectors;
CSSSelectorList m_selectorList;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
index 4285d26c27f..1dbd6c4941d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
@@ -27,25 +27,24 @@
#include "config.h"
#include "core/dom/ShadowTreeStyleSheetCollection.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Element.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/frame/Settings.h"
namespace WebCore {
using namespace HTMLNames;
ShadowTreeStyleSheetCollection::ShadowTreeStyleSheetCollection(ShadowRoot& shadowRoot)
- : StyleSheetCollection(shadowRoot)
+ : TreeScopeStyleSheetCollection(shadowRoot)
{
}
-void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollectionBase& collection)
+void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollection& collection)
{
DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
@@ -54,32 +53,30 @@ void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, Sty
StyleSheet* sheet = 0;
CSSStyleSheet* activeSheet = 0;
- if (!node->isHTMLElement() || !node->hasTagName(styleTag))
+ if (!isHTMLStyleElement(*node))
continue;
- Element* element = toElement(node);
- AtomicString title = element->getAttribute(titleAttr);
+ HTMLStyleElement* element = toHTMLStyleElement(node);
+ const AtomicString& title = element->fastGetAttribute(titleAttr);
bool enabledViaScript = false;
- sheet = toHTMLStyleElement(node)->sheet();
+ sheet = element->sheet();
if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
activeSheet = toCSSStyleSheet(sheet);
// FIXME: clarify how PREFERRED or ALTERNATE works in shadow trees.
// Should we set preferred/selected stylesheets name in shadow trees and
// use the name in document?
- AtomicString rel = element->getAttribute(relAttr);
if (!enabledViaScript && sheet && !title.isEmpty()) {
if (engine->preferredStylesheetSetName().isEmpty()) {
- if (element->hasLocalName(styleTag) || !rel.contains("alternate")) {
- engine->setPreferredStylesheetSetName(title);
- engine->setSelectedStylesheetSetName(title);
- }
+ engine->setPreferredStylesheetSetName(title);
+ engine->setSelectedStylesheetSetName(title);
}
if (title != engine->preferredStylesheetSetName())
activeSheet = 0;
}
+ const AtomicString& rel = element->fastGetAttribute(relAttr);
if (rel.contains("alternate") && title.isEmpty())
activeSheet = 0;
@@ -90,9 +87,9 @@ void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, Sty
}
}
-bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
+void ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
- StyleSheetCollectionBase collection;
+ StyleSheetCollection collection;
collectStyleSheets(engine, collection);
StyleSheetChange change;
@@ -113,13 +110,11 @@ bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine
}
}
if (change.requiresFullStyleRecalc)
- toShadowRoot(m_treeScope.rootNode())->host()->setNeedsStyleRecalc();
+ toShadowRoot(m_treeScope.rootNode()).host()->setNeedsStyleRecalc(SubtreeStyleChange);
m_scopingNodesForStyleScoped.didRemoveScopingNodes();
collection.swap(*this);
updateUsesRemUnits();
-
- return change.requiresFullStyleRecalc;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h
index b7c13cb39cc..7eaafe5e9f2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h
@@ -28,7 +28,7 @@
#ifndef ShadowTreeStyleSheetCollection_h
#define ShadowTreeStyleSheetCollection_h
-#include "core/dom/StyleSheetCollection.h"
+#include "core/dom/TreeScopeStyleSheetCollection.h"
namespace WebCore {
@@ -38,15 +38,21 @@ class StyleSheet;
class StyleSheetCollection;
class StyleEngine;
-class ShadowTreeStyleSheetCollection FINAL : public StyleSheetCollection {
- WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
+class ShadowTreeStyleSheetCollection FINAL : public TreeScopeStyleSheetCollection {
+ WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
explicit ShadowTreeStyleSheetCollection(ShadowRoot&);
- bool updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
+ void updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ TreeScopeStyleSheetCollection::trace(visitor);
+ }
private:
- void collectStyleSheets(StyleEngine*, StyleSheetCollectionBase&);
+ void collectStyleSheets(StyleEngine*, StyleSheetCollection&);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp b/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp
index 63c3da1ef57..4bec8c0ea46 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp
@@ -164,7 +164,7 @@ void SpaceSplitString::set(const AtomicString& inputString, bool shouldFoldCase)
if (shouldFoldCase && hasNonASCIIOrUpper(string))
string = string.foldCase();
- m_data = SpaceSplitStringData::create(string);
+ m_data = SpaceSplitStringData::create(AtomicString(string));
}
SpaceSplitStringData::~SpaceSplitStringData()
@@ -175,7 +175,7 @@ SpaceSplitStringData::~SpaceSplitStringData()
PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& string)
{
- SpaceSplitStringData*& data = sharedDataMap().add(string, 0).iterator->value;
+ SpaceSplitStringData*& data = sharedDataMap().add(string, 0).storedValue->value;
if (!data) {
data = new SpaceSplitStringData(string);
return adoptRef(data);
diff --git a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp
index 10f4b281435..b678d0488b9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp
@@ -30,9 +30,23 @@
#include "core/dom/StaticNodeList.h"
#include "core/dom/Element.h"
+#include <v8.h>
namespace WebCore {
+PassRefPtrWillBeRawPtr<StaticNodeList> StaticNodeList::adopt(WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
+{
+ RefPtrWillBeRawPtr<StaticNodeList> nodeList = adoptRefWillBeNoop(new StaticNodeList);
+ nodeList->m_nodes.swap(nodes);
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(nodeList->AllocationSize());
+ return nodeList.release();
+}
+
+StaticNodeList::~StaticNodeList()
+{
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-AllocationSize());
+}
+
unsigned StaticNodeList::length() const
{
return m_nodes.size();
@@ -45,16 +59,10 @@ Node* StaticNodeList::item(unsigned index) const
return 0;
}
-Node* StaticNodeList::namedItem(const AtomicString& elementId) const
+void StaticNodeList::trace(Visitor* visitor)
{
- size_t length = m_nodes.size();
- for (size_t i = 0; i < length; ++i) {
- Node* node = m_nodes[i].get();
- if (node->isElementNode() && toElement(node)->getIdAttribute() == elementId)
- return node;
- }
-
- return 0;
+ visitor->trace(m_nodes);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h
index fd66b3aa957..62e22e8be77 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h
@@ -29,6 +29,7 @@
#ifndef StaticNodeList_h
#define StaticNodeList_h
+#include "core/dom/Node.h"
#include "core/dom/NodeList.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -40,24 +41,27 @@ class Node;
class StaticNodeList FINAL : public NodeList {
public:
- static PassRefPtr<StaticNodeList> adopt(Vector<RefPtr<Node> >& nodes)
- {
- RefPtr<StaticNodeList> nodeList = adoptRef(new StaticNodeList);
- nodeList->m_nodes.swap(nodes);
- return nodeList.release();
- }
+ static PassRefPtrWillBeRawPtr<StaticNodeList> adopt(WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes);
- static PassRefPtr<StaticNodeList> createEmpty()
+ static PassRefPtrWillBeRawPtr<StaticNodeList> createEmpty()
{
- return adoptRef(new StaticNodeList);
+ return adoptRefWillBeNoop(new StaticNodeList);
}
+ virtual ~StaticNodeList();
+
virtual unsigned length() const OVERRIDE;
virtual Node* item(unsigned index) const OVERRIDE;
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- Vector<RefPtr<Node> > m_nodes;
+ ptrdiff_t AllocationSize()
+ {
+ return m_nodes.capacity() * sizeof(RefPtrWillBeMember<Node>);
+ }
+
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_nodes;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp b/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp
index 1a1a5fc7495..1b0292092cf 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp
@@ -39,14 +39,14 @@ namespace WebCore {
namespace {
-class DispatchCallbackTask : public ExecutionContextTask {
+class DispatchCallbackTask FINAL : public ExecutionContextTask {
public:
static PassOwnPtr<DispatchCallbackTask> create(PassOwnPtr<StringCallback> callback, const String& data)
{
return adoptPtr(new DispatchCallbackTask(callback, data));
}
- virtual void performTask(ExecutionContext*)
+ virtual void performTask(ExecutionContext*) OVERRIDE
{
m_callback->handleEvent(m_data);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp
index 8233785616d..cea6ad5b960 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "core/dom/StyleElement.h"
+#include "bindings/v8/ScriptController.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/StyleSheetContents.h"
@@ -28,8 +29,10 @@
#include "core/dom/Element.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/dom/StyleEngine.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "platform/TraceEvent.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -42,6 +45,7 @@ static bool isCSS(Element* element, const AtomicString& type)
StyleElement::StyleElement(Document* document, bool createdByParser)
: m_createdByParser(createdByParser)
, m_loading(false)
+ , m_registeredAsCandidate(false)
, m_startPosition(TextPosition::belowRangePosition())
{
if (createdByParser && document && document->scriptableDocumentParser() && !document->isInDocumentWrite())
@@ -50,13 +54,19 @@ StyleElement::StyleElement(Document* document, bool createdByParser)
StyleElement::~StyleElement()
{
+#if !ENABLE(OILPAN)
if (m_sheet)
clearSheet();
+#endif
}
void StyleElement::processStyleSheet(Document& document, Element* element)
{
+ TRACE_EVENT0("webkit", "StyleElement::processStyleSheet");
ASSERT(element);
+ ASSERT(element->inDocument());
+
+ m_registeredAsCandidate = true;
document.styleEngine()->addStyleSheetCandidateNode(element, m_createdByParser);
if (m_createdByParser)
return;
@@ -64,17 +74,26 @@ void StyleElement::processStyleSheet(Document& document, Element* element)
process(element);
}
-void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode)
+void StyleElement::removedFromDocument(Document& document, Element* element)
+{
+ removedFromDocument(document, element, 0, document);
+}
+
+void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode, TreeScope& treeScope)
{
ASSERT(element);
- document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode);
- RefPtr<StyleSheet> removedSheet = m_sheet;
+ if (m_registeredAsCandidate) {
+ document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
+ m_registeredAsCandidate = false;
+ }
+
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
if (m_sheet)
- clearSheet();
-
- document.removedStyleSheet(removedSheet.get(), RecalcStyleDeferred, AnalyzedStyleUpdate);
+ clearSheet(element);
+ if (removedSheet)
+ document.removedStyleSheet(removedSheet.get(), AnalyzedStyleUpdate);
}
void StyleElement::clearDocumentData(Document& document, Element* element)
@@ -82,8 +101,11 @@ void StyleElement::clearDocumentData(Document& document, Element* element)
if (m_sheet)
m_sheet->clearOwnerNode();
- if (element->inDocument())
- document.styleEngine()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0);
+ if (element->inDocument()) {
+ ContainerNode* scopingNode = isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0;
+ TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : element->treeScope();
+ document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
+ }
}
void StyleElement::childrenChanged(Element* element)
@@ -109,9 +131,13 @@ void StyleElement::process(Element* element)
createSheet(element, element->textFromChildren());
}
-void StyleElement::clearSheet()
+void StyleElement::clearSheet(Element* ownerElement)
{
ASSERT(m_sheet);
+
+ if (ownerElement && m_sheet->isLoading())
+ ownerElement->document().styleEngine()->removePendingSheet(ownerElement);
+
m_sheet.release()->clearOwnerNode();
}
@@ -120,30 +146,27 @@ void StyleElement::createSheet(Element* e, const String& text)
ASSERT(e);
ASSERT(e->inDocument());
Document& document = e->document();
- if (m_sheet) {
- if (m_sheet->isLoading())
- document.styleEngine()->removePendingSheet(e);
- clearSheet();
- }
+ if (m_sheet)
+ clearSheet(e);
+
+ // Inline style added from an isolated world should bypass the main world's
+ // CSP just as an inline script would.
+ LocalFrame* frame = document.frame();
+ bool shouldBypassMainWorldContentSecurityPolicy = frame && frame->script().shouldBypassMainWorldContentSecurityPolicy();
// If type is empty or CSS, this is a CSS style sheet.
const AtomicString& type = this->type();
- bool passesContentSecurityPolicyChecks = document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line);
+ bool passesContentSecurityPolicyChecks = shouldBypassMainWorldContentSecurityPolicy || document.contentSecurityPolicy()->allowStyleHash(text) || document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line);
if (isCSS(e, type) && passesContentSecurityPolicyChecks) {
- RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
MediaQueryEvaluator screenEval("screen", true);
MediaQueryEvaluator printEval("print", true);
if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
- document.styleEngine()->addPendingSheet();
m_loading = true;
-
TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
- m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document.inputEncoding());
+ m_sheet = document.styleEngine()->createSheet(e, text, startPosition, m_createdByParser);
m_sheet->setMediaQueries(mediaQueries.release());
- m_sheet->setTitle(e->title());
- m_sheet->contents()->parseStringAtPosition(text, startPosition, m_createdByParser);
-
m_loading = false;
}
}
@@ -173,4 +196,9 @@ void StyleElement::startLoadingDynamicSheet(Document& document)
document.styleEngine()->addPendingSheet();
}
+void StyleElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_sheet);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleElement.h b/chromium/third_party/WebKit/Source/core/dom/StyleElement.h
index a26f5a52e10..4f76cad04fa 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleElement.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleElement.h
@@ -29,11 +29,13 @@ namespace WebCore {
class ContainerNode;
class Document;
class Element;
+class TreeScope;
-class StyleElement {
+class StyleElement : public WillBeGarbageCollectedMixin {
public:
StyleElement(Document*, bool createdByParser);
virtual ~StyleElement();
+ virtual void trace(Visitor*);
protected:
virtual const AtomicString& type() const = 0;
@@ -46,20 +48,22 @@ protected:
void startLoadingDynamicSheet(Document&);
void processStyleSheet(Document&, Element*);
- void removedFromDocument(Document&, Element*, ContainerNode* scopingNode = 0);
+ void removedFromDocument(Document&, Element*);
+ void removedFromDocument(Document&, Element*, ContainerNode* scopingNode, TreeScope&);
void clearDocumentData(Document&, Element*);
void childrenChanged(Element*);
void finishParsingChildren(Element*);
- RefPtr<CSSStyleSheet> m_sheet;
+ RefPtrWillBeMember<CSSStyleSheet> m_sheet;
private:
void createSheet(Element*, const String& text = String());
void process(Element*);
- void clearSheet();
+ void clearSheet(Element* ownerElement = 0);
- bool m_createdByParser;
- bool m_loading;
+ bool m_createdByParser : 1;
+ bool m_loading : 1;
+ bool m_registeredAsCandidate : 1;
TextPosition m_startPosition;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp
index 54ce1fe3368..901bed5922c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -28,25 +28,23 @@
#include "config.h"
#include "core/dom/StyleEngine.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSStyleSheet.h"
-#include "core/css/StyleInvalidationAnalysis.h"
+#include "core/css/FontFaceCache.h"
#include "core/css/StyleSheetContents.h"
+#include "core/dom/DocumentStyleSheetCollector.h"
#include "core/dom/Element.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/ShadowTreeStyleSheetCollection.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLLinkElement.h"
-#include "core/html/HTMLStyleElement.h"
+#include "core/html/imports/HTMLImportsController.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/page/InjectedStyleSheets.h"
#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
#include "core/frame/Settings.h"
-#include "core/svg/SVGStyleElement.h"
#include "platform/URLPatternMatcher.h"
namespace WebCore {
@@ -54,12 +52,15 @@ namespace WebCore {
using namespace HTMLNames;
StyleEngine::StyleEngine(Document& document)
- : m_document(document)
- , m_isMaster(HTMLImport::isMaster(&document))
+ : m_document(&document)
+ , m_isMaster(!document.importsController() || document.importsController()->master() == &document)
, m_pendingStylesheets(0)
, m_injectedStyleSheetCacheValid(false)
- , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+#if ENABLE(OILPAN)
+ , m_documentStyleSheetCollection(new DocumentStyleSheetCollection(document))
+#else
, m_documentStyleSheetCollection(document)
+#endif
, m_documentScopeDirty(true)
, m_usesSiblingRules(false)
, m_usesSiblingRulesOverride(false)
@@ -69,16 +70,25 @@ StyleEngine::StyleEngine(Document& document)
, m_maxDirectAdjacentSelectors(0)
, m_ignorePendingStylesheets(false)
, m_didCalculateResolver(false)
- , m_lastResolverAccessCount(0)
- , m_resolverThrowawayTimer(this, &StyleEngine::resolverThrowawayTimerFired)
// We don't need to create CSSFontSelector for imported document or
// HTMLTemplateElement's document, because those documents have no frame.
- , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : 0)
+ , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : nullptr)
+ , m_xslStyleSheet(nullptr)
{
+ if (m_fontSelector)
+ m_fontSelector->registerForInvalidationCallbacks(this);
}
StyleEngine::~StyleEngine()
{
+}
+
+#if !ENABLE(OILPAN)
+void StyleEngine::detachFromDocument()
+{
+ // Cleanup is performed eagerly when the StyleEngine is removed from the
+ // document. The StyleEngine is unreachable after this, since only the
+ // document has a reference to it.
for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
m_injectedAuthorStyleSheets[i]->clearOwnerNode();
for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
@@ -86,16 +96,21 @@ StyleEngine::~StyleEngine()
if (m_fontSelector) {
m_fontSelector->clearDocument();
- if (m_resolver)
- m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+ m_fontSelector->unregisterForInvalidationCallbacks(this);
}
+
+ // Decrement reference counts for things we could be keeping alive.
+ m_fontSelector.clear();
+ m_resolver.clear();
+ m_styleSheetCollectionMap.clear();
}
+#endif
inline Document* StyleEngine::master()
{
if (isMaster())
- return &m_document;
- HTMLImport* import = m_document.import();
+ return m_document;
+ HTMLImportsController* import = document().importsController();
if (!import) // Document::import() can return null while executing its destructor.
return 0;
return import->master();
@@ -128,52 +143,39 @@ void StyleEngine::insertTreeScopeInDocumentOrder(TreeScopeSet& treeScopes, TreeS
treeScopes.insertBefore(followingTreeScope, treeScope);
}
-StyleSheetCollection* StyleEngine::ensureStyleSheetCollectionFor(TreeScope& treeScope)
+TreeScopeStyleSheetCollection* StyleEngine::ensureStyleSheetCollectionFor(TreeScope& treeScope)
{
if (treeScope == m_document)
- return &m_documentStyleSheetCollection;
+ return documentStyleSheetCollection();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_styleSheetCollectionMap.add(&treeScope, nullptr);
+ StyleSheetCollectionMap::AddResult result = m_styleSheetCollectionMap.add(&treeScope, nullptr);
if (result.isNewEntry)
- result.iterator->value = adoptPtr(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
- return result.iterator->value.get();
+ result.storedValue->value = adoptPtrWillBeNoop(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
+ return result.storedValue->value.get();
}
-StyleSheetCollection* StyleEngine::styleSheetCollectionFor(TreeScope& treeScope)
+TreeScopeStyleSheetCollection* StyleEngine::styleSheetCollectionFor(TreeScope& treeScope)
{
if (treeScope == m_document)
- return &m_documentStyleSheetCollection;
+ return documentStyleSheetCollection();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(&treeScope);
+ StyleSheetCollectionMap::iterator it = m_styleSheetCollectionMap.find(&treeScope);
if (it == m_styleSheetCollectionMap.end())
return 0;
return it->value.get();
}
-const Vector<RefPtr<StyleSheet> >& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
+const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
{
if (treeScope == m_document)
- return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
+ return documentStyleSheetCollection()->styleSheetsForStyleSheetList();
return ensureStyleSheetCollectionFor(treeScope)->styleSheetsForStyleSheetList();
}
-const Vector<RefPtr<CSSStyleSheet> >& StyleEngine::activeAuthorStyleSheets() const
-{
- return m_documentStyleSheetCollection.activeAuthorStyleSheets();
-}
-
-void StyleEngine::getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& StyleEngine::activeAuthorStyleSheets() const
{
- activeAuthorStyleSheets.append(&m_documentStyleSheetCollection.activeAuthorStyleSheets());
-
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values begin = m_styleSheetCollectionMap.values().begin();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values end = m_styleSheetCollectionMap.values().end();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values it = begin;
- for (; it != end; ++it) {
- const StyleSheetCollection* collection = it->get();
- activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
- }
+ return documentStyleSheetCollection()->activeAuthorStyleSheets();
}
void StyleEngine::combineCSSFeatureFlags(const RuleFeatureSet& features)
@@ -191,7 +193,7 @@ void StyleEngine::resetCSSFeatureFlags(const RuleFeatureSet& features)
m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors();
}
-const Vector<RefPtr<CSSStyleSheet> >& StyleEngine::injectedAuthorStyleSheets() const
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& StyleEngine::injectedAuthorStyleSheets() const
{
updateInjectedStyleSheetCache();
return m_injectedAuthorStyleSheets;
@@ -204,21 +206,20 @@ void StyleEngine::updateInjectedStyleSheetCache() const
m_injectedStyleSheetCacheValid = true;
m_injectedAuthorStyleSheets.clear();
- Page* owningPage = m_document.page();
+ Page* owningPage = document().page();
if (!owningPage)
return;
- const PageGroup& pageGroup = owningPage->group();
- const InjectedStyleSheetVector& sheets = pageGroup.injectedStyleSheets();
- for (unsigned i = 0; i < sheets.size(); ++i) {
- const InjectedStyleSheet* sheet = sheets[i].get();
- if (sheet->injectedFrames() == InjectStyleInTopFrameOnly && m_document.ownerElement())
+ const InjectedStyleSheetEntryVector& entries = InjectedStyleSheets::instance().entries();
+ for (unsigned i = 0; i < entries.size(); ++i) {
+ const InjectedStyleSheetEntry* entry = entries[i].get();
+ if (entry->injectedFrames() == InjectStyleInTopFrameOnly && document().ownerElement())
continue;
- if (!URLPatternMatcher::matchesPatterns(m_document.url(), sheet->whitelist()))
+ if (!URLPatternMatcher::matchesPatterns(document().url(), entry->whitelist()))
continue;
- RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(&m_document), KURL());
+ RefPtrWillBeRawPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(m_document, KURL());
m_injectedAuthorStyleSheets.append(groupSheet);
- groupSheet->contents()->parseString(sheet->source());
+ groupSheet->contents()->parseString(entry->source());
}
}
@@ -228,38 +229,28 @@ void StyleEngine::invalidateInjectedStyleSheetCache()
markDocumentDirty();
// FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollection::updateActiveStyleSheets
// and batch updates lots of sheets so we can't call addedStyleSheet() or removedStyleSheet().
- m_document.styleResolverChanged(RecalcStyleDeferred);
+ document().styleResolverChanged();
}
-void StyleEngine::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
+void StyleEngine::addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet)
{
- m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, &m_document));
- m_document.addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
+ m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
+ document().addedStyleSheet(m_authorStyleSheets.last().get());
markDocumentDirty();
}
void StyleEngine::addPendingSheet()
{
- master()->styleEngine()->notifyPendingStyleSheetAdded();
+ m_pendingStylesheets++;
}
// This method is called whenever a top-level stylesheet has finished loading.
-void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
+void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode)
{
- TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? &styleSheetCandidateNode->treeScope() : &m_document;
+ ASSERT(styleSheetCandidateNode);
+ TreeScope* treeScope = isHTMLStyleElement(*styleSheetCandidateNode) ? &styleSheetCandidateNode->treeScope() : m_document.get();
markTreeScopeDirty(*treeScope);
- master()->styleEngine()->notifyPendingStyleSheetRemoved(notification);
-}
-
-void StyleEngine::notifyPendingStyleSheetAdded()
-{
- ASSERT(isMaster());
- m_pendingStylesheets++;
-}
-void StyleEngine::notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType notification)
-{
- ASSERT(isMaster());
// Make sure we knew this sheet was pending, and that our count isn't out of sync.
ASSERT(m_pendingStylesheets > 0);
@@ -267,14 +258,9 @@ void StyleEngine::notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationT
if (m_pendingStylesheets)
return;
- if (notification == RemovePendingSheetNotifyLater) {
- m_document.setNeedsNotifyRemoveAllPendingStylesheet();
- return;
- }
-
// FIXME: We can't call addedStyleSheet or removedStyleSheet here because we don't know
// what's new. We should track that to tell the style system what changed.
- m_document.didRemoveAllPendingStylesheet();
+ document().didRemoveAllPendingStylesheet();
}
void StyleEngine::modifiedStyleSheet(StyleSheet* sheet)
@@ -286,7 +272,7 @@ void StyleEngine::modifiedStyleSheet(StyleSheet* sheet)
if (!node || !node->inDocument())
return;
- TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
markTreeScopeDirty(treeScope);
@@ -297,10 +283,10 @@ void StyleEngine::addStyleSheetCandidateNode(Node* node, bool createdByParser)
if (!node->inDocument())
return;
- TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
-
- StyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
+ ASSERT(!isXSLStyleSheet(*node));
+ TreeScopeStyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
ASSERT(collection);
collection->addStyleSheetCandidateNode(node, createdByParser);
@@ -309,12 +295,17 @@ void StyleEngine::addStyleSheetCandidateNode(Node* node, bool createdByParser)
insertTreeScopeInDocumentOrder(m_activeTreeScopes, &treeScope);
}
-void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
+void StyleEngine::removeStyleSheetCandidateNode(Node* node)
+{
+ removeStyleSheetCandidateNode(node, 0, *m_document);
+}
+
+void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode, TreeScope& treeScope)
{
- TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+ ASSERT(!isXSLStyleSheet(*node));
- StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
+ TreeScopeStyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
ASSERT(collection);
collection->removeStyleSheetCandidateNode(node, scopingNode);
@@ -322,17 +313,59 @@ void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopi
m_activeTreeScopes.remove(&treeScope);
}
+void StyleEngine::addXSLStyleSheet(ProcessingInstruction* node, bool createdByParser)
+{
+ if (!node->inDocument())
+ return;
+
+ ASSERT(isXSLStyleSheet(*node));
+ bool needToUpdate = false;
+ if (createdByParser || !m_xslStyleSheet) {
+ needToUpdate = !m_xslStyleSheet;
+ } else {
+ unsigned position = m_xslStyleSheet->compareDocumentPositionInternal(node, Node::TreatShadowTreesAsDisconnected);
+ needToUpdate = position & Node::DOCUMENT_POSITION_FOLLOWING;
+ }
+
+ if (!needToUpdate)
+ return;
+
+ markTreeScopeDirty(*m_document);
+ m_xslStyleSheet = node;
+}
+
+void StyleEngine::removeXSLStyleSheet(ProcessingInstruction* node)
+{
+ ASSERT(isXSLStyleSheet(*node));
+ if (m_xslStyleSheet != node)
+ return;
+
+ markTreeScopeDirty(*m_document);
+ m_xslStyleSheet = nullptr;
+}
+
void StyleEngine::modifiedStyleSheetCandidateNode(Node* node)
{
if (!node->inDocument())
return;
- TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
markTreeScopeDirty(treeScope);
}
-bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
+void StyleEngine::enableExitTransitionStylesheets()
+{
+ TreeScopeStyleSheetCollection* collection = ensureStyleSheetCollectionFor(*m_document);
+ collection->enableExitTransitionStylesheets();
+}
+
+bool StyleEngine::shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMode updateMode) const
+{
+ return m_documentScopeDirty || updateMode == FullStyleUpdate;
+}
+
+bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode) const
{
return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
}
@@ -350,48 +383,30 @@ void StyleEngine::clearMediaQueryRuleSetOnTreeScopeStyleSheets(TreeScopeSet tree
void StyleEngine::clearMediaQueryRuleSetStyleSheets()
{
- m_documentStyleSheetCollection.clearMediaQueryRuleSetStyleSheets();
+ documentStyleSheetCollection()->clearMediaQueryRuleSetStyleSheets();
clearMediaQueryRuleSetOnTreeScopeStyleSheets(m_activeTreeScopes);
clearMediaQueryRuleSetOnTreeScopeStyleSheets(m_dirtyTreeScopes);
}
-void StyleEngine::collectDocumentActiveStyleSheets(StyleSheetCollectionBase& collection)
+void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector)
{
- ASSERT(isMaster());
-
- if (HTMLImport* rootImport = m_document.import()) {
- for (HTMLImport* import = traverseFirstPostOrder(rootImport); import; import = traverseNextPostOrder(import)) {
- Document* document = import->document();
- if (!document)
- continue;
- StyleEngine* engine = document->styleEngine();
- DocumentStyleSheetCollection::CollectFor collectFor = document == &m_document ?
- DocumentStyleSheetCollection::CollectForList : DocumentStyleSheetCollection::DontCollectForList;
- engine->m_documentStyleSheetCollection.collectStyleSheets(engine, collection, collectFor);
- }
- } else {
- m_documentStyleSheetCollection.collectStyleSheets(this, collection, DocumentStyleSheetCollection::CollectForList);
- }
+ ASSERT(!isMaster());
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > sheetsForList;
+ ImportedDocumentStyleSheetCollector subcollector(parentCollector, sheetsForList);
+ documentStyleSheetCollection()->collectStyleSheets(this, subcollector);
+ documentStyleSheetCollection()->swapSheetsForSheetList(sheetsForList);
}
-bool StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
+void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
{
ASSERT(isMaster());
+ ASSERT(!document().inStyleRecalc());
- if (m_document.inStyleRecalc()) {
- // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
- // https://bugs.webkit.org/show_bug.cgi?id=54344
- // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
- m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
- return false;
-
- }
- if (!m_document.isActive())
- return false;
+ if (!document().isActive())
+ return;
- bool requiresFullStyleRecalc = false;
- if (m_documentScopeDirty || updateMode == FullStyleUpdate)
- requiresFullStyleRecalc = m_documentStyleSheetCollection.updateActiveStyleSheets(this, updateMode);
+ if (shouldUpdateDocumentStyleSheetCollection(updateMode))
+ documentStyleSheetCollection()->updateActiveStyleSheets(this, updateMode);
if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeScopes : m_dirtyTreeScopes;
@@ -406,44 +421,36 @@ bool StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
if (!collection->hasStyleSheetCandidateNodes())
treeScopesRemoved.add(treeScope);
}
- if (!treeScopesRemoved.isEmpty())
- for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); it != treeScopesRemoved.end(); ++it)
- m_activeTreeScopes.remove(*it);
+ m_activeTreeScopes.removeAll(treeScopesRemoved);
}
- m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
- activeStyleSheetsUpdatedForInspector();
- m_usesRemUnits = m_documentStyleSheetCollection.usesRemUnits();
- if (m_documentScopeDirty || updateMode == FullStyleUpdate)
- m_document.notifySeamlessChildDocumentsOfStylesheetUpdate();
+ InspectorInstrumentation::activeStyleSheetsUpdated(m_document);
+ m_usesRemUnits = documentStyleSheetCollection()->usesRemUnits();
m_dirtyTreeScopes.clear();
m_documentScopeDirty = false;
-
- return requiresFullStyleRecalc;
}
-void StyleEngine::activeStyleSheetsUpdatedForInspector()
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > StyleEngine::activeStyleSheetsForInspector() const
{
- if (m_activeTreeScopes.isEmpty()) {
- InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
- return;
- }
- Vector<RefPtr<StyleSheet> > activeStyleSheets;
+ if (m_activeTreeScopes.isEmpty())
+ return documentStyleSheetCollection()->activeAuthorStyleSheets();
- activeStyleSheets.append(m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheets;
- TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
- TreeScopeSet::iterator end = m_activeTreeScopes.end();
- for (TreeScopeSet::iterator it = begin; it != end; ++it) {
- if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
- activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
+ activeStyleSheets.appendVector(documentStyleSheetCollection()->activeAuthorStyleSheets());
+
+ TreeScopeSet::const_iterator begin = m_activeTreeScopes.begin();
+ TreeScopeSet::const_iterator end = m_activeTreeScopes.end();
+ for (TreeScopeSet::const_iterator it = begin; it != end; ++it) {
+ if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
+ activeStyleSheets.appendVector(collection->activeAuthorStyleSheets());
}
// FIXME: Inspector needs a vector which has all active stylesheets.
// However, creating such a large vector might cause performance regression.
// Need to implement some smarter solution.
- InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, activeStyleSheets);
+ return activeStyleSheets;
}
void StyleEngine::didRemoveShadowRoot(ShadowRoot* shadowRoot)
@@ -456,14 +463,14 @@ void StyleEngine::appendActiveAuthorStyleSheets()
ASSERT(isMaster());
m_resolver->setBuildScopedStyleTreeInDocumentOrder(true);
- m_resolver->appendAuthorStyleSheets(0, m_documentStyleSheetCollection.activeAuthorStyleSheets());
+ m_resolver->appendAuthorStyleSheets(documentStyleSheetCollection()->activeAuthorStyleSheets());
TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
TreeScopeSet::iterator end = m_activeTreeScopes.end();
for (TreeScopeSet::iterator it = begin; it != end; ++it) {
- if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
+ if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
m_resolver->setBuildScopedStyleTreeInDocumentOrder(!collection->scopingNodesForStyleScoped());
- m_resolver->appendAuthorStyleSheets(0, collection->activeAuthorStyleSheets());
+ m_resolver->appendAuthorStyleSheets(collection->activeAuthorStyleSheets());
}
}
m_resolver->finishAppendAuthorStyleSheets();
@@ -476,22 +483,19 @@ void StyleEngine::createResolver()
// which is not in a frame. Code which hits this should have checked
// Document::isActive() before calling into code which could get here.
- ASSERT(m_document.frame());
- ASSERT(m_fontSelector);
+ ASSERT(document().frame());
- m_resolver = adoptPtr(new StyleResolver(m_document));
+ m_resolver = adoptPtrWillBeNoop(new StyleResolver(*m_document));
appendActiveAuthorStyleSheets();
- m_fontSelector->registerForInvalidationCallbacks(m_resolver.get());
- combineCSSFeatureFlags(m_resolver->ensureRuleFeatureSet());
+ combineCSSFeatureFlags(m_resolver->ensureUpdatedRuleFeatureSet());
}
void StyleEngine::clearResolver()
{
- ASSERT(!m_document.inStyleRecalc());
+ ASSERT(!document().inStyleRecalc());
ASSERT(isMaster() || !m_resolver);
- ASSERT(m_fontSelector || !m_resolver);
if (m_resolver)
- m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+ document().updateStyleInvalidationIfNeeded();
m_resolver.clear();
}
@@ -506,21 +510,8 @@ unsigned StyleEngine::resolverAccessCount() const
return m_resolver ? m_resolver->accessCount() : 0;
}
-void StyleEngine::resolverThrowawayTimerFired(Timer<StyleEngine>*)
-{
- if (resolverAccessCount() == m_lastResolverAccessCount)
- clearResolver();
- m_lastResolverAccessCount = resolverAccessCount();
-}
-
-void StyleEngine::didAttach()
-{
- m_resolverThrowawayTimer.startRepeating(60);
-}
-
void StyleEngine::didDetach()
{
- m_resolverThrowawayTimer.stop();
clearResolver();
}
@@ -529,53 +520,74 @@ bool StyleEngine::shouldClearResolver() const
return !m_didCalculateResolver && !haveStylesheetsLoaded();
}
-StyleResolverChange StyleEngine::resolverChanged(RecalcStyleTime time, StyleResolverUpdateMode mode)
+bool StyleEngine::shouldApplyXSLTransform() const
{
- StyleResolverChange change;
+ if (!RuntimeEnabledFeatures::xsltEnabled())
+ return false;
+ return m_xslStyleSheet && !m_document->transformSourceDocument();
+}
+void StyleEngine::resolverChanged(StyleResolverUpdateMode mode)
+{
if (!isMaster()) {
if (Document* master = this->master())
- master->styleResolverChanged(time, mode);
- return change;
+ master->styleResolverChanged(mode);
+ return;
}
// Don't bother updating, since we haven't loaded all our style info yet
// and haven't calculated the style selector for the first time.
- if (!m_document.isActive() || shouldClearResolver()) {
+ if (!document().isActive() || shouldClearResolver()) {
clearResolver();
- return change;
+ return;
}
- m_didCalculateResolver = true;
- if (m_document.didLayoutWithPendingStylesheets() && !hasPendingSheets())
- change.setNeedsRepaint();
+ if (shouldApplyXSLTransform()) {
+ // Processing instruction (XML documents only).
+ // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
+ // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
+ if (!m_document->parsing() && !m_xslStyleSheet->isLoading())
+ m_document->applyXSLTransform(m_xslStyleSheet.get());
+ return;
+ }
- if (updateActiveStyleSheets(mode))
- change.setNeedsStyleRecalc();
+ m_didCalculateResolver = true;
+ updateActiveStyleSheets(mode);
+}
- return change;
+void StyleEngine::clearFontCache()
+{
+ // We should not recreate FontSelector. Instead, clear fontFaceCache.
+ if (m_fontSelector)
+ m_fontSelector->fontFaceCache()->clear();
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
}
-void StyleEngine::resetFontSelector()
+void StyleEngine::updateGenericFontFamilySettings()
{
+ // FIXME: we should not update generic font family settings when
+ // document is inactive.
+ ASSERT(document().isActive());
+
if (!m_fontSelector)
return;
- m_fontSelector->clearDocument();
- if (m_resolver) {
- m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+ m_fontSelector->updateGenericFontFamilySettings(*m_document);
+ if (m_resolver)
m_resolver->invalidateMatchedPropertiesCache();
- }
+}
- // If the document has been already detached, we don't need to recreate
- // CSSFontSelector.
- if (m_document.isActive()) {
- m_fontSelector = CSSFontSelector::create(&m_document);
- if (m_resolver)
- m_fontSelector->registerForInvalidationCallbacks(m_resolver.get());
- } else {
- m_fontSelector = 0;
- }
+void StyleEngine::removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
+{
+ if (!m_fontSelector)
+ return;
+
+ FontFaceCache* cache = m_fontSelector->fontFaceCache();
+ for (unsigned i = 0; i < fontFaceRules.size(); ++i)
+ cache->remove(fontFaceRules[i]);
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
}
void StyleEngine::markTreeScopeDirty(TreeScope& scope)
@@ -591,8 +603,99 @@ void StyleEngine::markTreeScopeDirty(TreeScope& scope)
void StyleEngine::markDocumentDirty()
{
m_documentScopeDirty = true;
- if (!HTMLImport::isMaster(&m_document))
- m_document.import()->master()->styleEngine()->markDocumentDirty();
+ if (document().importLoader())
+ document().importsController()->master()->styleEngine()->markDocumentDirty();
+}
+
+static bool isCacheableForStyleElement(const StyleSheetContents& contents)
+{
+ // FIXME: Support copying import rules.
+ if (!contents.importRules().isEmpty())
+ return false;
+ // Until import rules are supported in cached sheets it's not possible for loading to fail.
+ ASSERT(!contents.didLoadErrorOccur());
+ // It is not the original sheet anymore.
+ if (contents.isMutable())
+ return false;
+ if (!contents.hasSyntacticallyValidCSSHeader())
+ return false;
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSStyleSheet> StyleEngine::createSheet(Element* e, const String& text, TextPosition startPosition, bool createdByParser)
+{
+ RefPtrWillBeRawPtr<CSSStyleSheet> styleSheet = nullptr;
+
+ e->document().styleEngine()->addPendingSheet();
+
+ if (!e->document().inQuirksMode()) {
+ AtomicString textContent(text);
+
+ WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> >::AddResult result = m_textToSheetCache.add(textContent, nullptr);
+ if (result.isNewEntry || !result.storedValue->value) {
+ styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser);
+ if (result.isNewEntry && isCacheableForStyleElement(*styleSheet->contents())) {
+ result.storedValue->value = styleSheet->contents();
+ m_sheetToTextCache.add(styleSheet->contents(), textContent);
+ }
+ } else {
+ StyleSheetContents* contents = result.storedValue->value;
+ ASSERT(contents);
+ ASSERT(isCacheableForStyleElement(*contents));
+ ASSERT(contents->singleOwnerDocument() == e->document());
+ styleSheet = CSSStyleSheet::createInline(contents, e, startPosition);
+ }
+ } else {
+ // FIXME: currently we don't cache StyleSheetContents inQuirksMode.
+ styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser);
+ }
+
+ ASSERT(styleSheet);
+ styleSheet->setTitle(e->title());
+ return styleSheet;
+}
+
+PassRefPtrWillBeRawPtr<CSSStyleSheet> StyleEngine::parseSheet(Element* e, const String& text, TextPosition startPosition, bool createdByParser)
+{
+ RefPtrWillBeRawPtr<CSSStyleSheet> styleSheet = nullptr;
+ styleSheet = CSSStyleSheet::createInline(e, KURL(), startPosition, e->document().inputEncoding());
+ styleSheet->contents()->parseStringAtPosition(text, startPosition, createdByParser);
+ return styleSheet;
+}
+
+void StyleEngine::removeSheet(StyleSheetContents* contents)
+{
+ WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString>::iterator it = m_sheetToTextCache.find(contents);
+ if (it == m_sheetToTextCache.end())
+ return;
+
+ m_textToSheetCache.remove(it->value);
+ m_sheetToTextCache.remove(contents);
+}
+
+void StyleEngine::fontsNeedUpdate(CSSFontSelector*)
+{
+ if (!document().isActive())
+ return;
+
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
+ document().setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
+void StyleEngine::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_injectedAuthorStyleSheets);
+ visitor->trace(m_authorStyleSheets);
+ visitor->trace(m_documentStyleSheetCollection);
+ visitor->trace(m_styleSheetCollectionMap);
+ visitor->trace(m_resolver);
+ visitor->trace(m_fontSelector);
+ visitor->trace(m_textToSheetCache);
+ visitor->trace(m_sheetToTextCache);
+ visitor->trace(m_xslStyleSheet);
+ CSSFontSelectorClient::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h
index e6a4c4d8f09..261b09fa9c1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -28,10 +28,12 @@
#ifndef StyleEngine_h
#define StyleEngine_h
+#include "core/css/CSSFontSelectorClient.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentOrderedList.h"
#include "core/dom/DocumentStyleSheetCollection.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/ListHashSet.h"
#include "wtf/RefPtr.h"
@@ -48,30 +50,14 @@ class Node;
class RuleFeatureSet;
class ShadowTreeStyleSheetCollection;
class StyleResolver;
+class StyleRuleFontFace;
class StyleSheet;
class StyleSheetCollection;
class StyleSheetContents;
class StyleSheetList;
-class StyleResolverChange {
-public:
- StyleResolverChange()
- : m_needsRepaint(false)
- , m_needsStyleRecalc(false)
- { }
-
- bool needsRepaint() const { return m_needsRepaint; }
- bool needsStyleRecalc() const { return m_needsStyleRecalc; }
- void setNeedsRepaint() { m_needsRepaint = true; }
- void setNeedsStyleRecalc() { m_needsStyleRecalc = true; }
-
-private:
- bool m_needsRepaint;
- bool m_needsStyleRecalc;
-};
-
-class StyleEngine {
- WTF_MAKE_FAST_ALLOCATED;
+class StyleEngine FINAL : public CSSFontSelectorClient {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
class IgnoringPendingStylesheet : public TemporaryChange<bool> {
@@ -84,42 +70,53 @@ public:
friend class IgnoringPendingStylesheet;
- static PassOwnPtr<StyleEngine> create(Document& document) { return adoptPtr(new StyleEngine(document)); }
+ static PassOwnPtrWillBeRawPtr<StyleEngine> create(Document& document) { return adoptPtrWillBeNoop(new StyleEngine(document)); }
~StyleEngine();
- const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
- const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
+#if !ENABLE(OILPAN)
+ void detachFromDocument();
+#endif
+
+ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const;
- const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
- const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheetsForInspector() const;
void modifiedStyleSheet(StyleSheet*);
void addStyleSheetCandidateNode(Node*, bool createdByParser);
- void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
+ void removeStyleSheetCandidateNode(Node*);
+ void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&);
void modifiedStyleSheetCandidateNode(Node*);
+ void enableExitTransitionStylesheets();
+ void addXSLStyleSheet(ProcessingInstruction*, bool createdByParser);
+ void removeXSLStyleSheet(ProcessingInstruction*);
void invalidateInjectedStyleSheetCache();
void updateInjectedStyleSheetCache() const;
- void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
-
- bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
+ void addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet);
void clearMediaQueryRuleSetStyleSheets();
- bool updateActiveStyleSheets(StyleResolverUpdateMode);
+ void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector);
+ void updateActiveStyleSheets(StyleResolverUpdateMode);
String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
+ void selectStylesheetSetName(const String& name)
+ {
+ setPreferredStylesheetSetName(name);
+ setSelectedStylesheetSetName(name);
+ }
+
void addPendingSheet();
- enum RemovePendingSheetNotificationType {
- RemovePendingSheetNotifyImmediately,
- RemovePendingSheetNotifyLater
- };
- void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+ void removePendingSheet(Node* styleSheetCandidateNode);
bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; }
@@ -133,15 +130,13 @@ public:
void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
bool usesRemUnits() const { return m_usesRemUnits; }
void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
- bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
+ bool hasScopedStyleSheet() { return documentStyleSheetCollection()->scopingNodesForStyleScoped(); }
void combineCSSFeatureFlags(const RuleFeatureSet&);
void resetCSSFeatureFlags(const RuleFeatureSet&);
- void didModifySeamlessParentStyleSheet() { markDocumentDirty(); }
void didRemoveShadowRoot(ShadowRoot*);
void appendActiveAuthorStyleSheets();
- void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
StyleResolver* resolver() const
{
@@ -163,30 +158,41 @@ public:
void clearMasterResolver();
CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
- void resetFontSelector();
+ void removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >&);
+ void clearFontCache();
+ // updateGenericFontFamilySettings is used from WebSettingsImpl.
+ void updateGenericFontFamilySettings();
- void didAttach();
void didDetach();
bool shouldClearResolver() const;
- StyleResolverChange resolverChanged(RecalcStyleTime, StyleResolverUpdateMode);
+ void resolverChanged(StyleResolverUpdateMode);
unsigned resolverAccessCount() const;
- void collectDocumentActiveStyleSheets(StyleSheetCollectionBase&);
void markDocumentDirty();
+ PassRefPtrWillBeRawPtr<CSSStyleSheet> createSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
+ void removeSheet(StyleSheetContents*);
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ // CSSFontSelectorClient implementation.
+ virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE;
+
private:
StyleEngine(Document&);
- StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
- StyleSheetCollection* styleSheetCollectionFor(TreeScope&);
- void activeStyleSheetsUpdatedForInspector();
- bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
- void resolverThrowawayTimerFired(Timer<StyleEngine>*);
+ TreeScopeStyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
+ TreeScopeStyleSheetCollection* styleSheetCollectionFor(TreeScope&);
+ bool shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMode) const;
+ bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode) const;
+ bool shouldApplyXSLTransform() const;
void markTreeScopeDirty(TreeScope&);
bool isMaster() const { return m_isMaster; }
Document* master();
+ Document& document() const { return *m_document; }
typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
@@ -194,10 +200,28 @@ private:
void createResolver();
- void notifyPendingStyleSheetAdded();
- void notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType);
+ static PassRefPtrWillBeRawPtr<CSSStyleSheet> parseSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
+
+ // FIXME: Oilpan: clean this const madness up once oilpan ships.
+ const DocumentStyleSheetCollection* documentStyleSheetCollection() const
+ {
+#if ENABLE(OILPAN)
+ return m_documentStyleSheetCollection;
+#else
+ return &m_documentStyleSheetCollection;
+#endif
+ }
- Document& m_document;
+ DocumentStyleSheetCollection* documentStyleSheetCollection()
+ {
+#if ENABLE(OILPAN)
+ return m_documentStyleSheetCollection;
+#else
+ return &m_documentStyleSheetCollection;
+#endif
+ }
+
+ RawPtrWillBeMember<Document> m_document;
bool m_isMaster;
// Track the number of currently loading top-level stylesheets needed for rendering.
@@ -206,15 +230,18 @@ private:
// elements and when it is safe to execute scripts.
int m_pendingStylesheets;
- mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
+ mutable WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_injectedAuthorStyleSheets;
mutable bool m_injectedStyleSheetCacheValid;
- Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
-
- bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_authorStyleSheets;
+#if ENABLE(OILPAN)
+ Member<DocumentStyleSheetCollection> m_documentStyleSheetCollection;
+#else
DocumentStyleSheetCollection m_documentStyleSheetCollection;
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap;
+#endif
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<TreeScope>, OwnPtrWillBeMember<ShadowTreeStyleSheetCollection> > StyleSheetCollectionMap;
+ StyleSheetCollectionMap m_styleSheetCollectionMap;
bool m_documentScopeDirty;
TreeScopeSet m_dirtyTreeScopes;
@@ -232,11 +259,14 @@ private:
bool m_ignorePendingStylesheets;
bool m_didCalculateResolver;
- unsigned m_lastResolverAccessCount;
- Timer<StyleEngine> m_resolverThrowawayTimer;
- OwnPtr<StyleResolver> m_resolver;
+ OwnPtrWillBeMember<StyleResolver> m_resolver;
+
+ RefPtrWillBeMember<CSSFontSelector> m_fontSelector;
+
+ WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> > m_textToSheetCache;
+ WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString> m_sheetToTextCache;
- RefPtr<CSSFontSelector> m_fontSelector;
+ RefPtrWillBeMember<ProcessingInstruction> m_xslStyleSheet;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp
new file mode 100644
index 00000000000..23768afc886
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/StyleSheetCandidate.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/Element.h"
+#include "core/dom/ProcessingInstruction.h"
+#include "core/dom/StyleEngine.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLStyleElement.h"
+#include "core/html/imports/HTMLImport.h"
+#include "core/svg/SVGStyleElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AtomicString StyleSheetCandidate::title() const
+{
+ return isElement() ? toElement(m_node).fastGetAttribute(titleAttr) : nullAtom;
+}
+
+bool StyleSheetCandidate::isXSL() const
+{
+ return !m_node.document().isHTMLDocument() && m_type == Pi && toProcessingInstruction(m_node).isXSL();
+}
+
+bool StyleSheetCandidate::isImport() const
+{
+ return m_type == HTMLLink && toHTMLLinkElement(m_node).isImport();
+}
+
+Document* StyleSheetCandidate::importedDocument() const
+{
+ ASSERT(isImport());
+ return toHTMLLinkElement(m_node).import();
+}
+
+bool StyleSheetCandidate::isAlternate() const
+{
+ if (!isElement())
+ return false;
+ return toElement(m_node).getAttribute(relAttr).contains("alternate");
+}
+
+bool StyleSheetCandidate::isEnabledViaScript() const
+{
+ return isHTMLLink() && toHTMLLinkElement(m_node).isEnabledViaScript();
+}
+
+bool StyleSheetCandidate::isEnabledAndLoading() const
+{
+ return isHTMLLink() && !toHTMLLinkElement(m_node).isDisabled() && toHTMLLinkElement(m_node).styleSheetIsLoading();
+}
+
+bool StyleSheetCandidate::hasPreferrableName(const String& currentPreferrableName) const
+{
+ ASSERT(isEnabledAndLoading() || sheet());
+ return !isEnabledViaScript() && !title().isEmpty() && !isAlternate() && currentPreferrableName.isEmpty();
+}
+
+bool StyleSheetCandidate::canBeActivated(const String& currentPreferrableName) const
+{
+ StyleSheet* sheet = this->sheet();
+ if (!sheet || sheet->disabled() || !sheet->isCSSStyleSheet())
+ return false;
+ const AtomicString& title = this->title();
+ if (!isEnabledViaScript() && !title.isEmpty() && title != currentPreferrableName)
+ return false;
+ if (isAlternate() && title.isEmpty())
+ return false;
+
+ return true;
+}
+
+StyleSheetCandidate::Type StyleSheetCandidate::typeOf(Node& node)
+{
+ if (node.nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
+ return Pi;
+
+ if (node.isHTMLElement()) {
+ if (isHTMLLinkElement(node))
+ return HTMLLink;
+ if (isHTMLStyleElement(node))
+ return HTMLStyle;
+
+ ASSERT_NOT_REACHED();
+ return HTMLStyle;
+ }
+
+ if (isSVGStyleElement(node))
+ return SVGStyle;
+
+ ASSERT_NOT_REACHED();
+ return HTMLStyle;
+}
+
+StyleSheet* StyleSheetCandidate::sheet() const
+{
+ switch (m_type) {
+ case HTMLLink:
+ return toHTMLLinkElement(m_node).sheet();
+ case HTMLStyle:
+ return toHTMLStyleElement(m_node).sheet();
+ case SVGStyle:
+ return toSVGStyleElement(m_node).sheet();
+ case Pi:
+ return toProcessingInstruction(m_node).sheet();
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h
index 5684cb877ac..742e8621e31 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h
@@ -24,29 +24,55 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PostAttachCallbacks_h
-#define PostAttachCallbacks_h
+#ifndef StyleSheetCandidate_h
+#define StyleSheetCandidate_h
-#include "wtf/Forward.h"
+#include "wtf/text/AtomicString.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
+class Document;
class Node;
+class StyleSheet;
-class PostAttachCallbacks {
+class StyleSheetCandidate {
public:
- typedef void (*Callback)(Node*);
- static void queueCallback(Callback, Node*);
-
- class SuspendScope {
- public:
- SuspendScope();
- ~SuspendScope();
+ enum Type {
+ HTMLLink,
+ HTMLStyle,
+ SVGStyle,
+ Pi
};
+
+ StyleSheetCandidate(Node& node)
+ : m_node(node)
+ , m_type(typeOf(node))
+ { }
+
+ bool isXSL() const;
+ bool isImport() const;
+ bool isAlternate() const;
+ bool isEnabledViaScript() const;
+ bool isEnabledAndLoading() const;
+ bool hasPreferrableName(const String& currentPreferrableName) const;
+ bool canBeActivated(const String& currentPreferrableName) const;
+
+ StyleSheet* sheet() const;
+ AtomicString title() const;
+ Document* importedDocument() const;
+
private:
- PostAttachCallbacks();
+ bool isElement() const { return m_type != Pi; }
+ bool isHTMLLink() const { return m_type == HTMLLink; }
+
+ static Type typeOf(Node&);
+
+ Node& m_node;
+ Type m_type;
};
-} // namespace WebCore
+}
+
+#endif
-#endif // PostAttachCallbacks_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp
index cb944d876ee..186f1a499a6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp
@@ -28,238 +28,49 @@
#include "core/dom/StyleSheetCollection.h"
#include "core/css/CSSStyleSheet.h"
-#include "core/css/StyleInvalidationAnalysis.h"
-#include "core/css/StyleRuleImport.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/Element.h"
-#include "core/dom/StyleEngine.h"
-#include "core/html/HTMLStyleElement.h"
-#include "core/frame/Settings.h"
namespace WebCore {
-StyleSheetCollectionBase::StyleSheetCollectionBase()
+StyleSheetCollection::StyleSheetCollection()
{
}
-StyleSheetCollectionBase::~StyleSheetCollectionBase()
+StyleSheetCollection::~StyleSheetCollection()
{
}
-void StyleSheetCollectionBase::swap(StyleSheetCollectionBase& other)
+void StyleSheetCollection::swap(StyleSheetCollection& other)
{
m_styleSheetsForStyleSheetList.swap(other.m_styleSheetsForStyleSheetList);
m_activeAuthorStyleSheets.swap(other.m_activeAuthorStyleSheets);
}
-void StyleSheetCollectionBase::appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+void StyleSheetCollection::swapSheetsForSheetList(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheets)
{
- m_activeAuthorStyleSheets.append(sheets);
+ // Only called for collection of HTML Imports that never has active sheets.
+ ASSERT(m_activeAuthorStyleSheets.isEmpty());
+ m_styleSheetsForStyleSheetList.swap(sheets);
}
-void StyleSheetCollectionBase::appendActiveStyleSheet(CSSStyleSheet* sheet)
+void StyleSheetCollection::appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
{
- m_activeAuthorStyleSheets.append(sheet);
-}
-
-void StyleSheetCollectionBase::appendSheetForList(StyleSheet* sheet)
-{
- m_styleSheetsForStyleSheetList.append(sheet);
-}
-
-
-StyleSheetCollection::StyleSheetCollection(TreeScope& treeScope)
- : m_treeScope(treeScope)
- , m_hadActiveLoadingStylesheet(false)
- , m_usesRemUnits(false)
-{
-}
-
-void StyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
-{
- if (!node->inDocument())
- return;
-
- // Until the <body> exists, we have no choice but to compare document positions,
- // since styles outside of the body and head continue to be shunted into the head
- // (and thus can shift to end up before dynamically added DOM content that is also
- // outside the body).
- if (createdByParser && document()->body())
- m_styleSheetCandidateNodes.parserAdd(node);
- else
- m_styleSheetCandidateNodes.add(node);
-
- if (!isHTMLStyleElement(node))
- return;
-
- ContainerNode* scopingNode = toHTMLStyleElement(node)->scopingNode();
- if (!isTreeScopeRoot(scopingNode))
- m_scopingNodesForStyleScoped.add(scopingNode);
-}
-
-void StyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
-{
- m_styleSheetCandidateNodes.remove(node);
-
- if (!isTreeScopeRoot(scopingNode))
- m_scopingNodesForStyleScoped.remove(scopingNode);
-}
-
-StyleSheetCollection::StyleResolverUpdateType StyleSheetCollection::compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets)
-{
- unsigned newStyleSheetCount = newStylesheets.size();
- unsigned oldStyleSheetCount = oldStyleSheets.size();
- ASSERT(newStyleSheetCount >= oldStyleSheetCount);
-
- if (!newStyleSheetCount)
- return Reconstruct;
-
- unsigned newIndex = 0;
- for (unsigned oldIndex = 0; oldIndex < oldStyleSheetCount; ++oldIndex) {
- while (oldStyleSheets[oldIndex] != newStylesheets[newIndex]) {
- addedSheets.append(newStylesheets[newIndex]->contents());
- if (++newIndex == newStyleSheetCount)
- return Reconstruct;
- }
- if (++newIndex == newStyleSheetCount)
- return Reconstruct;
- }
- bool hasInsertions = !addedSheets.isEmpty();
- while (newIndex < newStyleSheetCount) {
- addedSheets.append(newStylesheets[newIndex]->contents());
- ++newIndex;
- }
- // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
- // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
- return hasInsertions ? Reset : Additive;
-}
-
-bool StyleSheetCollection::activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets)
-{
- // StyleSheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
- bool hasActiveLoadingStylesheet = false;
- unsigned newStylesheetCount = newStyleSheets.size();
- for (unsigned i = 0; i < newStylesheetCount; ++i) {
- if (newStyleSheets[i]->isLoading())
- hasActiveLoadingStylesheet = true;
- }
- if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
- m_hadActiveLoadingStylesheet = false;
- return true;
- }
- m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
- return false;
-}
-
-static bool styleSheetContentsHasFontFaceRule(Vector<StyleSheetContents*> sheets)
-{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- ASSERT(sheets[i]);
- if (sheets[i]->hasFontFaceRule())
- return true;
- }
- return false;
-}
-
-static bool cssStyleSheetHasFontFaceRule(const Vector<RefPtr<CSSStyleSheet> > sheets)
-{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- ASSERT(sheets[i]);
- if (sheets[i]->contents()->hasFontFaceRule())
- return true;
- }
- return false;
+ m_activeAuthorStyleSheets.appendVector(sheets);
}
-void StyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const StyleSheetCollectionBase& newCollection, StyleSheetChange& change)
+void StyleSheetCollection::appendActiveStyleSheet(CSSStyleSheet* sheet)
{
- if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets()))
- return;
-
- if (updateMode != AnalyzedStyleUpdate)
- return;
-
- // Find out which stylesheets are new.
- Vector<StyleSheetContents*> addedSheets;
- if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheets().size()) {
- change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleSheets, newCollection.activeAuthorStyleSheets(), addedSheets);
- } else {
- StyleResolverUpdateType updateType = compareStyleSheets(newCollection.activeAuthorStyleSheets(), m_activeAuthorStyleSheets, addedSheets);
- if (updateType != Additive) {
- change.styleResolverUpdateType = updateType;
- } else {
- if (styleSheetContentsHasFontFaceRule(addedSheets)) {
- change.styleResolverUpdateType = ResetStyleResolverAndFontSelector;
- return;
- }
- // FIXME: since currently all stylesheets are re-added after reseting styleresolver,
- // fontSelector should be always reset. After creating RuleSet for each StyleSheetContents,
- // we can avoid appending all stylesheetcontents in reset case.
- // So we can remove "styleSheetContentsHasFontFaceRule(newSheets)".
- if (cssStyleSheetHasFontFaceRule(newCollection.activeAuthorStyleSheets()))
- change.styleResolverUpdateType = ResetStyleResolverAndFontSelector;
- else
- change.styleResolverUpdateType = Reset;
- }
- }
-
- // FIXME: If styleResolverUpdateType is Reconstruct, we should return early here since
- // we need to recalc the whole document. It's wrong to use StyleInvalidationAnalysis since
- // it only looks at the addedSheets.
-
- // No point in doing the analysis work if we're just going to recalc the whole document anyways.
- // This needs to be done after the compareStyleSheets calls above to ensure we don't throw away
- // the StyleResolver if we don't need to.
- if (document()->hasPendingForcedStyleRecalc())
- return;
-
- // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
- if (!document()->body() || document()->hasNodesWithPlaceholderStyle())
- return;
- StyleInvalidationAnalysis invalidationAnalysis(addedSheets);
- if (invalidationAnalysis.dirtiesAllStyle())
- return;
- invalidationAnalysis.invalidateStyle(*document());
- change.requiresFullStyleRecalc = false;
- return;
-}
-
-void StyleSheetCollection::clearMediaQueryRuleSetStyleSheets()
-{
- for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) {
- StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents();
- if (contents->hasMediaQueries())
- contents->clearRuleSet();
- }
-}
-
-void StyleSheetCollection::resetAllRuleSetsInTreeScope(StyleResolver* styleResolver)
-{
- // FIXME: If many web developers use style scoped, implement reset RuleSets in per-scoping node manner.
- if (DocumentOrderedList* styleScopedScopingNodes = scopingNodesForStyleScoped()) {
- for (DocumentOrderedList::iterator it = styleScopedScopingNodes->begin(); it != styleScopedScopingNodes->end(); ++it)
- styleResolver->resetAuthorStyle(toContainerNode(*it));
- }
- if (ListHashSet<Node*, 4>* removedNodes = scopingNodesRemoved()) {
- for (ListHashSet<Node*, 4>::iterator it = removedNodes->begin(); it != removedNodes->end(); ++it)
- styleResolver->resetAuthorStyle(toContainerNode(*it));
- }
- styleResolver->resetAuthorStyle(toContainerNode(m_treeScope.rootNode()));
+ m_activeAuthorStyleSheets.append(sheet);
}
-static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+void StyleSheetCollection::appendSheetForList(StyleSheet* sheet)
{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- if (sheets[i]->contents()->usesRemUnits())
- return true;
- }
- return false;
+ m_styleSheetsForStyleSheetList.append(sheet);
}
-void StyleSheetCollection::updateUsesRemUnits()
+void StyleSheetCollection::trace(Visitor* visitor)
{
- m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
+ visitor->trace(m_activeAuthorStyleSheets);
+ visitor->trace(m_styleSheetsForStyleSheetList);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
index 9c9023355ab..0f23d61d4ab 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
@@ -28,104 +28,42 @@
#ifndef StyleSheetCollection_h
#define StyleSheetCollection_h
-#include "core/dom/Document.h"
-#include "core/dom/DocumentOrderedList.h"
-#include "core/dom/StyleSheetScopingNodeList.h"
-#include "core/dom/TreeScope.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
-#include "wtf/HashMap.h"
-#include "wtf/ListHashSet.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
-class ContainerNode;
class CSSStyleSheet;
-class StyleEngine;
-class Node;
class StyleSheet;
-class StyleSheetContents;
-class StyleSheetList;
-// FIXME: Should be in separate file and be renamed like:
-// - StyleSheetCollectionBase -> StyleSheetCollection
-// - StyleSheetCollection -> ScopeStyleSheetCollection
-//
-class StyleSheetCollectionBase {
- WTF_MAKE_NONCOPYABLE(StyleSheetCollectionBase); WTF_MAKE_FAST_ALLOCATED;
+class StyleSheetCollection : public NoBaseWillBeGarbageCollectedFinalized<StyleSheetCollection> {
+ WTF_MAKE_NONCOPYABLE(StyleSheetCollection);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- StyleSheetCollectionBase();
- ~StyleSheetCollectionBase();
+ friend class ActiveDocumentStyleSheetCollector;
+ friend class ImportedDocumentStyleSheetCollector;
- Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
- Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
- const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
- const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
+ StyleSheetCollection();
+ virtual ~StyleSheetCollection();
- void swap(StyleSheetCollectionBase&);
- void appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
+
+ void swap(StyleSheetCollection&);
+ void swapSheetsForSheetList(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >&);
+ void appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
void appendActiveStyleSheet(CSSStyleSheet*);
void appendSheetForList(StyleSheet*);
-protected:
- Vector<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
- Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
-};
-
-
-class StyleSheetCollection : public StyleSheetCollectionBase {
-public:
- void addStyleSheetCandidateNode(Node*, bool createdByParser);
- void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode);
- bool hasStyleSheetCandidateNodes() const { return !m_styleSheetCandidateNodes.isEmpty(); }
-
-
- bool usesRemUnits() const { return m_usesRemUnits; }
-
- DocumentOrderedList& styleSheetCandidateNodes() { return m_styleSheetCandidateNodes; }
- DocumentOrderedList* scopingNodesForStyleScoped() { return m_scopingNodesForStyleScoped.scopingNodes(); }
- ListHashSet<Node*, 4>* scopingNodesRemoved() { return m_scopingNodesForStyleScoped.scopingNodesRemoved(); }
-
- void clearMediaQueryRuleSetStyleSheets();
+ virtual void trace(Visitor*);
protected:
- explicit StyleSheetCollection(TreeScope&);
-
- Document* document() { return m_treeScope.documentScope(); }
-
- enum StyleResolverUpdateType {
- Reconstruct,
- Reset,
- Additive,
- ResetStyleResolverAndFontSelector
- };
-
- struct StyleSheetChange {
- StyleResolverUpdateType styleResolverUpdateType;
- bool requiresFullStyleRecalc;
-
- StyleSheetChange()
- : styleResolverUpdateType(Reconstruct)
- , requiresFullStyleRecalc(true) { }
- };
-
- void analyzeStyleSheetChange(StyleResolverUpdateMode, const StyleSheetCollectionBase&, StyleSheetChange&);
- void resetAllRuleSetsInTreeScope(StyleResolver*);
- void updateUsesRemUnits();
-
-private:
- static StyleResolverUpdateType compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets);
- bool activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets);
-
-protected:
- TreeScope& m_treeScope;
- bool m_hadActiveLoadingStylesheet;
- bool m_usesRemUnits;
-
- DocumentOrderedList m_styleSheetCandidateNodes;
- StyleSheetScopingNodeList m_scopingNodesForStyleScoped;
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > m_styleSheetsForStyleSheetList;
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_activeAuthorStyleSheets;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp
index 5d809e00904..c633957f41d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp
@@ -53,7 +53,7 @@ void StyleSheetScopingNodeList::remove(ContainerNode* node)
return;
// If the node is still working as a scoping node, we cannot remove.
- if (node->inDocument() && node->numberOfScopedHTMLStyleChildren())
+ if (node->inDocument())
return;
m_scopingNodes->remove(node);
@@ -63,5 +63,3 @@ void StyleSheetScopingNodeList::remove(ContainerNode* node)
}
}
-
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp
index 39446348179..0e2bb71ff2d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp
@@ -22,47 +22,44 @@
*/
#include "config.h"
-#include "core/dom/TagNodeList.h"
+#include "core/dom/TagCollection.h"
#include "core/dom/NodeRareData.h"
#include "wtf/Assertions.h"
namespace WebCore {
-TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& namespaceURI, const AtomicString& localName)
- : LiveNodeList(rootNode, type, DoNotInvalidateOnAttributeChanges)
+TagCollection::TagCollection(ContainerNode& rootNode, CollectionType type, const AtomicString& namespaceURI, const AtomicString& localName)
+ : HTMLCollection(rootNode, type, DoesNotOverrideItemAfter)
, m_namespaceURI(namespaceURI)
, m_localName(localName)
{
ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
}
-TagNodeList::~TagNodeList()
+TagCollection::~TagCollection()
{
+#if !ENABLE(OILPAN)
if (m_namespaceURI == starAtom)
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type(), m_localName);
+ ownerNode().nodeLists()->removeCache(this, type(), m_localName);
else
- ownerNode()->nodeLists()->removeCacheWithQualifiedName(this, m_namespaceURI, m_localName);
+ ownerNode().nodeLists()->removeCache(this, m_namespaceURI, m_localName);
+#endif
}
-bool TagNodeList::nodeMatches(Element* testNode) const
+bool TagCollection::elementMatches(const Element& testNode) const
{
// Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagnamens
- if (m_localName != starAtom && m_localName != testNode->localName())
+ if (m_localName != starAtom && m_localName != testNode.localName())
return false;
- return m_namespaceURI == starAtom || m_namespaceURI == testNode->namespaceURI();
+ return m_namespaceURI == starAtom || m_namespaceURI == testNode.namespaceURI();
}
-HTMLTagNodeList::HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName)
- : TagNodeList(rootNode, HTMLTagNodeListType, starAtom, localName)
+HTMLTagCollection::HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName)
+ : TagCollection(rootNode, HTMLTagCollectionType, starAtom, localName)
, m_loweredLocalName(localName.lower())
{
}
-bool HTMLTagNodeList::nodeMatches(Element* testNode) const
-{
- return nodeMatchesInlined(testNode);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagCollection.h b/chromium/third_party/WebKit/Source/core/dom/TagCollection.h
new file mode 100644
index 00000000000..6b97db7f2a7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TagCollection.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TagCollection_h
+#define TagCollection_h
+
+#include "core/dom/Element.h"
+#include "core/html/HTMLCollection.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+// Collection that limits to a particular tag.
+class TagCollection : public HTMLCollection {
+public:
+ static PassRefPtrWillBeRawPtr<TagCollection> create(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+ {
+ ASSERT(namespaceURI != starAtom);
+ return adoptRefWillBeNoop(new TagCollection(rootNode, TagCollectionType, namespaceURI, localName));
+ }
+
+ static PassRefPtrWillBeRawPtr<TagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
+ {
+ ASSERT_UNUSED(type, type == TagCollectionType);
+ return adoptRefWillBeNoop(new TagCollection(rootNode, TagCollectionType, starAtom, localName));
+ }
+
+ virtual ~TagCollection();
+
+ bool elementMatches(const Element&) const;
+
+protected:
+ TagCollection(ContainerNode& rootNode, CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
+
+ AtomicString m_namespaceURI;
+ AtomicString m_localName;
+};
+
+DEFINE_TYPE_CASTS(TagCollection, LiveNodeListBase, collection, collection->type() == TagCollectionType, collection.type() == TagCollectionType);
+
+class HTMLTagCollection FINAL : public TagCollection {
+public:
+ static PassRefPtrWillBeRawPtr<HTMLTagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
+ {
+ ASSERT_UNUSED(type, type == HTMLTagCollectionType);
+ return adoptRefWillBeNoop(new HTMLTagCollection(rootNode, localName));
+ }
+
+ bool elementMatches(const Element&) const;
+
+private:
+ HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName);
+
+ AtomicString m_loweredLocalName;
+};
+
+DEFINE_TYPE_CASTS(HTMLTagCollection, LiveNodeListBase, collection, collection->type() == HTMLTagCollectionType, collection.type() == HTMLTagCollectionType);
+
+inline bool HTMLTagCollection::elementMatches(const Element& testElement) const
+{
+ // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagname
+ if (m_localName != starAtom) {
+ const AtomicString& localName = testElement.isHTMLElement() ? m_loweredLocalName : m_localName;
+ if (localName != testElement.localName())
+ return false;
+ }
+ ASSERT(m_namespaceURI == starAtom);
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // TagCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.h b/chromium/third_party/WebKit/Source/core/dom/TagNodeList.h
deleted file mode 100644
index 8ec41937666..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef TagNodeList_h
-#define TagNodeList_h
-
-#include "core/dom/Element.h"
-#include "core/dom/LiveNodeList.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-// NodeList that limits to a particular tag.
-class TagNodeList : public LiveNodeList {
-public:
- static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
- {
- ASSERT(namespaceURI != starAtom);
- return adoptRef(new TagNodeList(rootNode, TagNodeListType, namespaceURI, localName));
- }
-
- static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& localName)
- {
- ASSERT_UNUSED(type, type == TagNodeListType);
- return adoptRef(new TagNodeList(rootNode, TagNodeListType, starAtom, localName));
- }
-
- virtual ~TagNodeList();
-
-protected:
- TagNodeList(PassRefPtr<Node> rootNode, CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
-
- virtual bool nodeMatches(Element*) const;
-
- AtomicString m_namespaceURI;
- AtomicString m_localName;
-};
-
-class HTMLTagNodeList FINAL : public TagNodeList {
-public:
- static PassRefPtr<HTMLTagNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& localName)
- {
- ASSERT_UNUSED(type, type == HTMLTagNodeListType);
- return adoptRef(new HTMLTagNodeList(rootNode, localName));
- }
-
- bool nodeMatchesInlined(Element*) const;
-
-private:
- HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName);
-
- virtual bool nodeMatches(Element*) const OVERRIDE;
-
- AtomicString m_loweredLocalName;
-};
-
-inline bool HTMLTagNodeList::nodeMatchesInlined(Element* testNode) const
-{
- // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagname
- if (m_localName != starAtom) {
- const AtomicString& localName = testNode->isHTMLElement() ? m_loweredLocalName : m_localName;
- if (localName != testNode->localName())
- return false;
- }
- ASSERT(m_namespaceURI == starAtom);
- return true;
-}
-
-} // namespace WebCore
-
-#endif // TagNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h b/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h
index 380e8fa48b2..aa41655cbb8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h
@@ -33,13 +33,21 @@ namespace WebCore {
class TemplateContentDocumentFragment FINAL : public DocumentFragment {
public:
- static PassRefPtr<TemplateContentDocumentFragment> create(Document& document, Element* host)
+ static PassRefPtrWillBeRawPtr<TemplateContentDocumentFragment> create(Document& document, Element* host)
{
- return adoptRef(new TemplateContentDocumentFragment(document, host));
+ return adoptRefWillBeNoop(new TemplateContentDocumentFragment(document, host));
}
Element* host() const { return m_host; }
- void clearHost() { m_host = 0; }
+#if !ENABLE(OILPAN)
+ void clearHost() { m_host = nullptr; }
+#endif
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_host);
+ DocumentFragment::trace(visitor);
+ }
private:
TemplateContentDocumentFragment(Document& document, Element* host)
@@ -50,7 +58,7 @@ private:
virtual bool isTemplateContent() const OVERRIDE { return true; }
- Element* m_host;
+ RawPtrWillBeMember<Element> m_host;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Text.cpp b/chromium/third_party/WebKit/Source/core/dom/Text.cpp
index f43f6ecd0e0..34a7df18241 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Text.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Text.cpp
@@ -22,44 +22,44 @@
#include "config.h"
#include "core/dom/Text.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/SVGNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/dom/NodeRenderingContext.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
-#include "core/events/ScopedEventQueue.h"
+#include "core/dom/RenderTreeBuilder.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/ScopedEventQueue.h"
#include "core/rendering/RenderCombineText.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
+#include "core/svg/SVGForeignObjectElement.h"
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
-PassRefPtr<Text> Text::create(Document& document, const String& data)
+PassRefPtrWillBeRawPtr<Text> Text::create(Document& document, const String& data)
{
- return adoptRef(new Text(document, data, CreateText));
+ return adoptRefWillBeNoop(new Text(document, data, CreateText));
}
-PassRefPtr<Text> Text::createEditingText(Document& document, const String& data)
+PassRefPtrWillBeRawPtr<Text> Text::createEditingText(Document& document, const String& data)
{
- return adoptRef(new Text(document, data, CreateEditingText));
+ return adoptRefWillBeNoop(new Text(document, data, CreateEditingText));
}
-PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
+PassRefPtrWillBeRawPtr<Node> Text::mergeNextSiblingNodesIfPossible()
{
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
// Remove empty text nodes.
if (!length()) {
// Care must be taken to get the next node before removing the current node.
- RefPtr<Node> nextNode(NodeTraversal::nextPostOrder(*this));
+ RefPtrWillBeRawPtr<Node> nextNode(NodeTraversal::nextPostOrder(*this));
remove(IGNORE_EXCEPTION);
return nextNode.release();
}
@@ -69,7 +69,7 @@ PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
if (nextSibling->nodeType() != TEXT_NODE)
break;
- RefPtr<Text> nextText = toText(nextSibling);
+ RefPtrWillBeRawPtr<Text> nextText = toText(nextSibling);
// Remove empty text nodes.
if (!nextText->length()) {
@@ -88,7 +88,7 @@ PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
nextText->setDataWithoutUpdate(emptyString());
nextText->updateTextRenderer(0, nextTextData.length());
- document().didMergeTextNodes(nextText.get(), offset);
+ document().didMergeTextNodes(*nextText, offset);
// Restore nextText for mutation event.
nextText->setDataWithoutUpdate(nextTextData);
@@ -102,18 +102,18 @@ PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
return NodeTraversal::nextPostOrder(*this);
}
-PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Text> Text::splitText(unsigned offset, ExceptionState& exceptionState)
{
// IndexSizeError: Raised if the specified offset is negative or greater than
// the number of 16-bit units in data.
if (offset > length()) {
exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than the Text node's length.");
- return 0;
+ return nullptr;
}
EventQueueScope scope;
String oldStr = data();
- RefPtr<Text> newText = cloneWithData(oldStr.substring(offset));
+ RefPtrWillBeRawPtr<Text> newText = cloneWithData(oldStr.substring(offset));
setDataWithoutUpdate(oldStr.substring(0, offset));
didModifyData(oldStr);
@@ -121,13 +121,13 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionState& exceptionState
if (parentNode())
parentNode()->insertBefore(newText.get(), nextSibling(), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (renderer())
toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr.length());
if (parentNode())
- document().didSplitTextNode(this);
+ document().didSplitTextNode(*this);
return newText.release();
}
@@ -189,26 +189,26 @@ String Text::wholeText() const
return result.toString();
}
-PassRefPtr<Text> Text::replaceWholeText(const String& newText)
+PassRefPtrWillBeRawPtr<Text> Text::replaceWholeText(const String& newText)
{
// Remove all adjacent text nodes, and replace the contents of this one.
// Protect startText and endText against mutation event handlers removing the last ref
- RefPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
- RefPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));
+ RefPtrWillBeRawPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
+ RefPtrWillBeRawPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));
- RefPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
- RefPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal
- for (RefPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
- RefPtr<Node> nodeToRemove(n.release());
+ RefPtrWillBeRawPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
+ RefPtrWillBeRawPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal
+ for (RefPtrWillBeRawPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
+ RefPtrWillBeRawPtr<Node> nodeToRemove(n.release());
n = nodeToRemove->nextSibling();
parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
}
if (this != endText) {
Node* onePastEndText = endText->nextSibling();
- for (RefPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
- RefPtr<Node> nodeToRemove(n.release());
+ for (RefPtrWillBeRawPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
+ RefPtrWillBeRawPtr<Node> nodeToRemove(n.release());
n = nodeToRemove->nextSibling();
parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
}
@@ -217,7 +217,7 @@ PassRefPtr<Text> Text::replaceWholeText(const String& newText)
if (newText.isEmpty()) {
if (parent && parentNode() == parent)
parent->removeChild(this, IGNORE_EXCEPTION);
- return 0;
+ return nullptr;
}
setData(newText);
@@ -234,12 +234,12 @@ Node::NodeType Text::nodeType() const
return TEXT_NODE;
}
-PassRefPtr<Node> Text::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> Text::cloneNode(bool /*deep*/)
{
return cloneWithData(data());
}
-bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
+bool Text::textRendererIsNeeded(const RenderStyle& style, const RenderObject& parent)
{
if (isEditingText())
return true;
@@ -247,39 +247,38 @@ bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
if (!length())
return false;
- if (context.style()->display() == NONE)
+ if (style.display() == NONE)
return false;
if (!containsOnlyWhitespace())
return true;
- RenderObject* parent = context.parentRenderer();
- if (!parent->canHaveWhitespaceChildren())
+ if (!parent.canHaveWhitespaceChildren())
return false;
- if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
+ if (style.preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
return true;
- RenderObject* prev = context.previousRenderer();
+ const RenderObject* prev = NodeRenderingTraversal::previousSiblingRenderer(this);
if (prev && prev->isBR()) // <span><br/> <br/></span>
return false;
- if (parent->isRenderInline()) {
+ if (parent.isRenderInline()) {
// <span><div/> <div/></span>
if (prev && !prev->isInline())
return false;
} else {
- if (parent->isRenderBlock() && !parent->childrenInline() && (!prev || !prev->isInline()))
+ if (parent.isRenderBlock() && !parent.childrenInline() && (!prev || !prev->isInline()))
return false;
// Avoiding creation of a Renderer for the text node is a non-essential memory optimization.
// So to avoid blowing up on very wide DOMs, we limit the number of siblings to visit.
unsigned maxSiblingsToVisit = 50;
- RenderObject* first = parent->firstChild();
+ RenderObject* first = parent.slowFirstChild();
while (first && first->isFloatingOrOutOfFlowPositioned() && maxSiblingsToVisit--)
first = first->nextSibling();
- if (!first || context.nextRenderer() == first)
+ if (!first || NodeRenderingTraversal::nextSiblingRenderer(this) == first)
// Whitespace at the start of a block just goes away. Don't even
// make a render object for this text.
return false;
@@ -290,7 +289,8 @@ bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
static bool isSVGText(Text* text)
{
Node* parentOrShadowHostNode = text->parentOrShadowHostNode();
- return parentOrShadowHostNode->isSVGElement() && !parentOrShadowHostNode->hasTagName(SVGNames::foreignObjectTag);
+ ASSERT(parentOrShadowHostNode);
+ return parentOrShadowHostNode->isSVGElement() && !isSVGForeignObjectElement(*parentOrShadowHostNode);
}
RenderText* Text::createTextRenderer(RenderStyle* style)
@@ -306,7 +306,7 @@ RenderText* Text::createTextRenderer(RenderStyle* style)
void Text::attach(const AttachContext& context)
{
- NodeRenderingContext(this, context.resolvedStyle).createRendererForTextIfNeeded();
+ RenderTreeBuilder(this, context.resolvedStyle).createRendererForTextIfNeeded();
CharacterData::attach(context);
}
@@ -339,22 +339,17 @@ void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfRe
if (!inActiveDocument())
return;
RenderText* textRenderer = toRenderText(renderer());
- if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) {
+ if (!textRenderer || !textRendererIsNeeded(*textRenderer->style(), *textRenderer->parent())) {
lazyReattachIfAttached();
// FIXME: Editing should be updated so this is not neccesary.
if (recalcStyleBehavior == DeprecatedRecalcStyleImmediatlelyForEditing)
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
return;
}
textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
}
-bool Text::childTypeAllowed(NodeType) const
-{
- return false;
-}
-
-PassRefPtr<Text> Text::cloneWithData(const String& data)
+PassRefPtrWillBeRawPtr<Text> Text::cloneWithData(const String& data)
{
return create(document(), data);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/Text.h b/chromium/third_party/WebKit/Source/core/dom/Text.h
index 79540c0b399..fc387d2d75c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Text.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Text.h
@@ -35,21 +35,21 @@ class Text : public CharacterData {
public:
static const unsigned defaultLengthLimit = 1 << 16;
- static PassRefPtr<Text> create(Document&, const String&);
- static PassRefPtr<Text> createEditingText(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<Text> create(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<Text> createEditingText(Document&, const String&);
// mergeNextSiblingNodesIfPossible() merges next sibling nodes if possible
// then returns a node not merged.
- PassRefPtr<Node> mergeNextSiblingNodesIfPossible();
- PassRefPtr<Text> splitText(unsigned offset, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> mergeNextSiblingNodesIfPossible();
+ PassRefPtrWillBeRawPtr<Text> splitText(unsigned offset, ExceptionState&);
// DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1312295772
String wholeText() const;
- PassRefPtr<Text> replaceWholeText(const String&);
+ PassRefPtrWillBeRawPtr<Text> replaceWholeText(const String&);
void recalcTextStyle(StyleRecalcChange, Text* nextTextSibling);
- bool textRendererIsNeeded(const NodeRenderingContext&);
+ bool textRendererIsNeeded(const RenderStyle&, const RenderObject& parent);
RenderText* createTextRenderer(RenderStyle*);
void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, RecalcStyleBehavior = DoNotRecalcStyle);
@@ -67,15 +67,14 @@ protected:
private:
virtual String nodeName() const OVERRIDE;
- virtual PassRefPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
- virtual bool childTypeAllowed(NodeType) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
bool needsWhitespaceRenderer();
- virtual PassRefPtr<Text> cloneWithData(const String&);
+ virtual PassRefPtrWillBeRawPtr<Text> cloneWithData(const String&);
#ifndef NDEBUG
- virtual void formatForDebugger(char* buffer, unsigned length) const;
+ virtual void formatForDebugger(char* buffer, unsigned length) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Text.idl b/chromium/third_party/WebKit/Source/core/dom/Text.idl
index 57e6dc0c8f8..2e3f84252bd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Text.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Text.idl
@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
[
- Constructor([Default=NullString] optional DOMString data),
+ Constructor(optional DOMString data = null),
ConstructorCallWith=Document,
Custom=Wrap,
] interface Text : CharacterData {
@@ -30,5 +30,5 @@
[MeasureAs=TextReplaceWholeText] Text replaceWholeText(DOMString content); // Removed from DOM4.
// Shadow DOM API
- [RuntimeEnabled=ShadowDOM, PerWorldBindings] NodeList getDestinationInsertionPoints();
+ NodeList getDestinationInsertionPoints();
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp b/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp
index 42b61c7ee59..b2d5b46a09f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp
@@ -54,7 +54,7 @@ void TextLinkColors::resetVisitedLinkColor()
void TextLinkColors::resetActiveLinkColor()
{
- m_activeLinkColor.setNamedColor("red");
+ m_activeLinkColor = Color(255, 0, 0);
}
static Color colorForCSSValue(CSSValueID cssValueId)
@@ -110,7 +110,8 @@ Color TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, Co
case CSSValueWebkitActivelink:
return activeLinkColor();
case CSSValueWebkitFocusRingColor:
- return RenderTheme::focusRingColor();
+ return RenderTheme::theme().focusRingColor();
+ case CSSValueInvert: // We don't support outline-color: invert
case CSSValueCurrentcolor:
return currentColor;
default:
diff --git a/chromium/third_party/WebKit/Source/core/dom/Touch.cpp b/chromium/third_party/WebKit/Source/core/dom/Touch.cpp
index a955babbb5d..c2b5f6118f5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Touch.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Touch.cpp
@@ -27,63 +27,45 @@
#include "core/dom/Touch.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "platform/geometry/FloatPoint.h"
namespace WebCore {
-static int contentsX(Frame* frame)
+static FloatPoint contentsOffset(LocalFrame* frame)
{
if (!frame)
- return 0;
+ return FloatPoint();
FrameView* frameView = frame->view();
if (!frameView)
- return 0;
- return frameView->scrollX() / frame->pageZoomFactor();
+ return FloatPoint();
+ float scale = 1.0f / frame->pageZoomFactor();
+ return FloatPoint(frameView->scrollPosition()).scaledBy(scale);
}
-static int contentsY(Frame* frame)
-{
- if (!frame)
- return 0;
- FrameView* frameView = frame->view();
- if (!frameView)
- return 0;
- return frameView->scrollY() / frame->pageZoomFactor();
-}
-
-Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier, int screenX, int screenY, int pageX, int pageY, int radiusX, int radiusY, float rotationAngle, float force)
+Touch::Touch(LocalFrame* frame, EventTarget* target, unsigned identifier, const FloatPoint& screenPos, const FloatPoint& pagePos, const FloatSize& radius, float rotationAngle, float force)
: m_target(target)
, m_identifier(identifier)
- , m_clientX(pageX - contentsX(frame))
- , m_clientY(pageY - contentsY(frame))
- , m_screenX(screenX)
- , m_screenY(screenY)
- , m_pageX(pageX)
- , m_pageY(pageY)
- , m_radiusX(radiusX)
- , m_radiusY(radiusY)
+ , m_clientPos(pagePos - contentsOffset(frame))
+ , m_screenPos(screenPos)
+ , m_pagePos(pagePos)
+ , m_radius(radius)
, m_rotationAngle(rotationAngle)
, m_force(force)
{
ScriptWrappable::init(this);
float scaleFactor = frame->pageZoomFactor();
- float x = pageX * scaleFactor;
- float y = pageY * scaleFactor;
- m_absoluteLocation = roundedLayoutPoint(FloatPoint(x, y));
+ m_absoluteLocation = roundedLayoutPoint(pagePos.scaledBy(scaleFactor));
}
-Touch::Touch(EventTarget* target, unsigned identifier, int clientX, int clientY, int screenX, int screenY, int pageX, int pageY, int radiusX, int radiusY, float rotationAngle, float force, LayoutPoint absoluteLocation)
+Touch::Touch(EventTarget* target, unsigned identifier, const FloatPoint& clientPos, const FloatPoint& screenPos, const FloatPoint& pagePos, const FloatSize& radius, float rotationAngle, float force, LayoutPoint absoluteLocation)
: m_target(target)
, m_identifier(identifier)
- , m_clientX(clientX)
- , m_clientY(clientY)
- , m_screenX(screenX)
- , m_screenY(screenY)
- , m_pageX(pageX)
- , m_pageY(pageY)
- , m_radiusX(radiusX)
- , m_radiusY(radiusY)
+ , m_clientPos(clientPos)
+ , m_screenPos(screenPos)
+ , m_pagePos(pagePos)
+ , m_radius(radius)
, m_rotationAngle(rotationAngle)
, m_force(force)
, m_absoluteLocation(absoluteLocation)
@@ -91,9 +73,14 @@ Touch::Touch(EventTarget* target, unsigned identifier, int clientX, int clientY,
ScriptWrappable::init(this);
}
-PassRefPtr<Touch> Touch::cloneWithNewTarget(EventTarget* eventTarget) const
+PassRefPtrWillBeRawPtr<Touch> Touch::cloneWithNewTarget(EventTarget* eventTarget) const
+{
+ return adoptRefWillBeNoop(new Touch(eventTarget, m_identifier, m_clientPos, m_screenPos, m_pagePos, m_radius, m_rotationAngle, m_force, m_absoluteLocation));
+}
+
+void Touch::trace(Visitor* visitor)
{
- return adoptRef(new Touch(eventTarget, m_identifier, m_clientX, m_clientY, m_screenX, m_screenY, m_pageX, m_pageY, m_radiusX, m_radiusY, m_rotationAngle, m_force, m_absoluteLocation));
+ visitor->trace(m_target);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Touch.h b/chromium/third_party/WebKit/Source/core/dom/Touch.h
index 220d4cf10d4..c4896bbd4f2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Touch.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Touch.h
@@ -28,61 +28,73 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/events/EventTarget.h"
+#include "platform/geometry/FloatPoint.h"
+#include "platform/geometry/FloatSize.h"
#include "platform/geometry/LayoutPoint.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
-class Touch : public RefCounted<Touch>, public ScriptWrappable {
+class Touch FINAL : public RefCountedWillBeGarbageCollectedFinalized<Touch>, public ScriptWrappable {
public:
- static PassRefPtr<Touch> create(Frame* frame, EventTarget* target,
- unsigned identifier, int screenX, int screenY, int pageX, int pageY,
- int radiusX, int radiusY, float rotationAngle, float force)
+ static PassRefPtrWillBeRawPtr<Touch> create(LocalFrame* frame, EventTarget* target,
+ unsigned identifier, const FloatPoint& screenPos, const FloatPoint& pagePos,
+ const FloatSize& radius, float rotationAngle, float force)
{
- return adoptRef(new Touch(frame, target, identifier, screenX,
- screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force));
+ return adoptRefWillBeNoop(
+ new Touch(frame, target, identifier, screenPos, pagePos, radius, rotationAngle, force));
}
+ // DOM Touch implementation
EventTarget* target() const { return m_target.get(); }
unsigned identifier() const { return m_identifier; }
- int clientX() const { return m_clientX; }
- int clientY() const { return m_clientY; }
- int screenX() const { return m_screenX; }
- int screenY() const { return m_screenY; }
- int pageX() const { return m_pageX; }
- int pageY() const { return m_pageY; }
- int webkitRadiusX() const { return m_radiusX; }
- int webkitRadiusY() const { return m_radiusY; }
+ double clientX() const { return m_clientPos.x(); }
+ double clientY() const { return m_clientPos.y(); }
+ double screenX() const { return m_screenPos.x(); }
+ double screenY() const { return m_screenPos.y(); }
+ double pageX() const { return m_pagePos.x(); }
+ double pageY() const { return m_pagePos.y(); }
+ double webkitRadiusX() const { return m_radius.width(); }
+ double webkitRadiusY() const { return m_radius.height(); }
float webkitRotationAngle() const { return m_rotationAngle; }
float webkitForce() const { return m_force; }
+
+ // Blink-internal methods
const LayoutPoint& absoluteLocation() const { return m_absoluteLocation; }
- PassRefPtr<Touch> cloneWithNewTarget(EventTarget*) const;
+ const FloatPoint& screenLocation() const { return m_screenPos; }
+ PassRefPtrWillBeRawPtr<Touch> cloneWithNewTarget(EventTarget*) const;
+
+ void trace(Visitor*);
private:
- Touch(Frame* frame, EventTarget* target, unsigned identifier,
- int screenX, int screenY, int pageX, int pageY,
- int radiusX, int radiusY, float rotationAngle, float force);
+ Touch(LocalFrame* frame, EventTarget* target, unsigned identifier,
+ const FloatPoint& screenPos, const FloatPoint& pagePos,
+ const FloatSize& radius, float rotationAngle, float force);
- Touch(EventTarget*, unsigned identifier, int clientX, int clientY,
- int screenX, int screenY, int pageX, int pageY,
- int radiusX, int radiusY, float rotationAngle, float force, LayoutPoint absoluteLocation);
+ Touch(EventTarget*, unsigned identifier, const FloatPoint& clientPos,
+ const FloatPoint& screenPos, const FloatPoint& pagePos,
+ const FloatSize& radius, float rotationAngle, float force, LayoutPoint absoluteLocation);
- RefPtr<EventTarget> m_target;
+ RefPtrWillBeMember<EventTarget> m_target;
unsigned m_identifier;
- int m_clientX;
- int m_clientY;
- int m_screenX;
- int m_screenY;
- int m_pageX;
- int m_pageY;
- int m_radiusX;
- int m_radiusY;
+ // Position relative to the viewport in CSS px.
+ FloatPoint m_clientPos;
+ // Position relative to the screen in DIPs.
+ FloatPoint m_screenPos;
+ // Position relative to the page in CSS px.
+ FloatPoint m_pagePos;
+ // Radius in CSS px.
+ FloatSize m_radius;
float m_rotationAngle;
float m_force;
+ // FIXME(rbyers): Shouldn't we be able to migrate callers to relying on screenPos, pagePos
+ // or clientPos? absoluteLocation appears to be the same as pagePos but without browser
+ // scale applied.
LayoutPoint m_absoluteLocation;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Touch.idl b/chromium/third_party/WebKit/Source/core/dom/Touch.idl
index c748ec8e0ef..574d68441d0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Touch.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Touch.idl
@@ -23,17 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface Touch {
- readonly attribute long clientX;
- readonly attribute long clientY;
- readonly attribute long screenX;
- readonly attribute long screenY;
- readonly attribute long pageX;
- readonly attribute long pageY;
+[
+ WillBeGarbageCollected,
+] interface Touch {
+ readonly attribute double clientX;
+ readonly attribute double clientY;
+ readonly attribute double screenX;
+ readonly attribute double screenY;
+ readonly attribute double pageX;
+ readonly attribute double pageY;
readonly attribute EventTarget target;
readonly attribute unsigned long identifier;
- readonly attribute long webkitRadiusX;
- readonly attribute long webkitRadiusY;
- readonly attribute float webkitRotationAngle;
- readonly attribute float webkitForce;
+ [MeasureAs=PrefixedTouchRadiusX] readonly attribute double webkitRadiusX;
+ [MeasureAs=PrefixedTouchRadiusY] readonly attribute double webkitRadiusY;
+ [MeasureAs=PrefixedTouchRotationAngle] readonly attribute float webkitRotationAngle;
+ [MeasureAs=PrefixedTouchForce] readonly attribute float webkitForce;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchController.cpp b/chromium/third_party/WebKit/Source/core/dom/TouchController.cpp
deleted file mode 100644
index a24bc81c166..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TouchController.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/TouchController.h"
-
-#include "core/dom/Document.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/TouchEvent.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-
-namespace WebCore {
-
-TouchController::TouchController(Document* document)
- : DOMWindowLifecycleObserver(document->domWindow())
- , DocumentLifecycleObserver(document)
-{
-}
-
-TouchController::~TouchController()
-{
-}
-
-const char* TouchController::supplementName()
-{
- return "TouchController";
-}
-
-TouchController* TouchController::from(Document* document)
-{
- TouchController* controller = static_cast<TouchController*>(DocumentSupplement::from(document, supplementName()));
- if (!controller) {
- controller = new TouchController(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(controller));
- }
- return controller;
-}
-
-void TouchController::didAddTouchEventHandler(Document* document, Node* handler)
-{
- if (!m_touchEventTargets)
- m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
- m_touchEventTargets->add(handler);
- if (Document* parent = document->parentDocument()) {
- TouchController::from(parent)->didAddTouchEventHandler(parent, document);
- return;
- }
- if (Page* page = document->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(document);
- if (m_touchEventTargets->size() == 1)
- page->chrome().client().needTouchEvents(true);
- }
-}
-
-void TouchController::didRemoveTouchEventHandler(Document* document, Node* handler)
-{
- if (!m_touchEventTargets)
- return;
- ASSERT(m_touchEventTargets->contains(handler));
- m_touchEventTargets->remove(handler);
- if (Document* parent = document->parentDocument()) {
- TouchController::from(parent)->didRemoveTouchEventHandler(parent, document);
- return;
- }
-
- Page* page = document->page();
- if (!page)
- return;
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(document);
- if (m_touchEventTargets->size())
- return;
- for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document() && TouchController::from(frame->document())->hasTouchEventHandlers())
- return;
- }
- page->chrome().client().needTouchEvents(false);
-}
-
-void TouchController::didRemoveEventTargetNode(Document* document, Node* handler)
-{
- if (m_touchEventTargets && !m_touchEventTargets->isEmpty()) {
- if (handler == document)
- m_touchEventTargets->clear();
- else
- m_touchEventTargets->removeAll(handler);
- Document* parent = document->parentDocument();
- if (m_touchEventTargets->isEmpty() && parent)
- TouchController::from(parent)->didRemoveEventTargetNode(parent, document);
- }
-}
-
-void TouchController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (isTouchEventType(eventType)) {
- Document* document = window->document();
- didAddTouchEventHandler(document, document);
- }
-}
-
-void TouchController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (isTouchEventType(eventType)) {
- Document* document = window->document();
- didRemoveTouchEventHandler(document, document);
- }
-}
-
-void TouchController::didRemoveAllEventListeners(DOMWindow* window)
-{
- if (Document* document = window->document())
- didRemoveEventTargetNode(document, document);
-}
-
-void TouchController::documentWasDetached()
-{
- Document* document = static_cast<Document*>(executionContext());
- Document* parentDocument = document->parentDocument();
-
- if (parentDocument) {
- TouchController* parentController = TouchController::from(parentDocument);
- if (parentController->hasTouchEventHandlers())
- parentController->didRemoveEventTargetNode(parentDocument, document);
- }
-}
-
-void TouchController::documentBeingDestroyed()
-{
- Document* document = static_cast<Document*>(executionContext());
-
- if (Document* ownerDocument = document->ownerDocument())
- TouchController::from(ownerDocument)->didRemoveEventTargetNode(ownerDocument, document);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchController.h b/chromium/third_party/WebKit/Source/core/dom/TouchController.h
deleted file mode 100644
index 8ce5e13e4ab..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TouchController.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-* Copyright (C) 2013 Google, Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef TouchController_h
-#define TouchController_h
-
-#include "core/dom/DocumentLifecycleObserver.h"
-#include "core/events/Event.h"
-#include "core/dom/Node.h"
-#include "core/frame/DOMWindowLifecycleObserver.h"
-#include "platform/Supplementable.h"
-#include "wtf/HashSet.h"
-
-namespace WebCore {
-
-typedef HashCountedSet<Node*> TouchEventTargetSet;
-
-class Document;
-class DOMWindow;
-
-class TouchController : public DocumentSupplement, public DOMWindowLifecycleObserver, public DocumentLifecycleObserver {
-
-public:
- virtual ~TouchController();
-
- static const char* supplementName();
- static TouchController* from(Document*);
-
- bool hasTouchEventHandlers() const { return m_touchEventTargets ? m_touchEventTargets->size() : false; }
-
- void didAddTouchEventHandler(Document*, Node*);
- void didRemoveTouchEventHandler(Document*, Node*);
- void didRemoveEventTargetNode(Document*, Node*);
-
- const TouchEventTargetSet* touchEventTargets() const { return m_touchEventTargets.get(); }
-
- // Inherited from DOMWindowLifecycleObserver
- virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
- virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
- virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE;
-
- // Inherited from DocumentLifecycleObserver
- virtual void documentWasDetached() OVERRIDE;
- virtual void documentBeingDestroyed() OVERRIDE;
-
-private:
- explicit TouchController(Document*);
-
- OwnPtr<TouchEventTargetSet> m_touchEventTargets;
-};
-
-} // namespace WebCore
-
-#endif // TouchController_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp b/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp
index 3653a2eaebb..b636f20a54a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp
@@ -41,4 +41,9 @@ const Touch* TouchList::item(unsigned index) const
return const_cast<TouchList*>(this)->item(index);
}
+void TouchList::trace(Visitor* visitor)
+{
+ visitor->trace(m_values);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchList.h b/chromium/third_party/WebKit/Source/core/dom/TouchList.h
index 6d5f2bf2c9c..0f827589bfc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TouchList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TouchList.h
@@ -28,21 +28,22 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/Touch.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
namespace WebCore {
-class TouchList : public RefCounted<TouchList>, public ScriptWrappable {
+class TouchList : public RefCountedWillBeGarbageCollectedFinalized<TouchList>, public ScriptWrappable {
public:
- static PassRefPtr<TouchList> create()
+ static PassRefPtrWillBeRawPtr<TouchList> create()
{
- return adoptRef(new TouchList);
+ return adoptRefWillBeNoop(new TouchList);
}
- static PassRefPtr<TouchList> create(Vector<RefPtr<Touch> >& touches)
+ static PassRefPtrWillBeRawPtr<TouchList> create(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches)
{
- return adoptRef(new TouchList(touches));
+ return adoptRefWillBeNoop(new TouchList(touches));
}
unsigned length() const { return m_values.size(); }
@@ -50,7 +51,9 @@ public:
Touch* item(unsigned);
const Touch* item(unsigned) const;
- void append(const PassRefPtr<Touch> touch) { m_values.append(touch); }
+ void append(const PassRefPtrWillBeRawPtr<Touch> touch) { m_values.append(touch); }
+
+ void trace(Visitor*);
private:
TouchList()
@@ -58,13 +61,13 @@ private:
ScriptWrappable::init(this);
}
- TouchList(Vector<RefPtr<Touch> >& touches)
+ TouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches)
{
m_values.swap(touches);
ScriptWrappable::init(this);
}
- Vector<RefPtr<Touch> > m_values;
+ WillBeHeapVector<RefPtrWillBeMember<Touch> > m_values;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchList.idl b/chromium/third_party/WebKit/Source/core/dom/TouchList.idl
index 351a59cbc20..516946de775 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TouchList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/TouchList.idl
@@ -23,7 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface TouchList {
+[
+ WillBeGarbageCollected,
+] interface TouchList {
readonly attribute unsigned long length;
getter Touch item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/dom/TransformSource.h b/chromium/third_party/WebKit/Source/core/dom/TransformSource.h
index f637ce36c52..a82c2a2e26b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TransformSource.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TransformSource.h
@@ -21,9 +21,7 @@
#define TransformSource_h
#include "wtf/FastAllocBase.h"
-#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
-#include "wtf/text/WTFString.h"
#include <libxml/tree.h>
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp
index 56ad63782b7..0ffc52ba0b3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp
@@ -27,24 +27,25 @@
#include "config.h"
#include "core/dom/TreeScope.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/IdTargetObserverRegistry.h"
+#include "core/dom/NodeRenderStyle.h"
#include "core/dom/TreeScopeAdopter.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/EventPath.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLMapElement.h"
#include "core/page/DOMSelection.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderView.h"
@@ -52,93 +53,96 @@
namespace WebCore {
-struct SameSizeAsTreeScope {
- virtual ~SameSizeAsTreeScope();
- void* pointers[8];
- int ints[1];
-};
-
-COMPILE_ASSERT(sizeof(TreeScope) == sizeof(SameSizeAsTreeScope), treescope_should_stay_small);
-
using namespace HTMLNames;
-TreeScope::TreeScope(ContainerNode* rootNode, Document* document)
- : m_rootNode(rootNode)
- , m_documentScope(document)
- , m_parentTreeScope(document)
+TreeScope::TreeScope(ContainerNode& rootNode, Document& document)
+ : m_rootNode(&rootNode)
+ , m_document(&document)
+ , m_parentTreeScope(&document)
+#if !ENABLE(OILPAN)
, m_guardRefCount(0)
+#endif
, m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
{
- ASSERT(rootNode);
- ASSERT(document);
ASSERT(rootNode != document);
+#if !ENABLE(OILPAN)
m_parentTreeScope->guardRef();
+#endif
m_rootNode->setTreeScope(this);
}
-TreeScope::TreeScope(Document* document)
+TreeScope::TreeScope(Document& document)
: m_rootNode(document)
- , m_documentScope(document)
- , m_parentTreeScope(0)
+ , m_document(&document)
+ , m_parentTreeScope(nullptr)
+#if !ENABLE(OILPAN)
, m_guardRefCount(0)
+#endif
, m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
{
- ASSERT(document);
m_rootNode->setTreeScope(this);
}
-TreeScope::TreeScope()
- : m_rootNode(0)
- , m_documentScope(0)
- , m_parentTreeScope(0)
- , m_guardRefCount(0)
-{
-}
-
TreeScope::~TreeScope()
{
+#if !ENABLE(OILPAN)
ASSERT(!m_guardRefCount);
m_rootNode->setTreeScope(0);
if (m_selection) {
m_selection->clearTreeScope();
- m_selection = 0;
+ m_selection = nullptr;
}
if (m_parentTreeScope)
m_parentTreeScope->guardDeref();
+#endif
+}
+
+TreeScope* TreeScope::olderShadowRootOrParentTreeScope() const
+{
+ if (rootNode().isShadowRoot()) {
+ if (ShadowRoot* olderShadowRoot = toShadowRoot(rootNode()).olderShadowRoot())
+ return olderShadowRoot;
+ }
+ return parentTreeScope();
+}
+
+bool TreeScope::isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope& scope) const
+{
+ for (const TreeScope* current = &scope; current; current = current->olderShadowRootOrParentTreeScope()) {
+ if (current == this)
+ return true;
+ }
+ return false;
}
bool TreeScope::rootNodeHasTreeSharedParent() const
{
- return rootNode()->hasTreeSharedParent();
+ return rootNode().hasTreeSharedParent();
}
+#if !ENABLE(OILPAN)
void TreeScope::destroyTreeScopeData()
{
m_elementsById.clear();
m_imageMapsByName.clear();
m_labelsByForAttribute.clear();
}
+#endif
-void TreeScope::clearDocumentScope()
-{
- ASSERT(rootNode()->isDocumentNode());
- m_documentScope = 0;
-}
-
-void TreeScope::setParentTreeScope(TreeScope* newParentScope)
+void TreeScope::setParentTreeScope(TreeScope& newParentScope)
{
// A document node cannot be re-parented.
- ASSERT(!rootNode()->isDocumentNode());
- // Every scope other than document needs a parent scope.
- ASSERT(newParentScope);
+ ASSERT(!rootNode().isDocumentNode());
- newParentScope->guardRef();
+#if !ENABLE(OILPAN)
+ newParentScope.guardRef();
if (m_parentTreeScope)
m_parentTreeScope->guardDeref();
- m_parentTreeScope = newParentScope;
- setDocumentScope(newParentScope->documentScope());
+#endif
+ m_parentTreeScope = &newParentScope;
+ setDocument(newParentScope.document());
}
Element* TreeScope::getElementById(const AtomicString& elementId) const
@@ -150,6 +154,16 @@ Element* TreeScope::getElementById(const AtomicString& elementId) const
return m_elementsById->getElementById(elementId.impl(), this);
}
+const Vector<Element*>& TreeScope::getAllElementsById(const AtomicString& elementId) const
+{
+ DEFINE_STATIC_LOCAL(Vector<Element*>, emptyVector, ());
+ if (elementId.isEmpty())
+ return emptyVector;
+ if (!m_elementsById)
+ return emptyVector;
+ return m_elementsById->getAllElementsById(elementId.impl(), this);
+}
+
void TreeScope::addElementById(const AtomicString& elementId, Element* element)
{
if (!m_elementsById)
@@ -208,44 +222,38 @@ HTMLMapElement* TreeScope::getImageMap(const String& url) const
return 0;
size_t hashPos = url.find('#');
String name = (hashPos == kNotFound ? url : url.substring(hashPos + 1)).impl();
- if (rootNode()->document().isHTMLDocument())
+ if (rootNode().document().isHTMLDocument())
return toHTMLMapElement(m_imageMapsByName->getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
return toHTMLMapElement(m_imageMapsByName->getElementByMapName(AtomicString(name).impl(), this));
}
-RenderObject* rendererFromPoint(Document* document, int x, int y, LayoutPoint* localPoint)
+HitTestResult hitTestInDocument(const Document* document, int x, int y)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
if (!frame)
- return 0;
+ return HitTestResult();
FrameView* frameView = frame->view();
if (!frameView)
- return 0;
+ return HitTestResult();
float scaleFactor = frame->pageZoomFactor();
IntPoint point = roundedIntPoint(FloatPoint(x * scaleFactor + frameView->scrollX(), y * scaleFactor + frameView->scrollY()));
if (!frameView->visibleContentRect().contains(point))
- return 0;
+ return HitTestResult();
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
HitTestResult result(point);
document->renderView()->hitTest(request, result);
-
- if (localPoint)
- *localPoint = result.localPoint();
-
- return result.renderer();
+ return result;
}
Element* TreeScope::elementFromPoint(int x, int y) const
{
- RenderObject* renderer = rendererFromPoint(&rootNode()->document(), x, y);
- if (!renderer)
- return 0;
- Node* node = renderer->node();
- if (!node)
+ HitTestResult result = hitTestInDocument(&rootNode().document(), x, y);
+ Node* node = result.innerNode();
+ if (!node || node->isDocumentNode())
return 0;
if (node->isPseudoElement() || node->isTextNode())
node = node->parentOrShadowHostNode();
@@ -276,14 +284,10 @@ HTMLLabelElement* TreeScope::labelElementForId(const AtomicString& forAttributeV
if (!m_labelsByForAttribute) {
// Populate the map on first access.
m_labelsByForAttribute = adoptPtr(new DocumentOrderedMap);
- ASSERT(rootNode());
- for (Element* element = ElementTraversal::firstWithin(*rootNode()); element; element = ElementTraversal::next(*element)) {
- if (isHTMLLabelElement(element)) {
- HTMLLabelElement* label = toHTMLLabelElement(element);
- const AtomicString& forValue = label->fastGetAttribute(forAttr);
- if (!forValue.isEmpty())
- addLabel(forValue, label);
- }
+ for (HTMLLabelElement* label = Traversal<HTMLLabelElement>::firstWithin(rootNode()); label; label = Traversal<HTMLLabelElement>::next(*label)) {
+ const AtomicString& forValue = label->fastGetAttribute(forAttr);
+ if (!forValue.isEmpty())
+ addLabel(forValue, label);
}
}
@@ -292,7 +296,7 @@ HTMLLabelElement* TreeScope::labelElementForId(const AtomicString& forAttributeV
DOMSelection* TreeScope::getSelection() const
{
- if (!rootNode()->document().frame())
+ if (!rootNode().document().frame())
return 0;
if (m_selection)
@@ -309,21 +313,17 @@ Element* TreeScope::findAnchor(const String& name)
{
if (name.isEmpty())
return 0;
- if (Element* element = getElementById(name))
+ if (Element* element = getElementById(AtomicString(name)))
return element;
- ASSERT(rootNode());
- for (Element* element = ElementTraversal::firstWithin(*rootNode()); element; element = ElementTraversal::next(*element)) {
- if (isHTMLAnchorElement(element)) {
- HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
- if (rootNode()->document().inQuirksMode()) {
- // Quirks mode, case insensitive comparison of names.
- if (equalIgnoringCase(anchor->name(), name))
- return anchor;
- } else {
- // Strict mode, names need to match exactly.
- if (anchor->name() == name)
- return anchor;
- }
+ for (HTMLAnchorElement* anchor = Traversal<HTMLAnchorElement>::firstWithin(rootNode()); anchor; anchor = Traversal<HTMLAnchorElement>::next(*anchor)) {
+ if (rootNode().document().inQuirksMode()) {
+ // Quirks mode, case insensitive comparison of names.
+ if (equalIgnoringCase(anchor->name(), name))
+ return anchor;
+ } else {
+ // Strict mode, names need to match exactly.
+ if (anchor->name() == name)
+ return anchor;
}
}
return 0;
@@ -331,14 +331,16 @@ Element* TreeScope::findAnchor(const String& name)
bool TreeScope::applyAuthorStyles() const
{
- return !rootNode()->isShadowRoot() || toShadowRoot(rootNode())->applyAuthorStyles();
+ return rootNode().isDocumentNode();
}
void TreeScope::adoptIfNeeded(Node& node)
{
ASSERT(this);
ASSERT(!node.isDocumentNode());
+#if !ENABLE(OILPAN)
ASSERT_WITH_SECURITY_IMPLICATION(!node.m_deletionHasBegun);
+#endif
TreeScopeAdopter adopter(node, *this);
if (adopter.needsScopeChange())
adopter.execute();
@@ -347,15 +349,17 @@ void TreeScope::adoptIfNeeded(Node& node)
static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame)
{
for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
- if (focusedFrame->tree().parent() == currentFrame)
- return focusedFrame->ownerElement();
+ if (focusedFrame->tree().parent() == currentFrame) {
+ // FIXME: This won't work for OOPI.
+ return focusedFrame->deprecatedLocalOwner();
+ }
}
return 0;
}
Element* TreeScope::adjustedFocusedElement() const
{
- Document& document = rootNode()->document();
+ Document& document = rootNode().document();
Element* element = document.focusedElement();
if (!element && document.page())
element = focusedFrameOwnerElement(document.page()->focusController().focusedFrame(), document.frame());
@@ -398,12 +402,12 @@ unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
const TreeScope* child1 = chain1[--index1];
const TreeScope* child2 = chain2[--index2];
if (child1 != child2) {
- Node* shadowHost1 = child1->rootNode()->parentOrShadowHostNode();
- Node* shadowHost2 = child2->rootNode()->parentOrShadowHostNode();
+ Node* shadowHost1 = child1->rootNode().parentOrShadowHostNode();
+ Node* shadowHost2 = child2->rootNode().parentOrShadowHostNode();
if (shadowHost1 != shadowHost2)
return shadowHost1->compareDocumentPositionInternal(shadowHost2, Node::TreatShadowTreesAsDisconnected);
- for (const ShadowRoot* child = toShadowRoot(child2->rootNode())->olderShadowRoot(); child; child = child->olderShadowRoot())
+ for (const ShadowRoot* child = toShadowRoot(child2->rootNode()).olderShadowRoot(); child; child = child->olderShadowRoot())
if (child == child1)
return Node::DOCUMENT_POSITION_FOLLOWING;
@@ -418,6 +422,32 @@ unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
Node::DOCUMENT_POSITION_PRECEDING | Node::DOCUMENT_POSITION_CONTAINS;
}
+const TreeScope* TreeScope::commonAncestorTreeScope(const TreeScope& other) const
+{
+ Vector<const TreeScope*, 16> thisChain;
+ for (const TreeScope* tree = this; tree; tree = tree->parentTreeScope())
+ thisChain.append(tree);
+
+ Vector<const TreeScope*, 16> otherChain;
+ for (const TreeScope* tree = &other; tree; tree = tree->parentTreeScope())
+ otherChain.append(tree);
+
+ // Keep popping out the last elements of these chains until a mismatched pair is found. If |this| and |other|
+ // belong to different documents, null will be returned.
+ const TreeScope* lastAncestor = 0;
+ while (!thisChain.isEmpty() && !otherChain.isEmpty() && thisChain.last() == otherChain.last()) {
+ lastAncestor = thisChain.last();
+ thisChain.removeLast();
+ otherChain.removeLast();
+ }
+ return lastAncestor;
+}
+
+TreeScope* TreeScope::commonAncestorTreeScope(TreeScope& other)
+{
+ return const_cast<TreeScope*>(static_cast<const TreeScope&>(*this).commonAncestorTreeScope(other));
+}
+
static void listTreeScopes(Node* node, Vector<TreeScope*, 5>& treeScopes)
{
while (true) {
@@ -451,24 +481,24 @@ TreeScope* commonTreeScope(Node* nodeA, Node* nodeB)
return treeScopesA[indexA] == treeScopesB[indexB] ? treeScopesA[indexA] : 0;
}
-#if SECURITY_ASSERT_ENABLED
+#if SECURITY_ASSERT_ENABLED && !ENABLE(OILPAN)
bool TreeScope::deletionHasBegun()
{
- return rootNode() && rootNode()->m_deletionHasBegun;
+ return rootNode().m_deletionHasBegun;
}
void TreeScope::beginDeletion()
{
- rootNode()->m_deletionHasBegun = true;
+ rootNode().m_deletionHasBegun = true;
}
#endif
+#if !ENABLE(OILPAN)
int TreeScope::refCount() const
{
- if (Node* root = rootNode())
- return root->refCount();
- return 0;
+ return rootNode().refCount();
}
+#endif
bool TreeScope::isInclusiveAncestorOf(const TreeScope& scope) const
{
@@ -484,9 +514,8 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
if (key.isEmpty())
return 0;
Element* result = 0;
- Node* root = rootNode();
- ASSERT(root);
- for (Element* element = ElementTraversal::firstWithin(*root); element; element = ElementTraversal::next(*element, root)) {
+ Node& root = rootNode();
+ for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) {
if (equalIgnoringCase(element->fastGetAttribute(accesskeyAttr), key))
result = element;
for (ShadowRoot* shadowRoot = element->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
@@ -497,4 +526,24 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
return result;
}
+void TreeScope::setNeedsStyleRecalcForViewportUnits()
+{
+ for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::nextIncludingPseudo(*element)) {
+ for (ShadowRoot* root = element->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ root->setNeedsStyleRecalcForViewportUnits();
+ RenderStyle* style = element->renderStyle();
+ if (style && style->hasViewportUnits())
+ element->setNeedsStyleRecalc(LocalStyleChange);
+ }
+}
+
+void TreeScope::trace(Visitor* visitor)
+{
+ visitor->trace(m_rootNode);
+ visitor->trace(m_document);
+ visitor->trace(m_parentTreeScope);
+ visitor->trace(m_idTargetObserverRegistry);
+ visitor->trace(m_selection);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScope.h b/chromium/third_party/WebKit/Source/core/dom/TreeScope.h
index 718d7e7fb00..79192e0d7c4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScope.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScope.h
@@ -28,7 +28,7 @@
#define TreeScope_h
#include "core/dom/DocumentOrderedMap.h"
-#include "wtf/Forward.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -39,6 +39,7 @@ class Document;
class Element;
class HTMLLabelElement;
class HTMLMapElement;
+class HitTestResult;
class LayoutPoint;
class IdTargetObserverRegistry;
class Node;
@@ -47,22 +48,26 @@ class RenderObject;
// A class which inherits both Node and TreeScope must call clearRareData() in its destructor
// so that the Node destructor no longer does problematic NodeList cache manipulation in
// the destructor.
-class TreeScope {
- friend class Document;
- friend class TreeScopeAdopter;
-
+class TreeScope : public WillBeGarbageCollectedMixin {
public:
TreeScope* parentTreeScope() const { return m_parentTreeScope; }
- void setParentTreeScope(TreeScope*);
+
+ TreeScope* olderShadowRootOrParentTreeScope() const;
+ bool isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope&) const;
Element* adjustedFocusedElement() const;
Element* getElementById(const AtomicString&) const;
+ const Vector<Element*>& getAllElementsById(const AtomicString&) const;
bool hasElementWithId(StringImpl* id) const;
bool containsMultipleElementsWithId(const AtomicString& id) const;
void addElementById(const AtomicString& elementId, Element*);
void removeElementById(const AtomicString& elementId, Element*);
- Document* documentScope() const { return m_documentScope; }
+ Document& document() const
+ {
+ ASSERT(m_document);
+ return *m_document;
+ }
Node* ancestorInThisScope(Node*) const;
@@ -92,10 +97,12 @@ public:
// Used by the basic DOM mutation methods (e.g., appendChild()).
void adoptIfNeeded(Node&);
- Node* rootNode() const { return m_rootNode; }
+ Node& rootNode() const { return *m_rootNode; }
IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
+
+#if !ENABLE(OILPAN)
// Nodes belonging to this scope hold guard references -
// these are enough to keep the scope from being destroyed, but
// not enough to keep it from removing its children. This allows a
@@ -109,6 +116,7 @@ public:
void guardDeref()
{
+ ASSERT(m_guardRefCount > 0);
ASSERT(!deletionHasBegun());
--m_guardRefCount;
if (!m_guardRefCount && !refCount() && !rootNodeHasTreeSharedParent()) {
@@ -116,35 +124,44 @@ public:
delete this;
}
}
+#endif
void removedLastRefToScope();
bool isInclusiveAncestorOf(const TreeScope&) const;
unsigned short comparePosition(const TreeScope&) const;
+ const TreeScope* commonAncestorTreeScope(const TreeScope& other) const;
+ TreeScope* commonAncestorTreeScope(TreeScope& other);
+
Element* getElementByAccessKey(const String& key) const;
+ virtual void trace(Visitor*);
+
protected:
- TreeScope(ContainerNode*, Document*);
- TreeScope(Document*);
+ TreeScope(ContainerNode&, Document&);
+ TreeScope(Document&);
virtual ~TreeScope();
+#if !ENABLE(OILPAN)
void destroyTreeScopeData();
- void clearDocumentScope();
- void setDocumentScope(Document* document)
- {
- ASSERT(document);
- m_documentScope = document;
- }
+#endif
+
+ void setDocument(Document& document) { m_document = &document; }
+ void setParentTreeScope(TreeScope&);
+#if !ENABLE(OILPAN)
bool hasGuardRefCount() const { return m_guardRefCount; }
+#endif
-private:
- TreeScope();
+ void setNeedsStyleRecalcForViewportUnits();
+private:
virtual void dispose() { }
+#if !ENABLE(OILPAN)
int refCount() const;
+
#if SECURITY_ASSERT_ENABLED
bool deletionHasBegun();
void beginDeletion();
@@ -152,21 +169,25 @@ private:
bool deletionHasBegun() { return false; }
void beginDeletion() { }
#endif
+#endif
bool rootNodeHasTreeSharedParent() const;
- Node* m_rootNode;
- Document* m_documentScope;
- TreeScope* m_parentTreeScope;
+ RawPtrWillBeMember<Node> m_rootNode;
+ RawPtrWillBeMember<Document> m_document;
+ RawPtrWillBeMember<TreeScope> m_parentTreeScope;
+
+#if !ENABLE(OILPAN)
int m_guardRefCount;
+#endif
OwnPtr<DocumentOrderedMap> m_elementsById;
OwnPtr<DocumentOrderedMap> m_imageMapsByName;
OwnPtr<DocumentOrderedMap> m_labelsByForAttribute;
- OwnPtr<IdTargetObserverRegistry> m_idTargetObserverRegistry;
+ OwnPtrWillBeMember<IdTargetObserverRegistry> m_idTargetObserverRegistry;
- mutable RefPtr<DOMSelection> m_selection;
+ mutable RefPtrWillBeMember<DOMSelection> m_selection;
};
inline bool TreeScope::hasElementWithId(StringImpl* id) const
@@ -187,7 +208,7 @@ inline bool operator!=(const TreeScope& a, const TreeScope& b) { return !(a == b
inline bool operator!=(const TreeScope& a, const TreeScope* b) { return !(a == b); }
inline bool operator!=(const TreeScope* a, const TreeScope& b) { return !(a == b); }
-RenderObject* rendererFromPoint(Document*, int x, int y, LayoutPoint* localPoint = 0);
+HitTestResult hitTestInDocument(const Document*, int x, int y);
TreeScope* commonTreeScope(Node*, Node*);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp
index 366b4af3fa1..ecd1147ea08 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp
@@ -38,24 +38,25 @@ void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
{
ASSERT(needsScopeChange());
+#if !ENABLE(OILPAN)
m_oldScope.guardRef();
+#endif
// If an element is moved from a document and then eventually back again the collection cache for
// that element may contain stale data as changes made to it will have updated the DOMTreeVersion
// of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
// we ensure that the collection cache will be invalidated as needed when the element is moved back.
- Document* oldDocument = m_oldScope.documentScope();
- ASSERT(oldDocument);
- Document* newDocument = m_newScope.documentScope();
+ Document& oldDocument = m_oldScope.document();
+ Document& newDocument = m_newScope.document();
bool willMoveToNewDocument = oldDocument != newDocument;
if (willMoveToNewDocument)
- oldDocument->incDOMTreeVersion();
+ oldDocument.incDOMTreeVersion();
for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
updateTreeScope(*node);
if (willMoveToNewDocument)
- moveNodeToNewDocument(*node, *oldDocument, newDocument);
+ moveNodeToNewDocument(*node, oldDocument, newDocument);
else if (node->hasRareData()) {
NodeRareData* rareData = node->rareData();
if (rareData->nodeLists())
@@ -66,23 +67,26 @@ void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
continue;
if (node->hasSyntheticAttrChildNodes()) {
- const Vector<RefPtr<Attr> >& attrs = toElement(node)->attrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& attrs = *toElement(node)->attrNodeList();
for (unsigned i = 0; i < attrs.size(); ++i)
moveTreeToNewScope(*attrs[i]);
}
for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) {
- shadow->setParentTreeScope(&m_newScope);
+ shadow->setParentTreeScope(m_newScope);
if (willMoveToNewDocument)
- moveTreeToNewDocument(*shadow, *oldDocument, newDocument);
+ moveTreeToNewDocument(*shadow, oldDocument, newDocument);
}
}
+#if !ENABLE(OILPAN)
m_oldScope.guardDeref();
+#endif
}
-void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument, Document* newDocument) const
+void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument, Document& newDocument) const
{
+ ASSERT(oldDocument != newDocument);
for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
moveNodeToNewDocument(*node, oldDocument, newDocument);
for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot())
@@ -106,25 +110,27 @@ inline void TreeScopeAdopter::updateTreeScope(Node& node) const
{
ASSERT(!node.isTreeScope());
ASSERT(node.treeScope() == m_oldScope);
+#if !ENABLE(OILPAN)
m_newScope.guardRef();
m_oldScope.guardDeref();
+#endif
node.setTreeScope(&m_newScope);
}
-inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document* newDocument) const
+inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument) const
{
- ASSERT(!node.inDocument() || oldDocument != newDocument);
+ ASSERT(oldDocument != newDocument);
if (node.hasRareData()) {
NodeRareData* rareData = node.rareData();
if (rareData->nodeLists())
- rareData->nodeLists()->adoptDocument(&oldDocument, newDocument);
+ rareData->nodeLists()->adoptDocument(oldDocument, newDocument);
}
- oldDocument.moveNodeIteratorsToNewDocument(&node, newDocument);
+ oldDocument.moveNodeIteratorsToNewDocument(node, newDocument);
if (node.isShadowRoot())
- toShadowRoot(node).setDocumentScope(newDocument);
+ toShadowRoot(node).setDocument(newDocument);
#ifndef NDEBUG
didMoveToNewDocumentWasCalled = false;
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h
index 17742ba2553..85310ec0888 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h
@@ -32,6 +32,7 @@ namespace WebCore {
class TreeScope;
class TreeScopeAdopter {
+ STACK_ALLOCATED();
public:
TreeScopeAdopter(Node& toAdopt, TreeScope& newScope);
@@ -47,8 +48,8 @@ public:
private:
void updateTreeScope(Node&) const;
void moveTreeToNewScope(Node&) const;
- void moveTreeToNewDocument(Node&, Document& oldDocument, Document* newDocument) const;
- void moveNodeToNewDocument(Node&, Document& oldDocument, Document* newDocument) const;
+ void moveTreeToNewDocument(Node&, Document& oldDocument, Document& newDocument) const;
+ void moveNodeToNewDocument(Node&, Document& oldDocument, Document& newDocument) const;
Node& m_toAdopt;
TreeScope& m_newScope;
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp
new file mode 100644
index 00000000000..d6b05637f98
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/TreeScopeStyleSheetCollection.h"
+
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleRuleImport.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/css/invalidation/StyleSheetInvalidationAnalysis.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Element.h"
+#include "core/dom/StyleEngine.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLStyleElement.h"
+
+namespace WebCore {
+
+TreeScopeStyleSheetCollection::TreeScopeStyleSheetCollection(TreeScope& treeScope)
+ : m_treeScope(treeScope)
+ , m_hadActiveLoadingStylesheet(false)
+ , m_usesRemUnits(false)
+{
+}
+
+void TreeScopeStyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
+{
+ if (!node->inDocument())
+ return;
+
+ // Until the <body> exists, we have no choice but to compare document positions,
+ // since styles outside of the body and head continue to be shunted into the head
+ // (and thus can shift to end up before dynamically added DOM content that is also
+ // outside the body).
+ if (createdByParser && document().body())
+ m_styleSheetCandidateNodes.parserAdd(node);
+ else
+ m_styleSheetCandidateNodes.add(node);
+
+ if (!isHTMLStyleElement(*node))
+ return;
+
+ ContainerNode* scopingNode = toHTMLStyleElement(*node).scopingNode();
+ if (!isTreeScopeRoot(scopingNode))
+ m_scopingNodesForStyleScoped.add(scopingNode);
+}
+
+void TreeScopeStyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
+{
+ m_styleSheetCandidateNodes.remove(node);
+
+ if (!isTreeScopeRoot(scopingNode))
+ m_scopingNodesForStyleScoped.remove(scopingNode);
+}
+
+TreeScopeStyleSheetCollection::StyleResolverUpdateType TreeScopeStyleSheetCollection::compareStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& oldStyleSheets, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStylesheets, WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& addedSheets)
+{
+ unsigned newStyleSheetCount = newStylesheets.size();
+ unsigned oldStyleSheetCount = oldStyleSheets.size();
+ ASSERT(newStyleSheetCount >= oldStyleSheetCount);
+
+ if (!newStyleSheetCount)
+ return Reconstruct;
+
+ unsigned newIndex = 0;
+ for (unsigned oldIndex = 0; oldIndex < oldStyleSheetCount; ++oldIndex) {
+ while (oldStyleSheets[oldIndex] != newStylesheets[newIndex]) {
+ addedSheets.append(newStylesheets[newIndex]->contents());
+ if (++newIndex == newStyleSheetCount)
+ return Reconstruct;
+ }
+ if (++newIndex == newStyleSheetCount)
+ return Reconstruct;
+ }
+ bool hasInsertions = !addedSheets.isEmpty();
+ while (newIndex < newStyleSheetCount) {
+ addedSheets.append(newStylesheets[newIndex]->contents());
+ ++newIndex;
+ }
+ // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
+ // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
+ return hasInsertions ? Reset : Additive;
+}
+
+bool TreeScopeStyleSheetCollection::activeLoadingStyleSheetLoaded(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStyleSheets)
+{
+ // StyleSheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
+ bool hasActiveLoadingStylesheet = false;
+ unsigned newStylesheetCount = newStyleSheets.size();
+ for (unsigned i = 0; i < newStylesheetCount; ++i) {
+ if (newStyleSheets[i]->isLoading())
+ hasActiveLoadingStylesheet = true;
+ }
+ if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
+ m_hadActiveLoadingStylesheet = false;
+ return true;
+ }
+ m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
+ return false;
+}
+
+static bool findFontFaceRulesFromStyleSheetContents(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& sheets, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
+{
+ bool hasFontFaceRule = false;
+
+ for (unsigned i = 0; i < sheets.size(); ++i) {
+ ASSERT(sheets[i]);
+ if (sheets[i]->hasFontFaceRule()) {
+ // FIXME: We don't need this for styles in shadow tree.
+ sheets[i]->findFontFaceRules(fontFaceRules);
+ hasFontFaceRule = true;
+ }
+ }
+ return hasFontFaceRule;
+}
+
+void TreeScopeStyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const StyleSheetCollection& newCollection, StyleSheetChange& change)
+{
+ if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets()))
+ return;
+
+ if (updateMode != AnalyzedStyleUpdate)
+ return;
+
+ // Find out which stylesheets are new.
+ WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> > addedSheets;
+ if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheets().size()) {
+ change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleSheets, newCollection.activeAuthorStyleSheets(), addedSheets);
+ } else {
+ StyleResolverUpdateType updateType = compareStyleSheets(newCollection.activeAuthorStyleSheets(), m_activeAuthorStyleSheets, addedSheets);
+ if (updateType != Additive) {
+ change.styleResolverUpdateType = updateType;
+ } else {
+ change.styleResolverUpdateType = Reset;
+ // If @font-face is removed, needs full style recalc.
+ if (findFontFaceRulesFromStyleSheetContents(addedSheets, change.fontFaceRulesToRemove))
+ return;
+ }
+ }
+
+ // FIXME: If styleResolverUpdateType is Reconstruct, we should return early here since
+ // we need to recalc the whole document. It's wrong to use StyleSheetInvalidationAnalysis since
+ // it only looks at the addedSheets.
+
+ // No point in doing the analysis work if we're just going to recalc the whole document anyways.
+ // This needs to be done after the compareStyleSheets calls above to ensure we don't throw away
+ // the StyleResolver if we don't need to.
+ if (document().hasPendingForcedStyleRecalc())
+ return;
+
+ // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
+ if (!document().body() || document().hasNodesWithPlaceholderStyle())
+ return;
+ StyleSheetInvalidationAnalysis invalidationAnalysis(addedSheets);
+ if (invalidationAnalysis.dirtiesAllStyle())
+ return;
+ invalidationAnalysis.invalidateStyle(document());
+ change.requiresFullStyleRecalc = false;
+ return;
+}
+
+void TreeScopeStyleSheetCollection::clearMediaQueryRuleSetStyleSheets()
+{
+ for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) {
+ StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents();
+ if (contents->hasMediaQueries())
+ contents->clearRuleSet();
+ }
+}
+
+void TreeScopeStyleSheetCollection::enableExitTransitionStylesheets()
+{
+ DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
+ DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
+ for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
+ Node* node = *it;
+ if (isHTMLLinkElement(*node))
+ toHTMLLinkElement(node)->enableIfExitTransitionStyle();
+ }
+}
+
+void TreeScopeStyleSheetCollection::resetAllRuleSetsInTreeScope(StyleResolver* styleResolver)
+{
+ // FIXME: If many web developers use style scoped, implement reset RuleSets in per-scoping node manner.
+ if (DocumentOrderedList* styleScopedScopingNodes = scopingNodesForStyleScoped()) {
+ for (DocumentOrderedList::iterator it = styleScopedScopingNodes->begin(); it != styleScopedScopingNodes->end(); ++it)
+ styleResolver->resetAuthorStyle(toContainerNode(*it));
+ }
+ if (ListHashSet<Node*, 4>* removedNodes = scopingNodesRemoved()) {
+ for (ListHashSet<Node*, 4>::iterator it = removedNodes->begin(); it != removedNodes->end(); ++it)
+ styleResolver->resetAuthorStyle(toContainerNode(*it));
+ }
+ styleResolver->resetAuthorStyle(toContainerNode(&m_treeScope.rootNode()));
+}
+
+static bool styleSheetsUseRemUnits(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
+{
+ for (unsigned i = 0; i < sheets.size(); ++i) {
+ if (sheets[i]->contents()->usesRemUnits())
+ return true;
+ }
+ return false;
+}
+
+void TreeScopeStyleSheetCollection::updateUsesRemUnits()
+{
+ m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
new file mode 100644
index 00000000000..2eac88f2556
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TreeScopeStyleSheetCollection_h
+#define TreeScopeStyleSheetCollection_h
+
+#include "core/dom/Document.h"
+#include "core/dom/DocumentOrderedList.h"
+#include "core/dom/StyleSheetCollection.h"
+#include "core/dom/StyleSheetScopingNodeList.h"
+#include "core/dom/TreeScope.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/HashMap.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContainerNode;
+class DocumentStyleSheetCollector;
+class StyleEngine;
+class Node;
+class StyleSheetContents;
+class StyleSheetList;
+class StyleRuleFontFace;
+
+class TreeScopeStyleSheetCollection : public StyleSheetCollection {
+public:
+ void addStyleSheetCandidateNode(Node*, bool createdByParser);
+ void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode);
+ bool hasStyleSheetCandidateNodes() const { return !m_styleSheetCandidateNodes.isEmpty(); }
+
+ bool usesRemUnits() const { return m_usesRemUnits; }
+
+ DocumentOrderedList& styleSheetCandidateNodes() { return m_styleSheetCandidateNodes; }
+ DocumentOrderedList* scopingNodesForStyleScoped() { return m_scopingNodesForStyleScoped.scopingNodes(); }
+ ListHashSet<Node*, 4>* scopingNodesRemoved() { return m_scopingNodesForStyleScoped.scopingNodesRemoved(); }
+
+ void clearMediaQueryRuleSetStyleSheets();
+ void enableExitTransitionStylesheets();
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ StyleSheetCollection::trace(visitor);
+ }
+
+protected:
+ explicit TreeScopeStyleSheetCollection(TreeScope&);
+
+ Document& document() const { return m_treeScope.document(); }
+
+ enum StyleResolverUpdateType {
+ Reconstruct,
+ Reset,
+ Additive
+ };
+
+ class StyleSheetChange {
+ STACK_ALLOCATED();
+ public:
+ StyleResolverUpdateType styleResolverUpdateType;
+ bool requiresFullStyleRecalc;
+ WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> > fontFaceRulesToRemove;
+
+ StyleSheetChange()
+ : styleResolverUpdateType(Reconstruct)
+ , requiresFullStyleRecalc(true) { }
+ };
+
+ void analyzeStyleSheetChange(StyleResolverUpdateMode, const StyleSheetCollection&, StyleSheetChange&);
+ void resetAllRuleSetsInTreeScope(StyleResolver*);
+ void updateUsesRemUnits();
+
+private:
+ static StyleResolverUpdateType compareStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& oldStyleSheets, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStylesheets, WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& addedSheets);
+ bool activeLoadingStyleSheetLoaded(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStyleSheets);
+
+protected:
+ TreeScope& m_treeScope;
+ bool m_hadActiveLoadingStylesheet;
+ bool m_usesRemUnits;
+
+ DocumentOrderedList m_styleSheetCandidateNodes;
+ StyleSheetScopingNodeList m_scopingNodesForStyleScoped;
+};
+
+}
+
+#endif
+
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
new file mode 100644
index 00000000000..8c05c0fc3cf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
@@ -0,0 +1,99 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/TreeScope.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(TreeScopeTest, CommonAncestorOfSameTrees)
+{
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ EXPECT_EQ(document.get(), document->commonAncestorTreeScope(*document));
+
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = html->createShadowRoot(ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(shadowRoot.get(), shadowRoot->commonAncestorTreeScope(*shadowRoot));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfInclusiveTrees)
+{
+ // document
+ // | : Common ancestor is document.
+ // shadowRoot
+
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = html->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(document.get(), document->commonAncestorTreeScope(*shadowRoot));
+ EXPECT_EQ(document.get(), shadowRoot->commonAncestorTreeScope(*document));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfSiblingTrees)
+{
+ // document
+ // / \ : Common ancestor is document.
+ // A B
+
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Element> head = document->createElement("head", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(head);
+ RefPtrWillBeRawPtr<Element> body = document->createElement("body", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(body);
+
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootA = head->createShadowRoot(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootB = body->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(document.get(), shadowRootA->commonAncestorTreeScope(*shadowRootB));
+ EXPECT_EQ(document.get(), shadowRootB->commonAncestorTreeScope(*shadowRootA));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfTreesAtDifferentDepths)
+{
+ // document
+ // / \ : Common ancestor is document.
+ // Y B
+ // /
+ // A
+
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Element> head = document->createElement("head", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(head);
+ RefPtrWillBeRawPtr<Element> body = document->createElement("body", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(body);
+
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootY = head->createShadowRoot(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootB = body->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ RefPtrWillBeRawPtr<Element> divInY = document->createElement("div", nullAtom, ASSERT_NO_EXCEPTION);
+ shadowRootY->appendChild(divInY);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootA = divInY->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(document.get(), shadowRootA->commonAncestorTreeScope(*shadowRootB));
+ EXPECT_EQ(document.get(), shadowRootB->commonAncestorTreeScope(*shadowRootA));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfTreesInDifferentDocuments)
+{
+ RefPtrWillBeRawPtr<Document> document1 = Document::create();
+ RefPtrWillBeRawPtr<Document> document2 = Document::create();
+ EXPECT_EQ(0, document1->commonAncestorTreeScope(*document2));
+ EXPECT_EQ(0, document2->commonAncestorTreeScope(*document1));
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeShared.h b/chromium/third_party/WebKit/Source/core/dom/TreeShared.h
index 8637dc631d0..1f22797aa42 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeShared.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeShared.h
@@ -21,6 +21,7 @@
#ifndef TreeShared_h
#define TreeShared_h
+#include "public/platform/WebPrivatePtr.h"
#include "wtf/Assertions.h"
#include "wtf/MainThread.h"
#include "wtf/Noncopyable.h"
@@ -32,14 +33,14 @@ template<typename NodeType> class TreeShared;
template<typename NodeType> void adopted(TreeShared<NodeType>*);
#endif
-template<typename NodeType> class TreeShared {
+template<typename NodeType> class TreeShared : public NoBaseWillBeGarbageCollectedFinalized<NodeType> {
WTF_MAKE_NONCOPYABLE(TreeShared);
protected:
TreeShared()
: m_refCount(1)
#if SECURITY_ASSERT_ENABLED
, m_deletionHasBegun(false)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_inRemovedLastRefFunction(false)
, m_adoptionIsRequired(true)
#endif
@@ -69,23 +70,20 @@ public:
void deref()
{
ASSERT(isMainThread());
- ASSERT(m_refCount >= 0);
+ ASSERT(m_refCount > 0);
ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
ASSERT(!m_inRemovedLastRefFunction);
ASSERT(!m_adoptionIsRequired);
NodeType* thisNode = static_cast<NodeType*>(this);
- if (--m_refCount <= 0 && !thisNode->hasTreeSharedParent()) {
-#if !ASSERT_DISABLED
+ if (!--m_refCount && !thisNode->hasTreeSharedParent()) {
+#if ASSERT_ENABLED
m_inRemovedLastRefFunction = true;
#endif
thisNode->removedLastRef();
}
}
- int refCount() const
- {
- return m_refCount;
- }
+ int refCount() const { return m_refCount; }
private:
int m_refCount;
@@ -93,7 +91,7 @@ private:
#if SECURITY_ASSERT_ENABLED
public:
bool m_deletionHasBegun;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool m_inRemovedLastRefFunction;
private:
@@ -108,8 +106,9 @@ template<typename NodeType> inline void adopted(TreeShared<NodeType>* object)
{
if (!object)
return;
+
ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun);
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
ASSERT(!object->m_inRemovedLastRefFunction);
object->m_adoptionIsRequired = false;
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp
index fa099813850..dfa29d55e4d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp
@@ -25,45 +25,45 @@
#include "config.h"
#include "core/dom/TreeWalker.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptState.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
namespace WebCore {
-TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
- : Traversal(rootNode, whatToShow, filter)
+TreeWalker::TreeWalker(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
+ : NodeIteratorBase(rootNode, whatToShow, filter)
, m_current(root())
{
ScriptWrappable::init(this);
}
-void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionState& exceptionState)
+void TreeWalker::setCurrentNode(PassRefPtrWillBeRawPtr<Node> node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwDOMException(NotSupportedError, "The Node provided is invalid.");
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return;
}
m_current = node;
}
-inline Node* TreeWalker::setCurrent(PassRefPtr<Node> node)
+inline Node* TreeWalker::setCurrent(PassRefPtrWillBeRawPtr<Node> node)
{
m_current = node;
return m_current.get();
}
-Node* TreeWalker::parentNode(ScriptState* state)
+Node* TreeWalker::parentNode(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
while (node != root()) {
node = node->parentNode();
if (!node)
return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -71,11 +71,11 @@ Node* TreeWalker::parentNode(ScriptState* state)
return 0;
}
-Node* TreeWalker::firstChild(ScriptState* state)
+Node* TreeWalker::firstChild(ExceptionState& exceptionState)
{
- for (RefPtr<Node> node = m_current->firstChild(); node; ) {
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> node = m_current->firstChild(); node; ) {
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -104,11 +104,11 @@ Node* TreeWalker::firstChild(ScriptState* state)
return 0;
}
-Node* TreeWalker::lastChild(ScriptState* state)
+Node* TreeWalker::lastChild(ExceptionState& exceptionState)
{
- for (RefPtr<Node> node = m_current->lastChild(); node; ) {
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> node = m_current->lastChild(); node; ) {
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -137,15 +137,15 @@ Node* TreeWalker::lastChild(ScriptState* state)
return 0;
}
-Node* TreeWalker::previousSibling(ScriptState* state)
+Node* TreeWalker::previousSibling(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
if (node == root())
return 0;
while (1) {
- for (RefPtr<Node> sibling = node->previousSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(state, sibling.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> sibling = node->previousSibling(); sibling; ) {
+ short acceptNodeResult = acceptNode(sibling.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -166,23 +166,23 @@ Node* TreeWalker::previousSibling(ScriptState* state)
node = node->parentNode();
if (!node || node == root())
return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return 0;
}
}
-Node* TreeWalker::nextSibling(ScriptState* state)
+Node* TreeWalker::nextSibling(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
if (node == root())
return 0;
while (1) {
- for (RefPtr<Node> sibling = node->nextSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(state, sibling.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> sibling = node->nextSibling(); sibling; ) {
+ short acceptNodeResult = acceptNode(sibling.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -203,29 +203,29 @@ Node* TreeWalker::nextSibling(ScriptState* state)
node = node->parentNode();
if (!node || node == root())
return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return 0;
}
}
-Node* TreeWalker::previousNode(ScriptState* state)
+Node* TreeWalker::previousNode(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
while (node != root()) {
while (Node* previousSibling = node->previousSibling()) {
node = previousSibling;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
continue;
while (Node* lastChild = node->lastChild()) {
node = lastChild;
- acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
break;
@@ -241,8 +241,8 @@ Node* TreeWalker::previousNode(ScriptState* state)
if (!parent)
return 0;
node = parent;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -250,14 +250,14 @@ Node* TreeWalker::previousNode(ScriptState* state)
return 0;
}
-Node* TreeWalker::nextNode(ScriptState* state)
+Node* TreeWalker::nextNode(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
Children:
while (Node* firstChild = node->firstChild()) {
node = firstChild;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -266,8 +266,8 @@ Children:
}
while (Node* nextSibling = NodeTraversal::nextSkippingChildren(*node, root())) {
node = nextSibling;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -277,4 +277,10 @@ Children:
return 0;
}
+void TreeWalker::trace(Visitor* visitor)
+{
+ visitor->trace(m_current);
+ NodeIteratorBase::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h
index 354e449289a..2980a0fce2d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h
@@ -27,7 +27,8 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/NodeFilter.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -35,30 +36,33 @@ namespace WebCore {
class ExceptionState;
-class TreeWalker : public ScriptWrappable, public RefCounted<TreeWalker>, public Traversal {
+class TreeWalker FINAL : public RefCountedWillBeGarbageCollectedFinalized<TreeWalker>, public ScriptWrappable, public NodeIteratorBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TreeWalker);
public:
- static PassRefPtr<TreeWalker> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
+ static PassRefPtrWillBeRawPtr<TreeWalker> create(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
{
- return adoptRef(new TreeWalker(rootNode, whatToShow, filter));
+ return adoptRefWillBeNoop(new TreeWalker(rootNode, whatToShow, filter));
}
Node* currentNode() const { return m_current.get(); }
- void setCurrentNode(PassRefPtr<Node>, ExceptionState&);
+ void setCurrentNode(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
- Node* parentNode(ScriptState*);
- Node* firstChild(ScriptState*);
- Node* lastChild(ScriptState*);
- Node* previousSibling(ScriptState*);
- Node* nextSibling(ScriptState*);
- Node* previousNode(ScriptState*);
- Node* nextNode(ScriptState*);
+ Node* parentNode(ExceptionState&);
+ Node* firstChild(ExceptionState&);
+ Node* lastChild(ExceptionState&);
+ Node* previousSibling(ExceptionState&);
+ Node* nextSibling(ExceptionState&);
+ Node* previousNode(ExceptionState&);
+ Node* nextNode(ExceptionState&);
+
+ void trace(Visitor*);
private:
- TreeWalker(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
+ TreeWalker(PassRefPtrWillBeRawPtr<Node>, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>);
- Node* setCurrent(PassRefPtr<Node>);
+ Node* setCurrent(PassRefPtrWillBeRawPtr<Node>);
- RefPtr<Node> m_current;
+ RefPtrWillBeMember<Node> m_current;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl
index 6a92eb0a168..2fb6eb58a91 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl
@@ -18,22 +18,22 @@
* Boston, MA 02110-1301, USA.
*/
-// Introduced in DOM Level 2:
+// Introduced in DOM Level 2
[
- SetReference(NodeFilter filter)
+ SetWrapperReferenceTo(NodeFilter filter),
+ WillBeGarbageCollected,
] interface TreeWalker {
readonly attribute Node root;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter filter;
- readonly attribute boolean expandEntityReferences;
+ [DeprecateAs=TreeWalkerExpandEntityReferences] readonly attribute boolean expandEntityReferences;
[RaisesException=Setter] attribute Node currentNode;
- [CallWith=ScriptState] Node parentNode();
- [CallWith=ScriptState] Node firstChild();
- [CallWith=ScriptState] Node lastChild();
- [CallWith=ScriptState] Node previousSibling();
- [CallWith=ScriptState] Node nextSibling();
- [CallWith=ScriptState] Node previousNode();
- [CallWith=ScriptState] Node nextNode();
+ [RaisesException] Node parentNode();
+ [RaisesException] Node firstChild();
+ [RaisesException] Node lastChild();
+ [RaisesException] Node previousSibling();
+ [RaisesException] Node nextSibling();
+ [RaisesException] Node previousNode();
+ [RaisesException] Node nextNode();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/URL.idl b/chromium/third_party/WebKit/Source/core/dom/URL.idl
index 30c96c69db2..37b80510f3c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/URL.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/URL.idl
@@ -24,17 +24,22 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://url.spec.whatwg.org/#url
+
[
- GlobalContext=Window&WorkerGlobalScope,
- RaisesException=Constructor,
Constructor(DOMString url),
- Constructor(DOMString url, URL base),
Constructor(DOMString url, DOMString base),
- ImplementedAs=DOMURL
+ Constructor(DOMString url, URL base),
+ Exposed=Window&Worker,
+ ImplementedAs=DOMURL,
+ RaisesException=Constructor,
+ WillBeGarbageCollected,
] interface URL {
- [CallWith=ExecutionContext,TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
+ // FIXME: should be in separate URLBlob.idl partial interface definition
+ // http://dev.w3.org/2006/webapi/FileAPI/#URL-object
+ // FIXME: should not be nullable
+ [RaisesException, CallWith=ExecutionContext, TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
[CallWith=ExecutionContext] static void revokeObjectURL(DOMString url);
};
-// force rebuild: crbug.com/307023
URL implements URLUtils;
diff --git a/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl b/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl
index 9cb7b488597..26ed382acf8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl
@@ -23,15 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://url.spec.whatwg.org/#urlutils
+
[
- NoInterfaceObject,
- ImplementedAs=DOMURLUtils
+ NoInterfaceObject, // Always used on target of 'implements'
] interface URLUtils {
- attribute DOMString href;
-
+ // FIXME: should be stringifier: http://crbug.com/306606
+ // stringifier attribute DOMString href;
+ [PerWorldBindings, LogActivity=SetterOnly, LogPreviousValue] attribute DOMString href;
[NotEnumerable, ImplementedAs=href] DOMString toString();
-
readonly attribute DOMString origin;
+
attribute DOMString protocol;
attribute DOMString username;
attribute DOMString password;
@@ -40,10 +42,7 @@
attribute DOMString port;
attribute DOMString pathname;
attribute DOMString search;
-
// Not yet implemented.
- // attribute URLQuery? query;
-
+ // attribute URLSearchParams searchParams;
attribute DOMString hash;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl b/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl
index 0d36b46d0af..ccd26f77053 100644
--- a/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl
@@ -23,13 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://url.spec.whatwg.org/#urlutilsreadonly
+
[
- NoInterfaceObject,
- ImplementedAs=DOMURLUtilsReadOnly
+ NoInterfaceObject, // Always used on target of 'implements'
] interface URLUtilsReadOnly {
+ // FIXME: should be stringifier: http://crbug.com/306606
+ // stringifier readonly attribute DOMString href;
readonly attribute DOMString href;
-
[NotEnumerable, ImplementedAs=href] DOMString toString();
+ // Not yet implemented.
+ // readonly attribute DOMString origin;
readonly attribute DOMString protocol;
readonly attribute DOMString host;
diff --git a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp
index 264061fd539..e59d1fa6003 100644
--- a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp
@@ -46,10 +46,12 @@ void UserActionElementSet::didDetach(Node* node)
clearFlags(toElement(node), IsActiveFlag | InActiveChainFlag | IsHoveredFlag);
}
+#if !ENABLE(OILPAN)
void UserActionElementSet::documentDidRemoveLastRef()
{
m_elements.clear();
}
+#endif
bool UserActionElementSet::hasFlags(const Node* node, unsigned flags) const
{
@@ -116,4 +118,9 @@ inline void UserActionElementSet::setFlags(Element* element, unsigned flags)
m_elements.add(element, flags);
}
+void UserActionElementSet::trace(Visitor* visitor)
+{
+ visitor->trace(m_elements);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h
index 9883262c04f..e060ef00c36 100644
--- a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h
+++ b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h
@@ -27,6 +27,7 @@
#ifndef UserActionElementSet_h
#define UserActionElementSet_h
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
@@ -36,10 +37,9 @@ namespace WebCore {
class Node;
class Element;
-class UserActionElementSet {
+class UserActionElementSet FINAL {
+ DISALLOW_ALLOCATION();
public:
- static PassOwnPtr<UserActionElementSet> create() { return adoptPtr(new UserActionElementSet()); }
-
bool isFocused(const Node* node) { return hasFlags(node, IsFocusedFlag); }
bool isActive(const Node* node) { return hasFlags(node, IsActiveFlag); }
bool isInActiveChain(const Node* node) { return hasFlags(node, InActiveChainFlag); }
@@ -53,7 +53,12 @@ public:
~UserActionElementSet();
void didDetach(Node*);
+
+#if !ENABLE(OILPAN)
void documentDidRemoveLastRef();
+#endif
+
+ void trace(Visitor*);
private:
enum ElementFlags {
@@ -72,7 +77,7 @@ private:
void clearFlags(Element*, unsigned);
bool hasFlags(const Element*, unsigned flags) const;
- typedef HashMap<RefPtr<Element>, unsigned> ElementFlagMap;
+ typedef WillBeHeapHashMap<RefPtrWillBeMember<Element>, unsigned> ElementFlagMap;
ElementFlagMap m_elements;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
index 77f924e623b..f6c88184eca 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
@@ -28,7 +28,13 @@
#include "config.h"
#include "core/dom/ViewportDescription.h"
-using namespace std;
+#include "core/dom/Document.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "platform/weborigin/KURL.h"
+#include "public/platform/Platform.h"
namespace WebCore {
@@ -54,27 +60,45 @@ float ViewportDescription::resolveViewportLength(const Length& length, const Flo
if (length.type() == ExtendToZoom)
return ViewportDescription::ValueExtendToZoom;
- if ((length.type() == Percent && direction == Horizontal) || length.type() == ViewportPercentageWidth)
+ if (length.type() == Percent && direction == Horizontal)
return initialViewportSize.width() * length.getFloatValue() / 100.0f;
- if ((length.type() == Percent && direction == Vertical) || length.type() == ViewportPercentageHeight)
+ if (length.type() == Percent && direction == Vertical)
return initialViewportSize.height() * length.getFloatValue() / 100.0f;
- if (length.type() == ViewportPercentageMin)
- return min(initialViewportSize.width(), initialViewportSize.height()) * length.viewportPercentageLength() / 100.0f;
+ if (length.type() == DeviceWidth)
+ return initialViewportSize.width();
- if (length.type() == ViewportPercentageMax)
- return max(initialViewportSize.width(), initialViewportSize.height()) * length.viewportPercentageLength() / 100.0f;
+ if (length.type() == DeviceHeight)
+ return initialViewportSize.height();
ASSERT_NOT_REACHED();
return ViewportDescription::ValueAuto;
}
-PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewportSize) const
+PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewportSize, Length legacyFallbackWidth) const
{
float resultWidth = ValueAuto;
- float resultMaxWidth = resolveViewportLength(maxWidth, initialViewportSize, Horizontal);
- float resultMinWidth = resolveViewportLength(minWidth, initialViewportSize, Horizontal);
+
+ Length copyMaxWidth = maxWidth;
+ Length copyMinWidth = minWidth;
+ // In case the width (used for min- and max-width) is undefined.
+ if (isLegacyViewportType() && maxWidth.isAuto()) {
+ // The width viewport META property is translated into 'width' descriptors, setting
+ // the 'min' value to 'extend-to-zoom' and the 'max' value to the intended length.
+ // In case the UA-defines a min-width, use that as length.
+ if (zoom == ViewportDescription::ValueAuto) {
+ copyMinWidth = Length(ExtendToZoom);
+ copyMaxWidth = legacyFallbackWidth;
+ } else if (maxHeight.isAuto()) {
+ copyMinWidth = Length(ExtendToZoom);
+ copyMaxWidth = Length(ExtendToZoom);
+ }
+ }
+
+ float resultMaxWidth = resolveViewportLength(copyMaxWidth, initialViewportSize, Horizontal);
+ float resultMinWidth = resolveViewportLength(copyMinWidth, initialViewportSize, Horizontal);
+
float resultHeight = ValueAuto;
float resultMaxHeight = resolveViewportLength(maxHeight, initialViewportSize, Vertical);
float resultMinHeight = resolveViewportLength(minHeight, initialViewportSize, Vertical);
@@ -82,17 +106,17 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
float resultZoom = zoom;
float resultMinZoom = minZoom;
float resultMaxZoom = maxZoom;
- float resultUserZoom = userZoom;
+ bool resultUserZoom = userZoom;
// 1. Resolve min-zoom and max-zoom values.
if (resultMinZoom != ViewportDescription::ValueAuto && resultMaxZoom != ViewportDescription::ValueAuto)
- resultMaxZoom = max(resultMinZoom, resultMaxZoom);
+ resultMaxZoom = std::max(resultMinZoom, resultMaxZoom);
// 2. Constrain zoom value to the [min-zoom, max-zoom] range.
if (resultZoom != ViewportDescription::ValueAuto)
- resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max);
+ resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, std::min), std::max);
- float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, min);
+ float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, std::min);
// 3. Resolve non-"auto" lengths to pixel lengths.
if (extendZoom == ViewportDescription::ValueAuto) {
@@ -118,19 +142,19 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
resultMaxHeight = extendHeight;
if (resultMinWidth == ViewportDescription::ValueExtendToZoom)
- resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, max);
+ resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, std::max);
if (resultMinHeight == ViewportDescription::ValueExtendToZoom)
- resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, max);
+ resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, std::max);
}
// 4. Resolve initial width from min/max descriptors.
if (resultMinWidth != ViewportDescription::ValueAuto || resultMaxWidth != ViewportDescription::ValueAuto)
- resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max);
+ resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), std::min), std::max);
// 5. Resolve initial height from min/max descriptors.
if (resultMinHeight != ViewportDescription::ValueAuto || resultMaxHeight != ViewportDescription::ValueAuto)
- resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max);
+ resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), std::min), std::max);
// 6-7. Resolve width value.
if (resultWidth == ViewportDescription::ValueAuto) {
@@ -154,7 +178,7 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
resultZoom = initialViewportSize.width() / resultWidth;
if (resultHeight != ViewportDescription::ValueAuto && resultHeight > 0) {
// if 'auto', the initial-scale will be negative here and thus ignored.
- resultZoom = max<float>(resultZoom, initialViewportSize.height() / resultHeight);
+ resultZoom = std::max<float>(resultZoom, initialViewportSize.height() / resultHeight);
}
}
@@ -176,4 +200,63 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
return result;
}
+void ViewportDescription::reportMobilePageStats(const LocalFrame* mainFrame) const
+{
+#if OS(ANDROID)
+ enum ViewportUMAType {
+ NoViewportTag,
+ DeviceWidth,
+ ConstantWidth,
+ MetaWidthOther,
+ MetaHandheldFriendly,
+ MetaMobileOptimized,
+ XhtmlMobileProfile,
+ TypeCount
+ };
+
+ if (!mainFrame || !mainFrame->host() || !mainFrame->view() || !mainFrame->document())
+ return;
+
+ // Avoid chrome:// pages like the new-tab page (on Android new tab is non-http).
+ if (!mainFrame->document()->url().protocolIsInHTTPFamily())
+ return;
+
+ if (!isSpecifiedByAuthor()) {
+ if (mainFrame->document()->isMobileDocument())
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", XhtmlMobileProfile, TypeCount);
+ else
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", NoViewportTag, TypeCount);
+
+ return;
+ }
+
+ if (isMetaViewportType()) {
+ if (maxWidth.type() == WebCore::Fixed) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", ConstantWidth, TypeCount);
+
+ if (mainFrame->view()) {
+ // To get an idea of how "far" the viewport is from the device's ideal width, we
+ // report the zoom level that we'd need to be at for the entire page to be visible.
+ int viewportWidth = maxWidth.intValue();
+ int windowWidth = mainFrame->document()->settings()->pinchVirtualViewportEnabled()
+ ? mainFrame->host()->pinchViewport().size().width()
+ : mainFrame->view()->frameRect().width();
+ int overviewZoomPercent = 100 * windowWidth / static_cast<float>(viewportWidth);
+ blink::Platform::current()->histogramSparse("Viewport.OverviewZoom", overviewZoomPercent);
+ }
+
+ } else if (maxWidth.type() == WebCore::DeviceWidth || maxWidth.type() == WebCore::ExtendToZoom) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", DeviceWidth, TypeCount);
+ } else {
+ // Overflow bucket for cases we may be unaware of.
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", MetaWidthOther, TypeCount);
+ }
+ } else if (type == ViewportDescription::HandheldFriendlyMeta) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", MetaHandheldFriendly, TypeCount);
+ } else if (type == ViewportDescription::MobileOptimizedMeta) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", MobileOptimizedMeta, TypeCount);
+ }
+#endif
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h
index 53eed2688f5..c5e22de890b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h
@@ -34,6 +34,9 @@
namespace WebCore {
+class KURL;
+class LocalFrame;
+
struct ViewportDescription {
enum Type {
@@ -63,14 +66,18 @@ struct ViewportDescription {
, zoom(ValueAuto)
, minZoom(ValueAuto)
, maxZoom(ValueAuto)
- , userZoom(ValueAuto)
+ , userZoom(true)
, orientation(ValueAuto)
, deprecatedTargetDensityDPI(ValueAuto)
+ , zoomIsExplicit(false)
+ , minZoomIsExplicit(false)
+ , maxZoomIsExplicit(false)
+ , userZoomIsExplicit(false)
{
}
// All arguments are in CSS units.
- PageScaleConstraints resolve(const FloatSize& initialViewportSize) const;
+ PageScaleConstraints resolve(const FloatSize& initialViewportSize, Length legacyFallbackWidth) const;
Length minWidth;
Length maxWidth;
@@ -79,10 +86,17 @@ struct ViewportDescription {
float zoom;
float minZoom;
float maxZoom;
- float userZoom;
+ bool userZoom;
float orientation;
float deprecatedTargetDensityDPI; // Only used for Android WebView
+ // Whether the computed value was explicitly specified rather than being
+ // inferred.
+ bool zoomIsExplicit;
+ bool minZoomIsExplicit;
+ bool maxZoomIsExplicit;
+ bool userZoomIsExplicit;
+
bool operator==(const ViewportDescription& other) const
{
// Used for figuring out whether to reset the viewport or not,
@@ -96,7 +110,11 @@ struct ViewportDescription {
&& maxZoom == other.maxZoom
&& userZoom == other.userZoom
&& orientation == other.orientation
- && deprecatedTargetDensityDPI == other.deprecatedTargetDensityDPI;
+ && deprecatedTargetDensityDPI == other.deprecatedTargetDensityDPI
+ && zoomIsExplicit == other.zoomIsExplicit
+ && minZoomIsExplicit == other.minZoomIsExplicit
+ && maxZoomIsExplicit == other.maxZoomIsExplicit
+ && userZoomIsExplicit == other.userZoomIsExplicit;
}
bool operator!=(const ViewportDescription& other) const
@@ -108,6 +126,10 @@ struct ViewportDescription {
bool isMetaViewportType() const { return type == ViewportMeta; }
bool isSpecifiedByAuthor() const { return type != UserAgentStyleSheet; }
+ // Reports UMA stat on whether the page is considered mobile or desktop and what kind of
+ // mobile it is. Applies only to Android, must only be called once per page load.
+ void reportMobilePageStats(const LocalFrame*) const;
+
private:
enum Direction { Horizontal, Vertical };
static float resolveViewportLength(const Length&, const FloatSize& initialViewportSize, Direction);
diff --git a/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp b/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp
index f715a3dfeb9..45f74a90fbd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "core/dom/VisitedLinkState.h"
-#include "HTMLNames.h"
-#include "XLinkNames.h"
+#include "core/HTMLNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLAnchorElement.h"
#include "public/platform/Platform.h"
@@ -65,7 +65,7 @@ void VisitedLinkState::invalidateStyleForAllLinks()
return;
for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(*element)) {
if (element->isLink())
- element->setNeedsStyleRecalc();
+ element->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
@@ -75,7 +75,7 @@ void VisitedLinkState::invalidateStyleForLink(LinkHash linkHash)
return;
for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(*element)) {
if (element->isLink() && linkHashForElement(*element) == linkHash)
- element->setNeedsStyleRecalc();
+ element->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp
new file mode 100644
index 00000000000..34296c004b7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp
@@ -0,0 +1,104 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/WeakNodeMap.h"
+
+#include "core/dom/Node.h"
+
+namespace WebCore {
+
+class NodeToWeakNodeMaps {
+public:
+ bool addedToMap(Node*, WeakNodeMap*);
+ bool removedFromMap(Node*, WeakNodeMap*);
+ void nodeDestroyed(Node*);
+
+ static NodeToWeakNodeMaps& instance()
+ {
+ DEFINE_STATIC_LOCAL(NodeToWeakNodeMaps, self, ());
+ return self;
+ }
+
+private:
+ typedef Vector<WeakNodeMap*, 1> MapList;
+ typedef HashMap<Node*, OwnPtr<MapList> > NodeToMapList;
+ NodeToMapList m_nodeToMapList;
+};
+
+bool NodeToWeakNodeMaps::addedToMap(Node* node, WeakNodeMap* map)
+{
+ NodeToMapList::AddResult result = m_nodeToMapList.add(node, nullptr);
+ if (result.isNewEntry)
+ result.storedValue->value = adoptPtr(new MapList());
+ result.storedValue->value->append(map);
+ return result.isNewEntry;
+}
+
+bool NodeToWeakNodeMaps::removedFromMap(Node* node, WeakNodeMap* map)
+{
+ NodeToMapList::iterator it = m_nodeToMapList.find(node);
+ ASSERT(it != m_nodeToMapList.end());
+ MapList* mapList = it->value.get();
+ size_t position = mapList->find(map);
+ ASSERT(position != kNotFound);
+ mapList->remove(position);
+ if (mapList->size() == 0) {
+ m_nodeToMapList.remove(it);
+ return true;
+ }
+ return false;
+}
+
+void NodeToWeakNodeMaps::nodeDestroyed(Node* node)
+{
+ OwnPtr<NodeToWeakNodeMaps::MapList> maps = m_nodeToMapList.take(node);
+ for (size_t i = 0; i < maps->size(); i++)
+ (*maps)[i]->nodeDestroyed(node);
+}
+
+WeakNodeMap::~WeakNodeMap()
+{
+ NodeToWeakNodeMaps& allMaps = NodeToWeakNodeMaps::instance();
+ for (NodeToValue::iterator it = m_nodeToValue.begin(); it != m_nodeToValue.end(); ++it) {
+ Node* node = it->key;
+ if (allMaps.removedFromMap(node, this))
+ node->clearFlag(Node::HasWeakReferencesFlag);
+ }
+}
+
+void WeakNodeMap::put(Node* node, int value)
+{
+ ASSERT(!m_nodeToValue.contains(node));
+ m_nodeToValue.set(node, value);
+ m_valueToNode.set(value, node);
+
+ NodeToWeakNodeMaps& maps = NodeToWeakNodeMaps::instance();
+ if (maps.addedToMap(node, this))
+ node->setFlag(Node::HasWeakReferencesFlag);
+}
+
+int WeakNodeMap::value(Node* node)
+{
+ return m_nodeToValue.get(node);
+}
+
+Node* WeakNodeMap::node(int value)
+{
+ return m_valueToNode.get(value);
+}
+
+void WeakNodeMap::nodeDestroyed(Node* node)
+{
+ int value = m_nodeToValue.take(node);
+ ASSERT(value);
+ m_valueToNode.remove(value);
+}
+
+void WeakNodeMap::notifyNodeDestroyed(Node* node)
+{
+ NodeToWeakNodeMaps::instance().nodeDestroyed(node);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h
new file mode 100644
index 00000000000..44cdf59fb47
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WeakNodeMap_h
+#define WeakNodeMap_h
+
+#include "wtf/HashMap.h"
+
+namespace WebCore {
+
+class Node;
+class NodeToWeakNodeMaps;
+
+class WeakNodeMap {
+public:
+ ~WeakNodeMap();
+
+ void put(Node*, int value);
+ int value(Node*);
+ Node* node(int value);
+
+private:
+ // FIXME: This should not be friends with Node, we should expose a proper API and not
+ // let the map directly set flags.
+ friend class Node;
+ static void notifyNodeDestroyed(Node*);
+
+ friend class NodeToWeakNodeMaps;
+ void nodeDestroyed(Node*);
+
+ typedef HashMap<Node*, int> NodeToValue;
+ NodeToValue m_nodeToValue;
+ typedef HashMap<int, Node*> ValueToNode;
+ ValueToNode m_valueToNode;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl b/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl
deleted file mode 100644
index 800e26d9b08..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- GenerateVisitDOMWrapper=ownerNode,
- ImplementedAs=NamedFlow,
- NoInterfaceObject,
- RuntimeEnabled=CSSRegions,
-] interface WebKitNamedFlow : EventTarget {
- readonly attribute DOMString name;
- readonly attribute boolean overset;
- readonly attribute long firstEmptyRegionIndex;
- NodeList getRegionsByContent(Node contentNode);
- NodeList getRegions();
- NodeList getContent();
-};
diff --git a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl b/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl
deleted file mode 100644
index 4744e069746..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- RuntimeEnabled=CSSRegions,
- ImplementedAs=DOMNamedFlowCollection
-] interface WebKitNamedFlowCollection {
- readonly attribute unsigned long length;
- getter WebKitNamedFlow item(unsigned long index);
- WebKitNamedFlow namedItem(DOMString name);
- [NotEnumerable, ImplementedAs=namedItem] getter WebKitNamedFlow (DOMString name);
-};
diff --git a/chromium/third_party/WebKit/Source/core/dom/WheelController.cpp b/chromium/third_party/WebKit/Source/core/dom/WheelController.cpp
deleted file mode 100644
index 68d5b18b2e5..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WheelController.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/WheelController.h"
-
-#include "core/dom/Document.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/WheelEvent.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-
-namespace WebCore {
-
-WheelController::WheelController(Document* document)
- : DOMWindowLifecycleObserver(document->domWindow())
- , m_wheelEventHandlerCount(0)
-{
-}
-
-WheelController::~WheelController()
-{
-}
-
-const char* WheelController::supplementName()
-{
- return "WheelController";
-}
-
-WheelController* WheelController::from(Document* document)
-{
- WheelController* controller = static_cast<WheelController*>(DocumentSupplement::from(document, supplementName()));
- if (!controller) {
- controller = new WheelController(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(controller));
- }
- return controller;
-}
-
-static void wheelEventHandlerCountChanged(Document* document)
-{
- Page* page = document->page();
- if (!page)
- return;
-
- ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
- if (!scrollingCoordinator)
- return;
-
- FrameView* frameView = document->view();
- if (!frameView)
- return;
-
- scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
-}
-
-void WheelController::didAddWheelEventHandler(Document* document)
-{
- ++m_wheelEventHandlerCount;
- Page* page = document->page();
- Frame* mainFrame = page ? page->mainFrame() : 0;
- if (mainFrame)
- mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
-
- wheelEventHandlerCountChanged(document);
-}
-
-void WheelController::didRemoveWheelEventHandler(Document* document)
-{
- ASSERT(m_wheelEventHandlerCount > 0);
- --m_wheelEventHandlerCount;
- Page* page = document->page();
- Frame* mainFrame = page ? page->mainFrame() : 0;
- if (mainFrame)
- mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
-
- wheelEventHandlerCountChanged(document);
-}
-
-void WheelController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (eventType != EventTypeNames::wheel && eventType != EventTypeNames::mousewheel)
- return;
-
- Document* document = window->document();
- didAddWheelEventHandler(document);
-}
-
-void WheelController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (eventType != EventTypeNames::wheel && eventType != EventTypeNames::mousewheel)
- return;
-
- Document* document = window->document();
- didRemoveWheelEventHandler(document);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClipboardAccessPolicy.h b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp
index 969b3f66e95..ed0d55c5530 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClipboardAccessPolicy.h
+++ b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp
@@ -1,19 +1,19 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
+ * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
+ * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,15 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ClipboardAccessPolicy_h
-#define ClipboardAccessPolicy_h
+#include "config.h"
+#include "core/dom/XMLDocument.h"
namespace WebCore {
-enum ClipboardAccessPolicy {
- ClipboardNumb, ClipboardImageWritable, ClipboardWritable, ClipboardTypesReadable, ClipboardReadable
-};
+XMLDocument::XMLDocument(const DocumentInit& initializer, DocumentClassFlags documentClasses)
+ : Document(initializer, documentClasses)
+{
+ ScriptWrappable::init(this);
+}
-} // namespace
-
-#endif
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/WheelController.h b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.h
index 550cb09a3c0..b1843440fa5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/WheelController.h
+++ b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,41 +23,37 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WheelController_h
-#define WheelController_h
-
-#include "core/dom/DocumentSupplementable.h"
-#include "core/events/Event.h"
-#include "core/frame/DOMWindowLifecycleObserver.h"
+#ifndef XMLDocument_h
+#define XMLDocument_h
+#include "core/dom/Document.h"
+#include "wtf/PassRefPtr.h"
namespace WebCore {
-class DOMWindow;
-
-class WheelController : public DocumentSupplement, public DOMWindowLifecycleObserver {
-
+class XMLDocument FINAL : public Document {
public:
- virtual ~WheelController();
-
- static const char* supplementName();
- static WheelController* from(Document*);
-
- unsigned wheelEventHandlerCount() { return m_wheelEventHandlerCount; }
-
- void didAddWheelEventHandler(Document*);
- void didRemoveWheelEventHandler(Document*);
-
- // Inherited from DOMWindowLifecycleObserver
- virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
- virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
-
-private:
- explicit WheelController(Document*);
-
- unsigned m_wheelEventHandlerCount;
+ static PassRefPtrWillBeRawPtr<XMLDocument> create(const DocumentInit& initializer = DocumentInit())
+ {
+ return adoptRefWillBeNoop(new XMLDocument(initializer, XMLDocumentClass));
+ }
+
+ static PassRefPtrWillBeRawPtr<XMLDocument> createXHTML(const DocumentInit& initializer = DocumentInit())
+ {
+ return adoptRefWillBeNoop(new XMLDocument(initializer, XMLDocumentClass | XHTMLDocumentClass));
+ }
+
+ static PassRefPtrWillBeRawPtr<XMLDocument> createSVG(const DocumentInit& initializer = DocumentInit())
+ {
+ return adoptRefWillBeNoop(new XMLDocument(initializer, XMLDocumentClass | SVGDocumentClass));
+ }
+
+protected:
+ XMLDocument(const DocumentInit&, DocumentClassFlags documentClasses);
};
+DEFINE_DOCUMENT_TYPE_CASTS(XMLDocument);
+
} // namespace WebCore
-#endif // WheelController_h
+#endif // XMLDocument_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl
new file mode 100644
index 00000000000..a41fb18aad2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface XMLDocument : Document {
+};
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
index 0dc1683ca39..46f8b533a84 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
@@ -31,16 +31,21 @@
#include "config.h"
#include "core/dom/custom/CustomElement.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
#include "core/dom/custom/CustomElementObserver.h"
+#include "core/dom/custom/CustomElementScheduler.h"
namespace WebCore {
+CustomElementMicrotaskImportStep* CustomElement::didCreateImport(HTMLImportChild* import)
+{
+ return CustomElementScheduler::scheduleImport(import);
+}
+
Vector<AtomicString>& CustomElement::embedderCustomElementNames()
{
DEFINE_STATIC_LOCAL(Vector<AtomicString>, names, ());
@@ -55,15 +60,8 @@ void CustomElement::addEmbedderCustomElementName(const AtomicString& name)
embedderCustomElementNames().append(lower);
}
-static CustomElement::NameSet enabledNameSet()
-{
- return CustomElement::NameSet((RuntimeEnabledFeatures::customElementsEnabled() ? CustomElement::StandardNames : 0) | (RuntimeEnabledFeatures::embedderCustomElementsEnabled() ? CustomElement::EmbedderNames : 0));
-}
-
bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
{
- validNames = NameSet(validNames & enabledNameSet());
-
if ((validNames & EmbedderNames) && kNotFound != embedderCustomElementNames().find(name))
return Document::isValidName(name);
@@ -71,15 +69,14 @@ bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
if (reservedNames.isEmpty()) {
reservedNames.append(MathMLNames::annotation_xmlTag.localName());
- // In principle, "color-profile" should exist in the SVGNames
- // namespace, but we don't implement the color-profile element.
- reservedNames.append("color-profile");
+#if ENABLE(SVG_FONTS)
reservedNames.append(SVGNames::font_faceTag.localName());
reservedNames.append(SVGNames::font_face_srcTag.localName());
reservedNames.append(SVGNames::font_face_uriTag.localName());
reservedNames.append(SVGNames::font_face_formatTag.localName());
reservedNames.append(SVGNames::font_face_nameTag.localName());
reservedNames.append(SVGNames::missing_glyphTag.localName());
+#endif
}
if (kNotFound == reservedNames.find(name))
@@ -100,23 +97,16 @@ void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition>
break;
case Element::WaitingForUpgrade:
- definitions().add(element, definition);
- CustomElementCallbackScheduler::scheduleCreatedCallback(definition->callbacks(), element);
+ element->setCustomElementDefinition(definition);
+ CustomElementScheduler::scheduleCallback(definition->callbacks(), element, CustomElementLifecycleCallbacks::Created);
break;
}
}
-CustomElementDefinition* CustomElement::definitionFor(Element* element)
-{
- CustomElementDefinition* definition = definitions().get(element);
- ASSERT(definition);
- return definition;
-}
-
void CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
{
ASSERT(element->customElementState() == Element::Upgraded);
- CustomElementCallbackScheduler::scheduleAttributeChangedCallback(definitionFor(element)->callbacks(), element, name, oldValue, newValue);
+ CustomElementScheduler::scheduleAttributeChangedCallback(element->customElementDefinition()->callbacks(), element, name, oldValue, newValue);
}
void CustomElement::didEnterDocument(Element* element, const Document& document)
@@ -124,7 +114,7 @@ void CustomElement::didEnterDocument(Element* element, const Document& document)
ASSERT(element->customElementState() == Element::Upgraded);
if (!document.domWindow())
return;
- CustomElementCallbackScheduler::scheduleAttachedCallback(definitionFor(element)->callbacks(), element);
+ CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::Attached);
}
void CustomElement::didLeaveDocument(Element* element, const Document& document)
@@ -132,7 +122,7 @@ void CustomElement::didLeaveDocument(Element* element, const Document& document)
ASSERT(element->customElementState() == Element::Upgraded);
if (!document.domWindow())
return;
- CustomElementCallbackScheduler::scheduleDetachedCallback(definitionFor(element)->callbacks(), element);
+ CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::Detached);
}
void CustomElement::wasDestroyed(Element* element)
@@ -144,23 +134,9 @@ void CustomElement::wasDestroyed(Element* element)
case Element::WaitingForUpgrade:
case Element::Upgraded:
- definitions().remove(element);
CustomElementObserver::notifyElementWasDestroyed(element);
break;
}
}
-void CustomElement::DefinitionMap::add(Element* element, PassRefPtr<CustomElementDefinition> definition)
-{
- ASSERT(definition.get());
- DefinitionMap::ElementDefinitionHashMap::AddResult result = m_definitions.add(element, definition);
- ASSERT_UNUSED(result, result.isNewEntry);
-}
-
-CustomElement::DefinitionMap& CustomElement::definitions()
-{
- DEFINE_STATIC_LOCAL(DefinitionMap, map, ());
- return map;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h
index c50bc0804e4..c9504eb7863 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h
@@ -41,8 +41,10 @@
namespace WebCore {
+class CustomElementMicrotaskImportStep;
class Document;
class Element;
+class HTMLImportChild;
class CustomElement {
public:
@@ -54,15 +56,14 @@ public:
static bool isValidName(const AtomicString& name, NameSet validNames = AllNames);
static void addEmbedderCustomElementName(const AtomicString& name);
+ // API to notify of document-level changes
+ static CustomElementMicrotaskImportStep* didCreateImport(HTMLImportChild*);
+
// API for registration contexts
static void define(Element*, PassRefPtr<CustomElementDefinition>);
- // API for wrapper creation, which uses a definition as a key
- static CustomElementDefinition* definitionFor(Element*);
-
// API for Element to kick off changes
- static void didFinishParsingChildren(Element*);
static void attributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
static void didEnterDocument(Element*, const Document&);
static void didLeaveDocument(Element*, const Document&);
@@ -72,24 +73,6 @@ private:
CustomElement();
static Vector<AtomicString>& embedderCustomElementNames();
-
- // Maps resolved elements to their definitions
-
- class DefinitionMap {
- WTF_MAKE_NONCOPYABLE(DefinitionMap);
- public:
- DefinitionMap() { }
- ~DefinitionMap() { }
-
- void add(Element*, PassRefPtr<CustomElementDefinition>);
- void remove(Element* element) { m_definitions.remove(element); }
- CustomElementDefinition* get(Element* element) const { return m_definitions.get(element); }
-
- private:
- typedef HashMap<Element*, RefPtr<CustomElementDefinition> > ElementDefinitionHashMap;
- ElementDefinitionHashMap m_definitions;
- };
- static DefinitionMap& definitions();
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp
index b86239671a6..3fcf748a7fb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,47 +29,27 @@
*/
#include "config.h"
-#include "core/dom/PostAttachCallbacks.h"
+#include "core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h"
-#include "core/dom/Node.h"
-#include "wtf/RefPtr.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
namespace WebCore {
-typedef std::pair<PostAttachCallbacks::Callback, RefPtr<Node> > CallbackInfo;
-typedef Vector<CallbackInfo> CallbackQueue;
-
-static size_t s_attachDepth;
-
-static CallbackQueue& callbackQueue()
-{
- DEFINE_STATIC_LOCAL(CallbackQueue, callbackQueue, ());
- return callbackQueue;
-}
-
-void PostAttachCallbacks::queueCallback(Callback callback, Node* node)
+void CustomElementAsyncImportMicrotaskQueue::enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step)
{
- callbackQueue().append(CallbackInfo(callback, node));
+ m_queue.append(step);
}
-PostAttachCallbacks::SuspendScope::SuspendScope()
+void CustomElementAsyncImportMicrotaskQueue::doDispatch()
{
- ++s_attachDepth;
-}
+ WillBeHeapVector<OwnPtrWillBeMember<CustomElementMicrotaskStep> > remaining;
-PostAttachCallbacks::SuspendScope::~SuspendScope()
-{
- if (s_attachDepth == 1) {
- // We recalculate size() each time through the loop because a callback
- // can add more callbacks to the end of the queue.
- CallbackQueue& queue = callbackQueue();
- for (size_t i = 0; i < queue.size(); ++i) {
- const CallbackInfo& info = queue[i];
- info.first(info.second.get());
- }
- queue.clear();
+ for (unsigned i = 0; i < m_queue.size(); ++i) {
+ if (CustomElementMicrotaskStep::Processing == m_queue[i]->process())
+ remaining.append(m_queue[i].release());
}
- --s_attachDepth;
+
+ m_queue.swap(remaining);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h
new file mode 100644
index 00000000000..e3845191020
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementAsyncImportMicrotaskQueue_h
+#define CustomElementAsyncImportMicrotaskQueue_h
+
+#include "core/dom/custom/CustomElementMicrotaskQueueBase.h"
+
+namespace WebCore {
+
+class CustomElementMicrotaskImportStep;
+
+class CustomElementAsyncImportMicrotaskQueue : public CustomElementMicrotaskQueueBase {
+public:
+ static PassRefPtrWillBeRawPtr<CustomElementAsyncImportMicrotaskQueue> create() { return adoptRefWillBeNoop(new CustomElementAsyncImportMicrotaskQueue()); }
+
+ void enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep>);
+
+private:
+ CustomElementAsyncImportMicrotaskQueue() { }
+ virtual void doDispatch() OVERRIDE;
+};
+
+}
+
+#endif // CustomElementAsyncImportMicrotaskQueue_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp
index 450af4ef301..5bd4866a076 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp
@@ -32,7 +32,7 @@
#include "core/dom/custom/CustomElementCallbackDispatcher.h"
#include "core/dom/custom/CustomElementCallbackQueue.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
+#include "core/dom/custom/CustomElementScheduler.h"
#include "wtf/MainThread.h"
namespace WebCore {
@@ -48,17 +48,6 @@ CustomElementCallbackDispatcher& CustomElementCallbackDispatcher::instance()
return instance;
}
-bool CustomElementCallbackDispatcher::dispatch()
-{
- ASSERT(isMainThread());
- if (inCallbackDeliveryScope())
- return false;
-
- bool didWork = m_baseElementQueue.dispatch(baseElementQueue());
- CustomElementCallbackScheduler::clearElementCallbackQueueMap();
- return didWork;
-}
-
// Dispatches callbacks when popping the processing stack.
void CustomElementCallbackDispatcher::processElementQueueAndPop()
{
@@ -68,7 +57,7 @@ void CustomElementCallbackDispatcher::processElementQueueAndPop()
void CustomElementCallbackDispatcher::processElementQueueAndPop(size_t start, size_t end)
{
ASSERT(isMainThread());
- ElementQueue thisQueue = currentElementQueue();
+ CustomElementCallbackQueue::ElementQueueId thisQueue = currentElementQueue();
for (size_t i = start; i < end; i++) {
{
@@ -86,23 +75,21 @@ void CustomElementCallbackDispatcher::processElementQueueAndPop(size_t start, si
m_flattenedProcessingStack.resize(start);
s_elementQueueEnd = start;
- if (start == kNumSentinels && m_baseElementQueue.isEmpty())
- CustomElementCallbackScheduler::clearElementCallbackQueueMap();
+ if (s_elementQueueStart == kNumSentinels)
+ CustomElementScheduler::callbackDispatcherDidFinish();
}
void CustomElementCallbackDispatcher::enqueue(CustomElementCallbackQueue* callbackQueue)
{
+ ASSERT(inCallbackDeliveryScope());
+
if (callbackQueue->owner() == currentElementQueue())
return;
callbackQueue->setOwner(currentElementQueue());
- if (inCallbackDeliveryScope()) {
- m_flattenedProcessingStack.append(callbackQueue);
- ++s_elementQueueEnd;
- } else {
- m_baseElementQueue.enqueue(callbackQueue);
- }
+ m_flattenedProcessingStack.append(callbackQueue);
+ ++s_elementQueueEnd;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h
index 179219110c1..3e505c80600 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h
@@ -31,19 +31,18 @@
#ifndef CustomElementCallbackDispatcher_h
#define CustomElementCallbackDispatcher_h
-#include "core/dom/custom/CustomElementBaseElementQueue.h"
+#include "core/dom/custom/CustomElementCallbackQueue.h"
#include "wtf/Vector.h"
namespace WebCore {
-class CustomElementCallbackQueue;
-class CustomElementCallbackScheduler;
+class CustomElementScheduler;
+// FIXME: Rename this CustomElementProcessingStack. It only handles
+// the processing stack.
class CustomElementCallbackDispatcher {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackDispatcher);
public:
- static CustomElementCallbackDispatcher& instance();
-
// This is stack allocated in many DOM callbacks. Make it cheap.
class CallbackDeliveryScope {
public:
@@ -64,13 +63,11 @@ public:
size_t m_savedElementQueueStart;
};
- // Returns true if more work may have to be performed at the
- // checkpoint by this or other workers (for example, this work
- // invoked author scripts)
- bool dispatch();
+ static bool inCallbackDeliveryScope() { return s_elementQueueStart; }
protected:
- friend class CustomElementCallbackScheduler;
+ friend class CustomElementScheduler;
+ static CustomElementCallbackDispatcher& instance();
void enqueue(CustomElementCallbackQueue*);
private:
@@ -95,20 +92,11 @@ private:
// stack. A cache of instance().m_flattenedProcessingStack.size().
static size_t s_elementQueueEnd;
- static bool inCallbackDeliveryScope() { return s_elementQueueStart; }
-
- typedef int ElementQueue;
- static ElementQueue baseElementQueue() { return ElementQueue(0); }
- static ElementQueue currentElementQueue() { return ElementQueue(s_elementQueueStart); }
+ static CustomElementCallbackQueue::ElementQueueId currentElementQueue() { return CustomElementCallbackQueue::ElementQueueId(s_elementQueueStart); }
static void processElementQueueAndPop();
void processElementQueueAndPop(size_t start, size_t end);
- // The base element queue, used when no CallbackDeliveryScope is
- // active. Callbacks for elements created by the parser are
- // enqueued here.
- CustomElementBaseElementQueue m_baseElementQueue;
-
// The processing stack, flattened. Element queues lower in the
// stack appear toward the head of the vector. The first element
// is a null sentinel value.
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp
index e4fb331b654..a6e6e1b274b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp
@@ -31,30 +31,12 @@
#include "config.h"
#include "core/dom/custom/CustomElementCallbackInvocation.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
+#include "core/dom/custom/CustomElementScheduler.h"
namespace WebCore {
-class CreatedInvocation : public CustomElementCallbackInvocation {
-public:
- CreatedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
- : CustomElementCallbackInvocation(callbacks)
- {
- }
-
-private:
- virtual void dispatch(Element*) OVERRIDE;
- virtual bool isCreated() const OVERRIDE { return true; }
-};
-
-void CreatedInvocation::dispatch(Element* element)
-{
- if (element->inDocument() && element->document().domWindow())
- CustomElementCallbackScheduler::scheduleAttachedCallback(callbacks(), element);
- callbacks()->created(element);
-}
-
class AttachedDetachedInvocation : public CustomElementCallbackInvocation {
public:
AttachedDetachedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which);
@@ -111,6 +93,25 @@ void AttributeChangedInvocation::dispatch(Element* element)
callbacks()->attributeChanged(element, m_name, m_oldValue, m_newValue);
}
+class CreatedInvocation : public CustomElementCallbackInvocation {
+public:
+ CreatedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
+ : CustomElementCallbackInvocation(callbacks)
+ {
+ }
+
+private:
+ virtual void dispatch(Element*) OVERRIDE;
+ virtual bool isCreated() const OVERRIDE { return true; }
+};
+
+void CreatedInvocation::dispatch(Element* element)
+{
+ if (element->inDocument() && element->document().domWindow())
+ CustomElementScheduler::scheduleCallback(callbacks(), element, CustomElementLifecycleCallbacks::Attached);
+ callbacks()->created(element);
+}
+
PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::createInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
{
switch (which) {
@@ -120,7 +121,6 @@ PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::cre
case CustomElementLifecycleCallbacks::Attached:
case CustomElementLifecycleCallbacks::Detached:
return adoptPtr(new AttachedDetachedInvocation(callbacks, which));
-
default:
ASSERT_NOT_REACHED();
return PassOwnPtr<CustomElementCallbackInvocation>();
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
index 097e0918b08..615a3f4c382 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
@@ -32,6 +32,7 @@
#define CustomElementCallbackInvocation_h
#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
+#include "core/dom/custom/CustomElementProcessingStep.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -39,18 +40,12 @@
namespace WebCore {
-class Element;
-
-class CustomElementCallbackInvocation {
+class CustomElementCallbackInvocation : public CustomElementProcessingStep {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackInvocation);
public:
static PassOwnPtr<CustomElementCallbackInvocation> createInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType);
static PassOwnPtr<CustomElementCallbackInvocation> createAttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
- virtual ~CustomElementCallbackInvocation() { }
- virtual void dispatch(Element*) = 0;
- virtual bool isCreated() const { return false; }
-
protected:
CustomElementCallbackInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
: m_callbacks(callbacks)
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp
index 7da3b717550..d20bb901174 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp
@@ -33,12 +33,12 @@
namespace WebCore {
-PassOwnPtr<CustomElementCallbackQueue> CustomElementCallbackQueue::create(PassRefPtr<Element> element)
+PassOwnPtrWillBeRawPtr<CustomElementCallbackQueue> CustomElementCallbackQueue::create(PassRefPtrWillBeRawPtr<Element> element)
{
- return adoptPtr(new CustomElementCallbackQueue(element));
+ return adoptPtrWillBeNoop(new CustomElementCallbackQueue(element));
}
-CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtr<Element> element)
+CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtrWillBeRawPtr<Element> element)
: m_element(element)
, m_owner(-1)
, m_index(0)
@@ -46,9 +46,10 @@ CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtr<Element> eleme
{
}
-void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
+bool CustomElementCallbackQueue::processInElementQueue(ElementQueueId caller)
{
ASSERT(!m_inCreatedCallback);
+ bool didWork = false;
while (m_index < m_queue.size() && owner() == caller) {
m_inCreatedCallback = m_queue[m_index]->isCreated();
@@ -58,6 +59,7 @@ void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
// detects this recursion and cedes processing.
m_queue[m_index++]->dispatch(m_element.get());
m_inCreatedCallback = false;
+ didWork = true;
}
if (owner() == caller && m_index == m_queue.size()) {
@@ -66,6 +68,13 @@ void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
m_queue.resize(0);
m_owner = -1;
}
+
+ return didWork;
+}
+
+void CustomElementCallbackQueue::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
index 269bfd29d4a..015f6ecc611 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
@@ -32,7 +32,9 @@
#define CustomElementCallbackQueue_h
#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackInvocation.h"
+#include "core/dom/custom/CustomElementProcessingStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -40,14 +42,17 @@
namespace WebCore {
-class CustomElementCallbackQueue {
+// FIXME: Rename this because it contains resolution and upgrade as
+// well as callbacks.
+class CustomElementCallbackQueue : public NoBaseWillBeGarbageCollectedFinalized<CustomElementCallbackQueue> {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackQueue);
public:
- static PassOwnPtr<CustomElementCallbackQueue> create(PassRefPtr<Element>);
+ static PassOwnPtrWillBeRawPtr<CustomElementCallbackQueue> create(PassRefPtrWillBeRawPtr<Element>);
- typedef int ElementQueue;
- ElementQueue owner() { return m_owner; }
- void setOwner(ElementQueue newOwner)
+ typedef int ElementQueueId;
+ ElementQueueId owner() const { return m_owner; }
+
+ void setOwner(ElementQueueId newOwner)
{
// ElementCallbackQueues only migrate towards the top of the
// processing stack.
@@ -55,16 +60,19 @@ public:
m_owner = newOwner;
}
- void append(PassOwnPtr<CustomElementCallbackInvocation> invocation) { m_queue.append(invocation); }
- void processInElementQueue(ElementQueue);
+ bool processInElementQueue(ElementQueueId);
+
+ void append(PassOwnPtr<CustomElementProcessingStep> invocation) { m_queue.append(invocation); }
bool inCreatedCallback() const { return m_inCreatedCallback; }
+ void trace(Visitor*);
+
private:
- CustomElementCallbackQueue(PassRefPtr<Element>);
+ explicit CustomElementCallbackQueue(PassRefPtrWillBeRawPtr<Element>);
- RefPtr<Element> m_element;
- Vector<OwnPtr<CustomElementCallbackInvocation> > m_queue;
- ElementQueue m_owner;
+ RefPtrWillBeMember<Element> m_element;
+ Vector<OwnPtr<CustomElementProcessingStep> > m_queue;
+ ElementQueueId m_owner;
size_t m_index;
bool m_inCreatedCallback;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp
deleted file mode 100644
index fc3c90ca63d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
-
-#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackDispatcher.h"
-#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
-
-namespace WebCore {
-
-void CustomElementCallbackScheduler::scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
-{
- if (!callbacks->hasAttributeChangedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().schedule(element);
- queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
-}
-
-void CustomElementCallbackScheduler::scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
-{
- if (!callbacks->hasCreatedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().scheduleInCurrentElementQueue(element);
- queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Created));
-}
-
-void CustomElementCallbackScheduler::scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
-{
- if (!callbacks->hasAttachedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().schedule(element);
- queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Attached));
-}
-
-void CustomElementCallbackScheduler::scheduleDetachedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
-{
- if (!callbacks->hasDetachedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().schedule(element);
- queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Detached));
-}
-
-CustomElementCallbackScheduler& CustomElementCallbackScheduler::instance()
-{
- DEFINE_STATIC_LOCAL(CustomElementCallbackScheduler, instance, ());
- return instance;
-}
-
-CustomElementCallbackQueue* CustomElementCallbackScheduler::ensureCallbackQueue(PassRefPtr<Element> element)
-{
- Element* key = element.get();
- ElementCallbackQueueMap::iterator it = m_elementCallbackQueueMap.find(key);
- if (it == m_elementCallbackQueueMap.end())
- it = m_elementCallbackQueueMap.add(key, CustomElementCallbackQueue::create(element)).iterator;
- return it->value.get();
-}
-
-void CustomElementCallbackScheduler::clearElementCallbackQueueMap()
-{
- ElementCallbackQueueMap emptyMap;
- instance().m_elementCallbackQueueMap.swap(emptyMap);
-}
-
-// Finds or creates the callback queue for element. If the
-// createdCallback has not finished running, the callback queue is not
-// moved to the top-of-stack. Otherwise like
-// scheduleInCurrentElementQueue.
-CustomElementCallbackQueue* CustomElementCallbackScheduler::schedule(PassRefPtr<Element> element)
-{
- CustomElementCallbackQueue* callbackQueue = ensureCallbackQueue(element);
- if (!callbackQueue->inCreatedCallback())
- CustomElementCallbackDispatcher::instance().enqueue(callbackQueue);
- return callbackQueue;
-}
-
-// Finds or creates the callback queue for element. If the element's
-// callback queue is scheduled in an earlier processing stack frame,
-// its owner is set to the element queue on the top of the processing
-// stack. Because callback queues are processed exhaustively, this
-// effectively moves the callback queue to the top of the stack.
-CustomElementCallbackQueue* CustomElementCallbackScheduler::scheduleInCurrentElementQueue(PassRefPtr<Element> element)
-{
- CustomElementCallbackQueue* callbackQueue = ensureCallbackQueue(element);
- CustomElementCallbackDispatcher::instance().enqueue(callbackQueue);
- return callbackQueue;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
index 72e4121ddbd..29b8ba6cbd1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
@@ -33,7 +33,6 @@
#include "core/dom/custom/CustomElementDescriptor.h"
#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
-#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h
index 7a3c6719bcc..5d3a36a8423 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h
@@ -31,6 +31,7 @@
#ifndef CustomElementDescriptor_h
#define CustomElementDescriptor_h
+#include "platform/heap/Handle.h"
#include "wtf/HashTableDeletedValueType.h"
#include "wtf/text/AtomicString.h"
@@ -41,6 +42,7 @@ struct CustomElementDescriptorHash;
// A Custom Element descriptor is everything necessary to match a
// Custom Element instance to a definition.
class CustomElementDescriptor {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
CustomElementDescriptor(const AtomicString& type, const AtomicString& namespaceURI, const AtomicString& localName)
: m_type(type)
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp
index 331548af8b6..ddaf1fc4643 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp
@@ -57,23 +57,23 @@ void CustomElementException::throwException(Reason reason, const AtomicString& t
return;
case ContextDestroyedCreatingCallbacks:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, preamble(type) + "The context is no longer valid.");
return;
case ContextDestroyedRegisteringDefinition:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The context is no longer valid.");
return;
case ExtendsIsInvalidName:
- exceptionState.throwDOMException(InvalidCharacterError, preamble(type) + "The tag name specified in 'extends' is not a valid tag name.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The tag name specified in 'extends' is not a valid tag name.");
return;
case ExtendsIsCustomElementName:
- exceptionState.throwDOMException(InvalidCharacterError, preamble(type) + "The tag name specified in 'extends' is a custom element name. Use inheritance instead.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The tag name specified in 'extends' is a custom element name. Use inheritance instead.");
return;
case InvalidName:
- exceptionState.throwDOMException(InvalidCharacterError, preamble(type) + "The type name is invalid.");
+ exceptionState.throwDOMException(SyntaxError, preamble(type) + "The type name is invalid.");
return;
case PrototypeInUse:
@@ -81,11 +81,11 @@ void CustomElementException::throwException(Reason reason, const AtomicString& t
return;
case PrototypeNotAnObject:
- exceptionState.throwDOMException(InvalidStateError, preamble(type) + "The prototype option is not an object.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The prototype option is not an object.");
return;
case TypeAlreadyRegistered:
- exceptionState.throwDOMException(InvalidStateError, preamble(type) + "A type with that name is already registered.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "A type with that name is already registered.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
index aa182e625d9..a713815e930 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
@@ -42,18 +42,6 @@ class CustomElementLifecycleCallbacks : public RefCounted<CustomElementLifecycle
public:
virtual ~CustomElementLifecycleCallbacks() { }
- bool hasCreatedCallback() const { return m_which & Created; }
- virtual void created(Element*) = 0;
-
- bool hasAttachedCallback() const { return m_which & Attached; }
- virtual void attached(Element*) = 0;
-
- bool hasDetachedCallback() const { return m_which & Detached; }
- virtual void detached(Element*) = 0;
-
- bool hasAttributeChangedCallback() const { return m_which & AttributeChanged; }
- virtual void attributeChanged(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
-
enum CallbackType {
None = 0,
Created = 1 << 0,
@@ -62,6 +50,13 @@ public:
AttributeChanged = 1 << 3
};
+ bool hasCallback(CallbackType type) const { return m_which & type; }
+
+ virtual void created(Element*) = 0;
+ virtual void attached(Element*) = 0;
+ virtual void detached(Element*) = 0;
+ virtual void attributeChanged(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
+
protected:
CustomElementLifecycleCallbacks(CallbackType which) : m_which(which) { }
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
new file mode 100644
index 00000000000..2adc2d15469
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+
+#include "core/dom/Microtask.h"
+#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+#include "core/dom/custom/CustomElementCallbackQueue.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/dom/custom/CustomElementMicrotaskStepDispatcher.h"
+#include "core/dom/custom/CustomElementScheduler.h"
+#include "wtf/MainThread.h"
+
+namespace WebCore {
+
+static const CustomElementCallbackQueue::ElementQueueId kMicrotaskQueueId = 0;
+
+CustomElementMicrotaskDispatcher::CustomElementMicrotaskDispatcher()
+ : m_hasScheduledMicrotask(false)
+ , m_phase(Quiescent)
+ , m_steps(CustomElementMicrotaskStepDispatcher::create())
+{
+}
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementMicrotaskDispatcher)
+
+CustomElementMicrotaskDispatcher& CustomElementMicrotaskDispatcher::instance()
+{
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<CustomElementMicrotaskDispatcher>, instance, (adoptPtrWillBeNoop(new CustomElementMicrotaskDispatcher())));
+ return *instance;
+}
+
+void CustomElementMicrotaskDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step)
+{
+ ensureMicrotaskScheduledForMicrotaskSteps();
+ m_steps->enqueue(parentLoader, step);
+}
+
+void CustomElementMicrotaskDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step, bool importIsSync)
+{
+ ensureMicrotaskScheduledForMicrotaskSteps();
+ m_steps->enqueue(parentLoader, step, importIsSync);
+}
+
+void CustomElementMicrotaskDispatcher::enqueue(CustomElementCallbackQueue* queue)
+{
+ ensureMicrotaskScheduledForElementQueue();
+ queue->setOwner(kMicrotaskQueueId);
+ m_elements.append(queue);
+}
+
+void CustomElementMicrotaskDispatcher::importDidFinish(CustomElementMicrotaskImportStep* step)
+{
+ ensureMicrotaskScheduledForMicrotaskSteps();
+}
+
+void CustomElementMicrotaskDispatcher::ensureMicrotaskScheduledForMicrotaskSteps()
+{
+ ASSERT(m_phase == Quiescent || m_phase == DispatchingCallbacks);
+ ensureMicrotaskScheduled();
+}
+
+void CustomElementMicrotaskDispatcher::ensureMicrotaskScheduledForElementQueue()
+{
+ ASSERT(m_phase == Quiescent || m_phase == Resolving);
+ ensureMicrotaskScheduled();
+}
+
+void CustomElementMicrotaskDispatcher::ensureMicrotaskScheduled()
+{
+ if (!m_hasScheduledMicrotask) {
+ Microtask::enqueueMicrotask(WTF::bind(&dispatch));
+ m_hasScheduledMicrotask = true;
+ }
+}
+
+void CustomElementMicrotaskDispatcher::dispatch()
+{
+ instance().doDispatch();
+}
+
+void CustomElementMicrotaskDispatcher::doDispatch()
+{
+ ASSERT(isMainThread());
+
+ ASSERT(m_phase == Quiescent && m_hasScheduledMicrotask);
+ m_hasScheduledMicrotask = false;
+
+ // Finishing microtask work deletes all
+ // CustomElementCallbackQueues. Being in a callback delivery scope
+ // implies those queues could still be in use.
+ ASSERT_WITH_SECURITY_IMPLICATION(!CustomElementCallbackDispatcher::inCallbackDeliveryScope());
+
+ m_phase = Resolving;
+ m_steps->dispatch();
+
+ m_phase = DispatchingCallbacks;
+ for (WillBeHeapVector<RawPtrWillBeMember<CustomElementCallbackQueue> >::iterator it = m_elements.begin(); it != m_elements.end(); ++it) {
+ // Created callback may enqueue an attached callback.
+ CustomElementCallbackDispatcher::CallbackDeliveryScope scope;
+ (*it)->processInElementQueue(kMicrotaskQueueId);
+ }
+
+ m_elements.clear();
+ CustomElementScheduler::microtaskDispatcherDidFinish();
+ m_phase = Quiescent;
+}
+
+void CustomElementMicrotaskDispatcher::trace(Visitor* visitor)
+{
+ visitor->trace(m_steps);
+#if ENABLE(OILPAN)
+ visitor->trace(m_elements);
+#endif
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskDispatcher::show()
+{
+ m_steps->show(2);
+
+}
+#endif
+
+} // namespace WebCore
+
+#if !defined(NDEBUG)
+void showCEMD()
+{
+ WebCore::CustomElementMicrotaskDispatcher::instance().show();
+}
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
new file mode 100644
index 00000000000..961074fd242
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
@@ -0,0 +1,70 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementMicrotaskDispatcher_h
+#define CustomElementMicrotaskDispatcher_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CustomElementCallbackQueue;
+class CustomElementMicrotaskImportStep;
+class CustomElementMicrotaskStep;
+class CustomElementMicrotaskStepDispatcher;
+class HTMLImportLoader;
+
+class CustomElementMicrotaskDispatcher FINAL : public NoBaseWillBeGarbageCollected<CustomElementMicrotaskDispatcher> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskDispatcher);
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementMicrotaskDispatcher);
+public:
+ static CustomElementMicrotaskDispatcher& instance();
+
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>);
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep>, bool importIsSync);
+
+ void enqueue(CustomElementCallbackQueue*);
+
+
+ void importDidFinish(CustomElementMicrotaskImportStep*);
+
+ bool elementQueueIsEmpty() { return m_elements.isEmpty(); }
+
+ void trace(Visitor*);
+
+#if !defined(NDEBUG)
+ void show();
+#endif
+
+private:
+ CustomElementMicrotaskDispatcher();
+
+ void ensureMicrotaskScheduledForElementQueue();
+ void ensureMicrotaskScheduledForMicrotaskSteps();
+ void ensureMicrotaskScheduled();
+
+ static void dispatch();
+ void doDispatch();
+
+ bool m_hasScheduledMicrotask;
+ enum {
+ Quiescent,
+ Resolving,
+ DispatchingCallbacks
+ } m_phase;
+
+ RefPtrWillBeMember<CustomElementMicrotaskStepDispatcher> m_steps;
+ WillBeHeapVector<RawPtrWillBeMember<CustomElementCallbackQueue> > m_elements;
+};
+
+}
+
+#if !defined(NDEBUG)
+void showCEMD();
+#endif
+
+#endif // CustomElementMicrotaskDispatcher_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp
new file mode 100644
index 00000000000..da48bb882eb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include <stdio.h>
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> CustomElementMicrotaskImportStep::create(HTMLImportChild* import)
+{
+ return adoptPtrWillBeNoop(new CustomElementMicrotaskImportStep(import));
+}
+
+CustomElementMicrotaskImportStep::CustomElementMicrotaskImportStep(HTMLImportChild* import)
+#if ENABLE(OILPAN)
+ : m_import(import)
+#else
+ : m_import(import->weakPtr())
+ , m_weakFactory(this)
+#endif
+ , m_queue(import->loader()->microtaskQueue())
+{
+}
+
+CustomElementMicrotaskImportStep::~CustomElementMicrotaskImportStep()
+{
+}
+
+void CustomElementMicrotaskImportStep::parentWasChanged()
+{
+ m_queue = CustomElementSyncMicrotaskQueue::create();
+ m_import.clear();
+}
+
+bool CustomElementMicrotaskImportStep::shouldWaitForImport() const
+{
+ return m_import && !m_import->loader()->isDone();
+}
+
+void CustomElementMicrotaskImportStep::didUpgradeAllCustomElements()
+{
+ ASSERT(m_queue);
+ if (m_import)
+ m_import->didFinishUpgradingCustomElements();
+}
+
+CustomElementMicrotaskStep::Result CustomElementMicrotaskImportStep::process()
+{
+ m_queue->dispatch();
+ if (!m_queue->isEmpty() || shouldWaitForImport())
+ return Processing;
+
+ didUpgradeAllCustomElements();
+ return FinishedProcessing;
+}
+
+void CustomElementMicrotaskImportStep::trace(Visitor* visitor)
+{
+ visitor->trace(m_import);
+ visitor->trace(m_queue);
+ CustomElementMicrotaskStep::trace(visitor);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskImportStep::show(unsigned indent)
+{
+ fprintf(stderr, "%*sImport(wait=%d sync=%d, url=%s)\n", indent, "", shouldWaitForImport(), m_import && m_import->isSync(), m_import ? m_import->url().string().utf8().data() : "null");
+ m_queue->show(indent + 1);
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
new file mode 100644
index 00000000000..e002356ad78
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementMicrotaskImportStep_h
+#define CustomElementMicrotaskImportStep_h
+
+#include "core/dom/custom/CustomElementMicrotaskStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/WeakPtr.h"
+
+namespace WebCore {
+
+class CustomElementSyncMicrotaskQueue;
+class HTMLImportChild;
+
+// Processes the Custom Elements in an HTML Import. This is a
+// composite step which processes the Custom Elements created by
+// parsing the import, and its sub-imports.
+//
+// This step blocks further Custom Element microtask processing if its
+// import isn't "ready" (finished parsing and running script.)
+class CustomElementMicrotaskImportStep : public CustomElementMicrotaskStep {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskImportStep);
+public:
+ static PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> create(HTMLImportChild*);
+ virtual ~CustomElementMicrotaskImportStep();
+
+ // API for HTML Imports
+ void parentWasChanged();
+ void importDidFinishLoading();
+#if !ENABLE(OILPAN)
+ WeakPtr<CustomElementMicrotaskImportStep> weakPtr() { return m_weakFactory.createWeakPtr(); }
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit CustomElementMicrotaskImportStep(HTMLImportChild*);
+
+ void didUpgradeAllCustomElements();
+ bool shouldWaitForImport() const;
+
+ // CustomElementMicrotaskStep
+ virtual Result process() OVERRIDE FINAL;
+
+#if !defined(NDEBUG)
+ virtual void show(unsigned indent) OVERRIDE;
+#endif
+ WeakPtrWillBeWeakMember<HTMLImportChild> m_import;
+#if !ENABLE(OILPAN)
+ WeakPtrFactory<CustomElementMicrotaskImportStep> m_weakFactory;
+#endif
+ RefPtrWillBeMember<CustomElementSyncMicrotaskQueue> m_queue;
+};
+
+}
+
+#endif // CustomElementMicrotaskImportStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp
new file mode 100644
index 00000000000..0495db605f8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskQueueBase.h"
+
+#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+
+namespace WebCore {
+
+void CustomElementMicrotaskQueueBase::dispatch()
+{
+ ASSERT(!m_inDispatch);
+ m_inDispatch = true;
+ doDispatch();
+ m_inDispatch = false;
+}
+
+void CustomElementMicrotaskQueueBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_queue);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskQueueBase::show(unsigned indent)
+{
+ for (unsigned q = 0; q < m_queue.size(); ++q) {
+ if (m_queue[q])
+ m_queue[q]->show(indent);
+ else
+ fprintf(stderr, "%*snull\n", indent, "");
+ }
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
new file mode 100644
index 00000000000..6520af12152
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementMicrotaskQueueBase_h
+#define CustomElementMicrotaskQueueBase_h
+
+#include "core/dom/custom/CustomElementMicrotaskStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CustomElementMicrotaskQueueBase : public RefCountedWillBeGarbageCollectedFinalized<CustomElementMicrotaskQueueBase> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskQueueBase);
+public:
+ virtual ~CustomElementMicrotaskQueueBase() { }
+
+ bool isEmpty() const { return m_queue.isEmpty(); }
+ void dispatch();
+
+ void trace(Visitor*);
+
+#if !defined(NDEBUG)
+ void show(unsigned indent);
+#endif
+
+protected:
+ CustomElementMicrotaskQueueBase() : m_inDispatch(false) { }
+ virtual void doDispatch() = 0;
+
+ WillBeHeapVector<OwnPtrWillBeMember<CustomElementMicrotaskStep> > m_queue;
+ bool m_inDispatch;
+};
+
+}
+
+#endif // CustomElementMicrotaskQueueBase_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp
new file mode 100644
index 00000000000..7996219b539
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskResolutionStep.h"
+
+#include "core/dom/Element.h"
+#include "core/dom/custom/CustomElementRegistrationContext.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> CustomElementMicrotaskResolutionStep::create(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
+{
+ return adoptPtrWillBeNoop(new CustomElementMicrotaskResolutionStep(context, element, descriptor));
+}
+
+CustomElementMicrotaskResolutionStep::CustomElementMicrotaskResolutionStep(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
+ : m_context(context)
+ , m_element(element)
+ , m_descriptor(descriptor)
+{
+}
+
+CustomElementMicrotaskResolutionStep::~CustomElementMicrotaskResolutionStep()
+{
+}
+
+CustomElementMicrotaskStep::Result CustomElementMicrotaskResolutionStep::process()
+{
+ m_context->resolve(m_element.get(), m_descriptor);
+ return CustomElementMicrotaskStep::FinishedProcessing;
+}
+
+void CustomElementMicrotaskResolutionStep::trace(Visitor* visitor)
+{
+ visitor->trace(m_context);
+ visitor->trace(m_element);
+ CustomElementMicrotaskStep::trace(visitor);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskResolutionStep::show(unsigned indent)
+{
+ fprintf(stderr, "%*sResolution: ", indent, "");
+ m_element->outerHTML().show();
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
index 741ede220bf..c3f04874ea7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
@@ -28,44 +28,44 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CustomElementCallbackScheduler_h
-#define CustomElementCallbackScheduler_h
+#ifndef CustomElementMicrotaskResolutionStep_h
+#define CustomElementMicrotaskResolutionStep_h
-#include "core/dom/custom/CustomElementCallbackQueue.h"
-#include "wtf/HashMap.h"
-#include "wtf/OwnPtr.h"
+#include "core/dom/custom/CustomElementDescriptor.h"
+#include "core/dom/custom/CustomElementMicrotaskStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
-#include "wtf/text/AtomicString.h"
+#include "wtf/RefPtr.h"
namespace WebCore {
-class CustomElementLifecycleCallbacks;
+class CustomElementRegistrationContext;
class Element;
-class CustomElementCallbackScheduler {
+class CustomElementMicrotaskResolutionStep : public CustomElementMicrotaskStep {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskResolutionStep);
public:
- static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
- static void scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
- static void scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
- static void scheduleDetachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
+ static PassOwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> create(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext>, PassRefPtrWillBeRawPtr<Element>, const CustomElementDescriptor&);
-protected:
- friend class CustomElementCallbackDispatcher;
- static void clearElementCallbackQueueMap();
+ virtual ~CustomElementMicrotaskResolutionStep();
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- CustomElementCallbackScheduler() { }
+ CustomElementMicrotaskResolutionStep(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext>, PassRefPtrWillBeRawPtr<Element>, const CustomElementDescriptor&);
- static CustomElementCallbackScheduler& instance();
+ virtual Result process() OVERRIDE;
- CustomElementCallbackQueue* ensureCallbackQueue(PassRefPtr<Element>);
- CustomElementCallbackQueue* schedule(PassRefPtr<Element>);
- CustomElementCallbackQueue* scheduleInCurrentElementQueue(PassRefPtr<Element>);
+#if !defined(NDEBUG)
+ virtual void show(unsigned indent) OVERRIDE;
+#endif
- typedef HashMap<Element*, OwnPtr<CustomElementCallbackQueue> > ElementCallbackQueueMap;
- ElementCallbackQueueMap m_elementCallbackQueueMap;
+ RefPtrWillBeMember<CustomElementRegistrationContext> m_context;
+ RefPtrWillBeMember<Element> m_element;
+ CustomElementDescriptor m_descriptor;
};
}
-#endif // CustomElementCallbackScheduler_h
+#endif // CustomElementMicrotaskResolutionStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h
index 0e8561da12e..c4addd7f0c9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h
@@ -28,37 +28,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "core/dom/custom/CustomElementBaseElementQueue.h"
+#ifndef CustomElementMicrotaskStep_h
+#define CustomElementMicrotaskStep_h
-#include "core/dom/custom/CustomElementCallbackDispatcher.h"
-#include "core/dom/custom/CustomElementCallbackQueue.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
namespace WebCore {
-void CustomElementBaseElementQueue::enqueue(CustomElementCallbackQueue* queue)
-{
- m_queue.append(queue);
-}
+class CustomElementMicrotaskStep : public NoBaseWillBeGarbageCollectedFinalized<CustomElementMicrotaskStep> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskStep);
+public:
+ CustomElementMicrotaskStep() { }
+ virtual ~CustomElementMicrotaskStep() { }
-bool CustomElementBaseElementQueue::dispatch(ElementQueue baseQueueId)
-{
- ASSERT(!m_inDispatch);
- m_inDispatch = true;
+ enum Result {
+ Processing,
+ FinishedProcessing
+ };
- bool didWork = m_queue.size();
+ virtual Result process() = 0;
- for (Vector<CustomElementCallbackQueue*>::iterator it = m_queue.begin(); it != m_queue.end(); ++it) {
- // The created callback may schedule entered document
- // callbacks.
- CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
- (*it)->processInElementQueue(baseQueueId);
- }
+ virtual void trace(Visitor*) { }
- m_queue.resize(0);
- m_inDispatch = 0;
+#if !defined(NDEBUG)
+ virtual void show(unsigned indent) = 0;
+#endif
+};
- return didWork;
}
-} // namespace WebCore
+#endif // CustomElementMicrotaskStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp
new file mode 100644
index 00000000000..bfddfe9aa7d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp
@@ -0,0 +1,58 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskStepDispatcher.h"
+
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/html/imports/HTMLImportLoader.h"
+
+namespace WebCore {
+
+CustomElementMicrotaskStepDispatcher::CustomElementMicrotaskStepDispatcher()
+ : m_syncQueue(CustomElementSyncMicrotaskQueue::create())
+ , m_asyncQueue(CustomElementAsyncImportMicrotaskQueue::create())
+{
+}
+
+void CustomElementMicrotaskStepDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step)
+{
+ if (parentLoader)
+ parentLoader->microtaskQueue()->enqueue(step);
+ else
+ m_syncQueue->enqueue(step);
+}
+
+void CustomElementMicrotaskStepDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step, bool importIsSync)
+{
+ if (importIsSync)
+ enqueue(parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>(step));
+ else
+ m_asyncQueue->enqueue(step);
+}
+
+void CustomElementMicrotaskStepDispatcher::dispatch()
+{
+ m_syncQueue->dispatch();
+ if (m_syncQueue->isEmpty())
+ m_asyncQueue->dispatch();
+}
+
+void CustomElementMicrotaskStepDispatcher::trace(Visitor* visitor)
+{
+ visitor->trace(m_syncQueue);
+ visitor->trace(m_asyncQueue);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskStepDispatcher::show(unsigned indent)
+{
+ fprintf(stderr, "%*sSync:\n", indent, "");
+ m_syncQueue->show(indent + 1);
+ fprintf(stderr, "%*sAsync:\n", indent, "");
+ m_asyncQueue->show(indent + 1);
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h
new file mode 100644
index 00000000000..6e715ed1b5a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementMicrotaskStepDispatcher_h
+#define CustomElementMicrotaskStepDispatcher_h
+
+#include "core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class HTMLImportLoader;
+
+class CustomElementMicrotaskStepDispatcher : public RefCountedWillBeGarbageCollectedFinalized<CustomElementMicrotaskStepDispatcher> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskStepDispatcher);
+public:
+ static PassRefPtrWillBeRawPtr<CustomElementMicrotaskStepDispatcher> create() { return adoptRefWillBeNoop(new CustomElementMicrotaskStepDispatcher()); }
+
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>);
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep>, bool importIsSync);
+
+ void dispatch();
+ void trace(Visitor*);
+
+#if !defined(NDEBUG)
+ void show(unsigned indent);
+#endif
+
+private:
+ CustomElementMicrotaskStepDispatcher();
+
+ RefPtrWillBeMember<CustomElementSyncMicrotaskQueue> m_syncQueue;
+ RefPtrWillBeMember<CustomElementAsyncImportMicrotaskQueue> m_asyncQueue;
+};
+
+}
+
+#endif // CustomElementMicrotaskStepDispatcher_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp
index 94247fccecc..9b537447f39 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp
@@ -31,12 +31,18 @@
#include "config.h"
#include "core/dom/custom/CustomElementObserver.h"
+#include "core/dom/Element.h"
+
namespace WebCore {
-CustomElementObserver::ElementObserverMap& CustomElementObserver::elementObservers()
+// Maps elements to the observer watching them. At most one per
+// element at a time.
+typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Element>, RawPtrWillBeMember<CustomElementObserver> > ElementObserverMap;
+
+static ElementObserverMap& elementObservers()
{
- DEFINE_STATIC_LOCAL(ElementObserverMap, map, ());
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<ElementObserverMap>, map, (adoptPtrWillBeNoop(new ElementObserverMap())));
+ return *map;
}
void CustomElementObserver::notifyElementDidFinishParsingChildren(Element* element)
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h
index ab7c57dcee8..6af62d5a6cb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h
@@ -31,15 +31,15 @@
#ifndef CustomElementObserver_h
#define CustomElementObserver_h
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
namespace WebCore {
class Element;
-class CustomElementObserver {
+class CustomElementObserver : public NoBaseWillBeGarbageCollectedFinalized<CustomElementObserver> {
public:
- CustomElementObserver() { }
virtual ~CustomElementObserver() { }
// API for CustomElement to kick off notifications
@@ -47,18 +47,16 @@ public:
static void notifyElementDidFinishParsingChildren(Element*);
static void notifyElementWasDestroyed(Element*);
+ virtual void trace(Visitor*) { }
+
protected:
+ CustomElementObserver() { }
+
void observe(Element*);
void unobserve(Element*);
virtual void elementDidFinishParsingChildren(Element*) = 0;
virtual void elementWasDestroyed(Element* element) { unobserve(element); }
-
-private:
- // Maps elements to the observer watching them. At most one per
- // element at a time.
- typedef HashMap<Element*, CustomElementObserver*> ElementObserverMap;
- static ElementObserverMap& elementObservers();
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h
index 78882aa3e0a..c92451bae82 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h
@@ -28,31 +28,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CustomElementBaseElementQueue_h
-#define CustomElementBaseElementQueue_h
+#ifndef CustomElementProcessingStep_h
+#define CustomElementProcessingStep_h
-#include "wtf/Vector.h"
+#include "wtf/Noncopyable.h"
namespace WebCore {
-class CustomElementCallbackQueue;
+class Element;
-class CustomElementBaseElementQueue {
- WTF_MAKE_NONCOPYABLE(CustomElementBaseElementQueue);
+class CustomElementProcessingStep {
+ WTF_MAKE_NONCOPYABLE(CustomElementProcessingStep);
public:
- CustomElementBaseElementQueue() : m_inDispatch(false) { }
+ CustomElementProcessingStep() { }
- bool isEmpty() const { return m_queue.isEmpty(); }
- void enqueue(CustomElementCallbackQueue*);
-
- typedef int ElementQueue;
- bool dispatch(ElementQueue baseQueueId);
-
-private:
- bool m_inDispatch;
- Vector<CustomElementCallbackQueue*> m_queue;
+ virtual ~CustomElementProcessingStep() { }
+ virtual void dispatch(Element*) = 0;
+ virtual bool isCreated() const { return false; }
};
}
-#endif // CustomElementBaseElementQueue_h
+#endif // CustomElementProcessingStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
index e248ab7cbf1..1c8898ad23c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
@@ -31,13 +31,14 @@
#include "config.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/custom/CustomElement.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
#include "core/dom/custom/CustomElementDefinition.h"
+#include "core/dom/custom/CustomElementScheduler.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLUnknownElement.h"
#include "core/svg/SVGUnknownElement.h"
@@ -45,6 +46,11 @@
namespace WebCore {
+CustomElementRegistrationContext::CustomElementRegistrationContext()
+ : m_candidates(CustomElementUpgradeCandidateMap::create())
+{
+}
+
void CustomElementRegistrationContext::registerElement(Document* document, CustomElementConstructorBuilder* constructorBuilder, const AtomicString& type, CustomElement::NameSet validNames, ExceptionState& exceptionState)
{
CustomElementDefinition* definition = m_registry.registerElement(document, constructorBuilder, type, validNames, exceptionState);
@@ -53,16 +59,20 @@ void CustomElementRegistrationContext::registerElement(Document* document, Custo
return;
// Upgrade elements that were waiting for this definition.
- const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition->descriptor());
- for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it)
- didResolveElement(definition, *it);
+ OwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap::ElementSet> upgradeCandidates = m_candidates->takeUpgradeCandidatesFor(definition->descriptor());
+
+ if (!upgradeCandidates)
+ return;
+
+ for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates->begin(); it != upgradeCandidates->end(); ++it)
+ CustomElement::define(*it, definition);
}
-PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName)
+PassRefPtrWillBeRawPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName)
{
ASSERT(CustomElement::isValidName(tagName.localName()));
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element;
if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI()) {
element = HTMLElement::create(tagName, document);
@@ -74,16 +84,16 @@ PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Doc
}
element->setCustomElementState(Element::WaitingForUpgrade);
- resolve(element.get(), nullAtom);
+ resolveOrScheduleResolution(element.get(), nullAtom);
return element.release();
}
void CustomElementRegistrationContext::didGiveTypeExtension(Element* element, const AtomicString& type)
{
- resolve(element, type);
+ resolveOrScheduleResolution(element, type);
}
-void CustomElementRegistrationContext::resolve(Element* element, const AtomicString& typeExtension)
+void CustomElementRegistrationContext::resolveOrScheduleResolution(Element* element, const AtomicString& typeExtension)
{
// If an element has a custom tag name it takes precedence over
// the "is" attribute (if any).
@@ -93,27 +103,20 @@ void CustomElementRegistrationContext::resolve(Element* element, const AtomicStr
ASSERT(!type.isNull());
CustomElementDescriptor descriptor(type, element->namespaceURI(), element->localName());
- CustomElementDefinition* definition = m_registry.find(descriptor);
- if (definition)
- didResolveElement(definition, element);
- else
- didCreateUnresolvedElement(descriptor, element);
-}
-
-void CustomElementRegistrationContext::didResolveElement(CustomElementDefinition* definition, Element* element)
-{
- CustomElement::define(element, definition);
-}
-
-void CustomElementRegistrationContext::didCreateUnresolvedElement(const CustomElementDescriptor& descriptor, Element* element)
-{
ASSERT(element->customElementState() == Element::WaitingForUpgrade);
- m_candidates.add(descriptor, element);
+
+ CustomElementScheduler::resolveOrScheduleResolution(this, element, descriptor);
}
-PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::create()
+void CustomElementRegistrationContext::resolve(Element* element, const CustomElementDescriptor& descriptor)
{
- return adoptRef(new CustomElementRegistrationContext());
+ CustomElementDefinition* definition = m_registry.find(descriptor);
+ if (definition) {
+ CustomElement::define(element, definition);
+ } else {
+ ASSERT(element->customElementState() == Element::WaitingForUpgrade);
+ m_candidates->add(descriptor, element);
+ }
}
void CustomElementRegistrationContext::setIsAttributeAndTypeExtension(Element* element, const AtomicString& type)
@@ -129,6 +132,10 @@ void CustomElementRegistrationContext::setTypeExtension(Element* element, const
if (!element->isHTMLElement() && !element->isSVGElement())
return;
+ CustomElementRegistrationContext* context = element->document().registrationContext();
+ if (!context)
+ return;
+
if (element->isCustomElement()) {
// This can happen if:
// 1. The element has a custom tag, which takes precedence over
@@ -141,10 +148,16 @@ void CustomElementRegistrationContext::setTypeExtension(Element* element, const
// Custom tags take precedence over type extensions
ASSERT(!CustomElement::isValidName(element->localName()));
+ if (!CustomElement::isValidName(type))
+ return;
+
element->setCustomElementState(Element::WaitingForUpgrade);
+ context->didGiveTypeExtension(element, type);
+}
- if (CustomElementRegistrationContext* context = element->document().registrationContext())
- context->didGiveTypeExtension(element, type);
+void CustomElementRegistrationContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_candidates);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
index 97dbc5fbfa7..6f8b9ff7151 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
@@ -35,7 +35,9 @@
#include "core/dom/custom/CustomElementDescriptor.h"
#include "core/dom/custom/CustomElementRegistry.h"
#include "core/dom/custom/CustomElementUpgradeCandidateMap.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/AtomicString.h"
@@ -47,34 +49,39 @@ class Document;
class Element;
class ExceptionState;
-class CustomElementRegistrationContext : public RefCounted<CustomElementRegistrationContext> {
+class CustomElementRegistrationContext FINAL : public RefCountedWillBeGarbageCollectedFinalized<CustomElementRegistrationContext> {
public:
- static PassRefPtr<CustomElementRegistrationContext> create();
+ static PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> create()
+ {
+ return adoptRefWillBeNoop(new CustomElementRegistrationContext());
+ }
~CustomElementRegistrationContext() { }
// Definitions
void registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString& type, CustomElement::NameSet validNames, ExceptionState&);
- PassRefPtr<Element> createCustomTagElement(Document&, const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Element> createCustomTagElement(Document&, const QualifiedName&);
static void setIsAttributeAndTypeExtension(Element*, const AtomicString& type);
static void setTypeExtension(Element*, const AtomicString& type);
+ void resolve(Element*, const CustomElementDescriptor&);
+
+ void trace(Visitor*);
+
protected:
- CustomElementRegistrationContext() { }
+ CustomElementRegistrationContext();
// Instance creation
void didGiveTypeExtension(Element*, const AtomicString& type);
private:
- void resolve(Element*, const AtomicString& typeExtension);
- void didResolveElement(CustomElementDefinition*, Element*);
- void didCreateUnresolvedElement(const CustomElementDescriptor&, Element*);
+ void resolveOrScheduleResolution(Element*, const AtomicString& typeExtension);
CustomElementRegistry m_registry;
// Element creation
- CustomElementUpgradeCandidateMap m_candidates;
+ OwnPtrWillBeMember<CustomElementUpgradeCandidateMap> m_candidates;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
index b4bd6668dea..f5f3bf1d541 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/dom/custom/CustomElementRegistry.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/CustomElementConstructorBuilder.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/custom/CustomElementException.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
@@ -51,7 +51,12 @@ public:
bool registrationContextWentAway() { return m_wentAway; }
private:
+#if ENABLE(OILPAN)
+ // In oilpan we don't have the disposed phase for context lifecycle observer.
+ virtual void documentWasDetached() OVERRIDE { m_wentAway = true; }
+#else
virtual void documentWasDisposed() OVERRIDE { m_wentAway = true; }
+#endif
bool m_wentAway;
};
@@ -76,7 +81,7 @@ CustomElementDefinition* CustomElementRegistry::registerElement(Document* docume
return 0;
}
- QualifiedName tagName = nullQName();
+ QualifiedName tagName = QualifiedName::null();
if (!constructorBuilder->validateOptions(type, tagName, exceptionState))
return 0;
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp
new file mode 100644
index 00000000000..0fd5203dba4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementScheduler.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+#include "core/dom/custom/CustomElementCallbackInvocation.h"
+#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/dom/custom/CustomElementMicrotaskResolutionStep.h"
+#include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/html/imports/HTMLImportChild.h"
+
+namespace WebCore {
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementScheduler)
+
+void CustomElementScheduler::scheduleCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, CustomElementLifecycleCallbacks::CallbackType type)
+{
+ ASSERT(type != CustomElementLifecycleCallbacks::AttributeChanged);
+
+ if (!callbacks->hasCallback(type))
+ return;
+
+ CustomElementCallbackQueue& queue = instance().schedule(element);
+ queue.append(CustomElementCallbackInvocation::createInvocation(callbacks, type));
+}
+
+void CustomElementScheduler::scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
+{
+ if (!callbacks->hasCallback(CustomElementLifecycleCallbacks::AttributeChanged))
+ return;
+
+ CustomElementCallbackQueue& queue = instance().schedule(element);
+ queue.append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
+}
+
+void CustomElementScheduler::resolveOrScheduleResolution(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
+{
+ if (CustomElementCallbackDispatcher::inCallbackDeliveryScope()) {
+ context->resolve(element.get(), descriptor);
+ return;
+ }
+
+ HTMLImportLoader* loader = element->document().importLoader();
+ OwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> step = CustomElementMicrotaskResolutionStep::create(context, element, descriptor);
+ CustomElementMicrotaskDispatcher::instance().enqueue(loader, step.release());
+}
+
+CustomElementMicrotaskImportStep* CustomElementScheduler::scheduleImport(HTMLImportChild* import)
+{
+ ASSERT(!import->isDone());
+ ASSERT(import->parent());
+
+ // Ownership of the new step is transferred to the parent
+ // processing step, or the base queue.
+ OwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step = CustomElementMicrotaskImportStep::create(import);
+ CustomElementMicrotaskImportStep* rawStep = step.get();
+ CustomElementMicrotaskDispatcher::instance().enqueue(import->parent()->loader(), step.release(), import->isSync());
+ return rawStep;
+}
+
+CustomElementScheduler& CustomElementScheduler::instance()
+{
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<CustomElementScheduler>, instance, (adoptPtrWillBeNoop (new CustomElementScheduler())));
+ return *instance;
+}
+
+CustomElementCallbackQueue& CustomElementScheduler::ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element> element)
+{
+ ElementCallbackQueueMap::ValueType* it = m_elementCallbackQueueMap.add(element.get(), nullptr).storedValue;
+ if (!it->value)
+ it->value = CustomElementCallbackQueue::create(element);
+ return *it->value.get();
+}
+
+void CustomElementScheduler::callbackDispatcherDidFinish()
+{
+ if (CustomElementMicrotaskDispatcher::instance().elementQueueIsEmpty())
+ instance().clearElementCallbackQueueMap();
+}
+
+void CustomElementScheduler::microtaskDispatcherDidFinish()
+{
+ ASSERT(!CustomElementCallbackDispatcher::inCallbackDeliveryScope());
+ instance().clearElementCallbackQueueMap();
+}
+
+void CustomElementScheduler::clearElementCallbackQueueMap()
+{
+ ElementCallbackQueueMap emptyMap;
+ m_elementCallbackQueueMap.swap(emptyMap);
+}
+
+// Finds or creates the callback queue for element.
+CustomElementCallbackQueue& CustomElementScheduler::schedule(PassRefPtrWillBeRawPtr<Element> passElement)
+{
+ RefPtrWillBeRawPtr<Element> element(passElement);
+
+ CustomElementCallbackQueue& callbackQueue = ensureCallbackQueue(element);
+ if (callbackQueue.inCreatedCallback()) {
+ // Don't move it. Authors use the createdCallback like a
+ // constructor. By not moving it, the createdCallback
+ // completes before any other callbacks are entered for this
+ // element.
+ return callbackQueue;
+ }
+
+ if (CustomElementCallbackDispatcher::inCallbackDeliveryScope()) {
+ // The processing stack is active.
+ CustomElementCallbackDispatcher::instance().enqueue(&callbackQueue);
+ return callbackQueue;
+ }
+
+ CustomElementMicrotaskDispatcher::instance().enqueue(&callbackQueue);
+ return callbackQueue;
+}
+
+void CustomElementScheduler::trace(Visitor* visitor)
+{
+ visitor->trace(m_elementCallbackQueueMap);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
new file mode 100644
index 00000000000..68c3dc9382f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementScheduler_h
+#define CustomElementScheduler_h
+
+#include "core/dom/custom/CustomElementCallbackQueue.h"
+#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
+#include "platform/heap/Handle.h"
+#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class CustomElementDescriptor;
+class CustomElementMicrotaskImportStep;
+class CustomElementRegistrationContext;
+class Element;
+class HTMLImportChild;
+
+class CustomElementScheduler FINAL : public NoBaseWillBeGarbageCollected<CustomElementScheduler> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementScheduler);
+public:
+
+ static void scheduleCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtrWillBeRawPtr<Element>, CustomElementLifecycleCallbacks::CallbackType);
+ static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtrWillBeRawPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
+
+ static void resolveOrScheduleResolution(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext>, PassRefPtrWillBeRawPtr<Element>, const CustomElementDescriptor&);
+ static CustomElementMicrotaskImportStep* scheduleImport(HTMLImportChild*);
+
+ static void microtaskDispatcherDidFinish();
+ static void callbackDispatcherDidFinish();
+
+ void trace(Visitor*);
+
+private:
+ CustomElementScheduler() { }
+
+ static CustomElementScheduler& instance();
+
+ CustomElementCallbackQueue& ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element>);
+ CustomElementCallbackQueue& schedule(PassRefPtrWillBeRawPtr<Element>);
+
+ // FIXME: Consider moving the element's callback queue to
+ // ElementRareData. Then the scheduler can become completely
+ // static.
+ void clearElementCallbackQueueMap();
+
+ // The element -> callback queue map is populated by the scheduler
+ // and owns the lifetimes of the CustomElementCallbackQueues.
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<Element>, OwnPtrWillBeMember<CustomElementCallbackQueue> > ElementCallbackQueueMap;
+ ElementCallbackQueueMap m_elementCallbackQueueMap;
+};
+
+}
+
+#endif // CustomElementScheduler_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp
new file mode 100644
index 00000000000..1fcd764e75d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+
+namespace WebCore {
+
+void CustomElementSyncMicrotaskQueue::enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step)
+{
+ m_queue.append(step);
+}
+
+void CustomElementSyncMicrotaskQueue::doDispatch()
+{
+ unsigned i;
+
+ for (i = 0; i < m_queue.size(); ++i) {
+ if (CustomElementMicrotaskStep::Processing == m_queue[i]->process())
+ break;
+ }
+
+ m_queue.remove(0, i);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h
new file mode 100644
index 00000000000..67bca95f642
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementSyncMicrotaskQueue_h
+#define CustomElementSyncMicrotaskQueue_h
+
+#include "core/dom/custom/CustomElementMicrotaskQueueBase.h"
+
+namespace WebCore {
+
+class CustomElementSyncMicrotaskQueue : public CustomElementMicrotaskQueueBase {
+public:
+ static PassRefPtrWillBeRawPtr<CustomElementSyncMicrotaskQueue> create() { return adoptRefWillBeNoop(new CustomElementSyncMicrotaskQueue()); }
+
+ void enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>);
+
+private:
+ CustomElementSyncMicrotaskQueue() { }
+ virtual void doDispatch();
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
index b7ea628bd48..998a6d5823b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
@@ -35,11 +35,20 @@
namespace WebCore {
+PassOwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap> CustomElementUpgradeCandidateMap::create()
+{
+ return adoptPtrWillBeNoop(new CustomElementUpgradeCandidateMap());
+}
+
CustomElementUpgradeCandidateMap::~CustomElementUpgradeCandidateMap()
{
+#if !ENABLE(OILPAN)
+ // With Oilpan enabled, the observer table keeps a weak reference to the
+ // element; no need for explicit removal.
UpgradeCandidateMap::const_iterator::Keys end = m_upgradeCandidates.end().keys();
for (UpgradeCandidateMap::const_iterator::Keys it = m_upgradeCandidates.begin().keys(); it != end; ++it)
unobserve(*it);
+#endif
}
void CustomElementUpgradeCandidateMap::add(const CustomElementDescriptor& descriptor, Element* element)
@@ -50,31 +59,23 @@ void CustomElementUpgradeCandidateMap::add(const CustomElementDescriptor& descri
ASSERT_UNUSED(result, result.isNewEntry);
UnresolvedDefinitionMap::iterator it = m_unresolvedDefinitions.find(descriptor);
+ ElementSet* elements;
if (it == m_unresolvedDefinitions.end())
- it = m_unresolvedDefinitions.add(descriptor, ElementSet()).iterator;
- it->value.add(element);
-}
-
-void CustomElementUpgradeCandidateMap::remove(Element* element)
-{
- unobserve(element);
- removeCommon(element);
+ elements = m_unresolvedDefinitions.add(descriptor, adoptPtrWillBeNoop(new ElementSet())).storedValue->value.get();
+ else
+ elements = it->value.get();
+ elements->add(element);
}
void CustomElementUpgradeCandidateMap::elementWasDestroyed(Element* element)
{
CustomElementObserver::elementWasDestroyed(element);
- removeCommon(element);
-}
-
-void CustomElementUpgradeCandidateMap::removeCommon(Element* element)
-{
UpgradeCandidateMap::iterator candidate = m_upgradeCandidates.find(element);
ASSERT_WITH_SECURITY_IMPLICATION(candidate != m_upgradeCandidates.end());
UnresolvedDefinitionMap::iterator elements = m_unresolvedDefinitions.find(candidate->value);
ASSERT_WITH_SECURITY_IMPLICATION(elements != m_unresolvedDefinitions.end());
- elements->value.remove(element);
+ elements->value->remove(element);
m_upgradeCandidates.remove(candidate);
}
@@ -92,19 +93,28 @@ void CustomElementUpgradeCandidateMap::moveToEnd(Element* element)
UnresolvedDefinitionMap::iterator elements = m_unresolvedDefinitions.find(candidate->value);
ASSERT_WITH_SECURITY_IMPLICATION(elements != m_unresolvedDefinitions.end());
- elements->value.appendOrMoveToLast(element);
+ elements->value->appendOrMoveToLast(element);
}
-ListHashSet<Element*> CustomElementUpgradeCandidateMap::takeUpgradeCandidatesFor(const CustomElementDescriptor& descriptor)
+PassOwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap::ElementSet> CustomElementUpgradeCandidateMap::takeUpgradeCandidatesFor(const CustomElementDescriptor& descriptor)
{
- const ListHashSet<Element*>& candidates = m_unresolvedDefinitions.take(descriptor);
+ OwnPtrWillBeRawPtr<ElementSet> candidates = m_unresolvedDefinitions.take(descriptor);
- for (ElementSet::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate) {
+ if (!candidates)
+ return nullptr;
+
+ for (ElementSet::const_iterator candidate = candidates->begin(); candidate != candidates->end(); ++candidate) {
unobserve(*candidate);
m_upgradeCandidates.remove(*candidate);
}
+ return candidates.release();
+}
- return candidates;
+void CustomElementUpgradeCandidateMap::trace(Visitor* visitor)
+{
+ visitor->trace(m_upgradeCandidates);
+ visitor->trace(m_unresolvedDefinitions);
+ CustomElementObserver::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h
index f68c50b65be..e92262eb6b9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h
@@ -35,38 +35,40 @@
#include "core/dom/custom/CustomElementDescriptorHash.h"
#include "core/dom/custom/CustomElementObserver.h"
#include "wtf/HashMap.h"
-#include "wtf/ListHashSet.h"
+#include "wtf/LinkedHashSet.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
class Element;
-class CustomElementUpgradeCandidateMap : CustomElementObserver {
+class CustomElementUpgradeCandidateMap FINAL : public CustomElementObserver {
WTF_MAKE_NONCOPYABLE(CustomElementUpgradeCandidateMap);
public:
- CustomElementUpgradeCandidateMap() { }
- ~CustomElementUpgradeCandidateMap();
+ static PassOwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap> create();
+ virtual ~CustomElementUpgradeCandidateMap();
// API for CustomElementRegistrationContext to save and take candidates
- typedef ListHashSet<Element*> ElementSet;
+ typedef WillBeHeapLinkedHashSet<RawPtrWillBeWeakMember<Element> > ElementSet;
void add(const CustomElementDescriptor&, Element*);
- void remove(Element*);
- ElementSet takeUpgradeCandidatesFor(const CustomElementDescriptor&);
+ PassOwnPtrWillBeRawPtr<ElementSet> takeUpgradeCandidatesFor(const CustomElementDescriptor&);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
+ CustomElementUpgradeCandidateMap() { }
+
virtual void elementWasDestroyed(Element*) OVERRIDE;
- void removeCommon(Element*);
virtual void elementDidFinishParsingChildren(Element*) OVERRIDE;
void moveToEnd(Element*);
- typedef HashMap<Element*, CustomElementDescriptor> UpgradeCandidateMap;
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Element>, CustomElementDescriptor> UpgradeCandidateMap;
UpgradeCandidateMap m_upgradeCandidates;
- typedef HashMap<CustomElementDescriptor, ElementSet> UnresolvedDefinitionMap;
+ typedef WillBeHeapHashMap<CustomElementDescriptor, OwnPtrWillBeMember<ElementSet> > UnresolvedDefinitionMap;
UnresolvedDefinitionMap m_unresolvedDefinitions;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp
index 2a1561202fc..0ea969d8696 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -30,8 +30,7 @@
#include "core/dom/Element.h"
#include "core/dom/shadow/ElementShadow.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
namespace WebCore {
@@ -73,7 +72,7 @@ Node* ComposedTreeWalker::traverseNode(const Node* node, TraversalDirection dire
const InsertionPoint* insertionPoint = toInsertionPoint(node);
if (Node* found = traverseDistributedNodes(direction == TraversalDirectionForward ? insertionPoint->first() : insertionPoint->last(), insertionPoint, direction))
return found;
- ASSERT(isHTMLShadowElement(node) || (isHTMLContentElement(node) && !node->hasChildNodes()));
+ ASSERT(isHTMLShadowElement(node) || (isHTMLContentElement(node) && !node->hasChildren()));
return 0;
}
@@ -140,14 +139,14 @@ Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetail
// The node is distributed. But the distribution was stopped at this insertion point.
if (shadowWhereNodeCanBeDistributed(*insertionPoint))
return 0;
- return traverseParentOrHost(insertionPoint, details);
+ return traverseParentOrHost(insertionPoint);
}
return 0;
}
- return traverseParentOrHost(node, details);
+ return traverseParentOrHost(node);
}
-inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node, ParentTraversalDetails* details) const
+inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node) const
{
Node* parent = node->parentNode();
if (!parent)
@@ -158,8 +157,6 @@ inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node, ParentTr
ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
if (!shadowRoot->isYoungest())
return 0;
- if (details)
- details->didTraverseShadowRoot(shadowRoot);
return shadowRoot->host();
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h
index b750e34c2a0..81cb1567d9b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -39,6 +39,7 @@ class ShadowRoot;
// FIXME: Make some functions inline to optimise the performance.
// https://bugs.webkit.org/show_bug.cgi?id=82702
class ComposedTreeWalker {
+ STACK_ALLOCATED();
public:
typedef NodeRenderingTraversal::ParentDetails ParentTraversalDetails;
@@ -49,7 +50,7 @@ public:
ComposedTreeWalker(const Node*, StartPolicy = CannotStartFromShadowBoundary);
- Node* get() const { return const_cast<Node*>(m_node); }
+ Node* get() const { return const_cast<Node*>(m_node.get()); }
void firstChild();
void lastChild();
@@ -107,9 +108,9 @@ private:
static Node* traverseBackToYoungerShadowRoot(const Node*, TraversalDirection);
- Node* traverseParentOrHost(const Node*, ParentTraversalDetails* = 0) const;
+ Node* traverseParentOrHost(const Node*) const;
- const Node* m_node;
+ RawPtrWillBeMember<const Node> m_node;
};
inline ComposedTreeWalker::ComposedTreeWalker(const Node* node, StartPolicy startPolicy)
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp
index a53ff57b81b..6b5bed5d153 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp
@@ -37,7 +37,7 @@ void ContentDistribution::swap(ContentDistribution& other)
m_indices.swap(other.m_indices);
}
-void ContentDistribution::append(PassRefPtr<Node> node)
+void ContentDistribution::append(PassRefPtrWillBeRawPtr<Node> node)
{
ASSERT(node);
ASSERT(!isActiveInsertionPoint(*node));
@@ -48,7 +48,7 @@ void ContentDistribution::append(PassRefPtr<Node> node)
size_t ContentDistribution::find(const Node* node) const
{
- HashMap<const Node*, size_t>::const_iterator it = m_indices.find(node);
+ WillBeHeapHashMap<RawPtrWillBeMember<const Node>, size_t>::const_iterator it = m_indices.find(node);
if (it == m_indices.end())
return kNotFound;
@@ -71,4 +71,10 @@ Node* ContentDistribution::previousTo(const Node* node) const
return at(index - 1).get();
}
+void ContentDistribution::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodes);
+ visitor->trace(m_indices);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h
index 65a221d9ea8..c3c7d707ae1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h
@@ -32,24 +32,24 @@
#define ContentDistribution_h
#include "core/dom/Node.h"
-#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
namespace WebCore {
-class ContentDistribution {
+class ContentDistribution FINAL {
+ DISALLOW_ALLOCATION();
public:
ContentDistribution() { m_nodes.reserveInitialCapacity(32); }
- PassRefPtr<Node> first() const { return m_nodes.first(); }
- PassRefPtr<Node> last() const { return m_nodes.last(); }
- PassRefPtr<Node> at(size_t index) const { return m_nodes.at(index); }
+ PassRefPtrWillBeRawPtr<Node> first() const { return m_nodes.first(); }
+ PassRefPtrWillBeRawPtr<Node> last() const { return m_nodes.last(); }
+ PassRefPtrWillBeRawPtr<Node> at(size_t index) const { return m_nodes.at(index); }
size_t size() const { return m_nodes.size(); }
bool isEmpty() const { return m_nodes.isEmpty(); }
- void append(PassRefPtr<Node>);
+ void append(PassRefPtrWillBeRawPtr<Node>);
void clear() { m_nodes.clear(); m_indices.clear(); }
void shrinkToFit() { m_nodes.shrinkToFit(); }
@@ -60,11 +60,13 @@ public:
void swap(ContentDistribution& other);
- const Vector<RefPtr<Node> >& nodes() const { return m_nodes; }
+ const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes() const { return m_nodes; }
+
+ void trace(Visitor*);
private:
- Vector<RefPtr<Node> > m_nodes;
- HashMap<const Node*, size_t> m_indices;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_nodes;
+ WillBeHeapHashMap<RawPtrWillBeMember<const Node>, size_t> m_indices;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
index 913bb93efc5..6e65a4962b0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
@@ -27,16 +27,19 @@
#include "config.h"
#include "core/dom/shadow/ElementShadow.h"
+#include "core/css/StyleSheetList.h"
#include "core/dom/ContainerNodeAlgorithms.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ContentDistribution.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLContentElement.h"
+#include "core/html/HTMLShadowElement.h"
+#include "core/inspector/InspectorInstrumentation.h"
namespace WebCore {
-class DistributionPool {
+class DistributionPool FINAL {
+ STACK_ALLOCATED();
public:
explicit DistributionPool(const ContainerNode&);
void clear();
@@ -46,7 +49,7 @@ public:
private:
void detachNonDistributedNodes();
- Vector<Node*, 32> m_nodes;
+ WillBeHeapVector<RawPtrWillBeMember<Node>, 32> m_nodes;
Vector<bool, 32> m_distributed;
};
@@ -86,7 +89,7 @@ void DistributionPool::distributeTo(InsertionPoint* insertionPoint, ElementShado
if (m_distributed[i])
continue;
- if (isHTMLContentElement(insertionPoint) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
+ if (isHTMLContentElement(*insertionPoint) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
continue;
Node* node = m_nodes[i];
@@ -120,41 +123,40 @@ inline void DistributionPool::detachNonDistributedNodes()
}
}
-PassOwnPtr<ElementShadow> ElementShadow::create()
+PassOwnPtrWillBeRawPtr<ElementShadow> ElementShadow::create()
{
- return adoptPtr(new ElementShadow());
+ return adoptPtrWillBeNoop(new ElementShadow());
}
ElementShadow::ElementShadow()
: m_needsDistributionRecalc(false)
- , m_applyAuthorStyles(false)
, m_needsSelectFeatureSet(false)
{
}
ElementShadow::~ElementShadow()
{
- removeAllShadowRoots();
+#if !ENABLE(OILPAN)
+ removeDetachedShadowRoots();
+#endif
}
ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType type)
{
- RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(&shadowHost.document(), type);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = ShadowRoot::create(shadowHost.document(), type);
+
+ if (type == ShadowRoot::AuthorShadowRoot && (!youngestShadowRoot() || youngestShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot))
+ shadowHost.willAddFirstAuthorShadowRoot();
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
root->lazyReattachIfAttached();
shadowRoot->setParentOrShadowHostNode(&shadowHost);
- shadowRoot->setParentTreeScope(&shadowHost.treeScope());
+ shadowRoot->setParentTreeScope(shadowHost.treeScope());
m_shadowRoots.push(shadowRoot.get());
- ChildNodeInsertionNotifier(shadowHost).notify(*shadowRoot);
+ shadowHost.notifyNodeInserted(*shadowRoot);
setNeedsDistributionRecalc();
- // addShadowRoot() affects apply-author-styles. However, we know that the youngest shadow root has not had any children yet.
- // The youngest shadow root's apply-author-styles is default (false). So we can just set m_applyAuthorStyles false.
- m_applyAuthorStyles = false;
-
- shadowHost.didAddShadowRoot(*shadowRoot);
InspectorInstrumentation::didPushShadowRoot(&shadowHost, shadowRoot.get());
ASSERT(m_shadowRoots.head());
@@ -162,23 +164,24 @@ ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost, ShadowRoot::Shadow
return *m_shadowRoots.head();
}
-void ElementShadow::removeAllShadowRoots()
+#if !ENABLE(OILPAN)
+void ElementShadow::removeDetachedShadowRoots()
{
// Dont protect this ref count.
Element* shadowHost = host();
ASSERT(shadowHost);
- while (RefPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
+ while (RefPtrWillBeRawPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
InspectorInstrumentation::willPopShadowRoot(shadowHost, oldRoot.get());
shadowHost->document().removeFocusedElementOfSubtree(oldRoot.get());
m_shadowRoots.removeHead();
oldRoot->setParentOrShadowHostNode(0);
- oldRoot->setParentTreeScope(&shadowHost->document());
+ oldRoot->setParentTreeScope(shadowHost->document());
oldRoot->setPrev(0);
oldRoot->setNext(0);
- ChildNodeRemovalNotifier(*shadowHost).notify(*oldRoot);
}
}
+#endif
void ElementShadow::attach(const Node::AttachContext& context)
{
@@ -200,14 +203,6 @@ void ElementShadow::detach(const Node::AttachContext& context)
root->detach(childrenContext);
}
-void ElementShadow::removeAllEventListeners()
-{
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- for (Node* node = root; node; node = NodeTraversal::next(*node))
- node->removeAllEventListeners();
- }
-}
-
void ElementShadow::setNeedsDistributionRecalc()
{
if (m_needsDistributionRecalc)
@@ -217,80 +212,68 @@ void ElementShadow::setNeedsDistributionRecalc()
clearDistribution();
}
-bool ElementShadow::didAffectApplyAuthorStyles()
+bool ElementShadow::hasSameStyles(const ElementShadow* other) const
{
- bool applyAuthorStyles = resolveApplyAuthorStyles();
-
- if (m_applyAuthorStyles == applyAuthorStyles)
- return false;
+ ShadowRoot* root = youngestShadowRoot();
+ ShadowRoot* otherRoot = other->youngestShadowRoot();
+ while (root || otherRoot) {
+ if (!root || !otherRoot)
+ return false;
- m_applyAuthorStyles = applyAuthorStyles;
- return true;
-}
+ StyleSheetList* list = root->styleSheets();
+ StyleSheetList* otherList = otherRoot->styleSheets();
-bool ElementShadow::containsActiveStyles() const
-{
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- if (root->hasScopedHTMLStyleChild())
- return true;
- if (!root->containsShadowElements())
+ if (list->length() != otherList->length())
return false;
- }
- return false;
-}
-bool ElementShadow::resolveApplyAuthorStyles() const
-{
- for (const ShadowRoot* shadowRoot = youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
- if (shadowRoot->applyAuthorStyles())
- return true;
- if (!shadowRoot->containsShadowElements())
- break;
+ for (size_t i = 0; i < list->length(); i++) {
+ if (toCSSStyleSheet(list->item(i))->contents() != toCSSStyleSheet(otherList->item(i))->contents())
+ return false;
+ }
+ root = root->olderShadowRoot();
+ otherRoot = otherRoot->olderShadowRoot();
}
- return false;
+
+ return true;
}
const InsertionPoint* ElementShadow::finalDestinationInsertionPointFor(const Node* key) const
{
+ ASSERT(key && !key->document().childNeedsDistributionRecalc());
NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
return it == m_nodeToInsertionPoints.end() ? 0: it->value.last().get();
}
const DestinationInsertionPoints* ElementShadow::destinationInsertionPointsFor(const Node* key) const
{
+ ASSERT(key && !key->document().childNeedsDistributionRecalc());
NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
return it == m_nodeToInsertionPoints.end() ? 0: &it->value;
}
void ElementShadow::distribute()
{
- host()->setNeedsStyleRecalc();
+ host()->setNeedsStyleRecalc(SubtreeStyleChange);
Vector<HTMLShadowElement*, 32> shadowInsertionPoints;
DistributionPool pool(*host());
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
HTMLShadowElement* shadowInsertionPoint = 0;
- const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* point = insertionPoints[i].get();
if (!point->isActive())
continue;
- if (isHTMLShadowElement(point)) {
- if (!shadowInsertionPoint)
- shadowInsertionPoint = toHTMLShadowElement(point);
+ if (isHTMLShadowElement(*point)) {
+ ASSERT(!shadowInsertionPoint);
+ shadowInsertionPoint = toHTMLShadowElement(point);
+ shadowInsertionPoints.append(shadowInsertionPoint);
} else {
pool.distributeTo(point, this);
if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*point))
shadow->setNeedsDistributionRecalc();
}
}
- if (shadowInsertionPoint) {
- shadowInsertionPoints.append(shadowInsertionPoint);
- if (shadowInsertionPoint->hasChildNodes())
- pool.populateChildren(*shadowInsertionPoint);
- } else {
- pool.clear();
- }
}
for (size_t i = shadowInsertionPoints.size(); i > 0; --i) {
@@ -314,7 +297,7 @@ void ElementShadow::distribute()
void ElementShadow::didDistributeNode(const Node* node, InsertionPoint* insertionPoint)
{
NodeToDestinationInsertionPoints::AddResult result = m_nodeToInsertionPoints.add(node, DestinationInsertionPoints());
- result.iterator->value.append(insertionPoint);
+ result.storedValue->value.append(insertionPoint);
}
const SelectRuleFeatureSet& ElementShadow::ensureSelectFeatureSet()
@@ -337,12 +320,12 @@ void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot& root)
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) {
if (ElementShadow* shadow = element->shadow())
m_selectFeatures.add(shadow->ensureSelectFeatureSet());
- if (!isHTMLContentElement(element))
+ if (!isHTMLContentElement(*element))
continue;
- const CSSSelectorList& list = toHTMLContentElement(element)->selectorList();
- for (const CSSSelector* selector = list.first(); selector; selector = CSSSelectorList::next(selector)) {
+ const CSSSelectorList& list = toHTMLContentElement(*element).selectorList();
+ for (const CSSSelector* selector = list.first(); selector; selector = CSSSelectorList::next(*selector)) {
for (const CSSSelector* component = selector; component; component = component->tagHistory())
- m_selectFeatures.collectFeaturesFromSelector(component);
+ m_selectFeatures.collectFeaturesFromSelector(*component);
}
}
}
@@ -368,7 +351,17 @@ void ElementShadow::clearDistribution()
m_nodeToInsertionPoints.clear();
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
- root->setShadowInsertionPointOfYoungerShadowRoot(0);
+ root->setShadowInsertionPointOfYoungerShadowRoot(nullptr);
+}
+
+void ElementShadow::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodeToInsertionPoints);
+ visitor->trace(m_selectFeatures);
+ // Shadow roots are linked with previous and next pointers which are traced.
+ // It is therefore enough to trace one of the shadow roots here and the
+ // rest will be traced from there.
+ visitor->trace(m_shadowRoots.head());
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
index 9017ddcafb7..870f89e2006 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
@@ -30,19 +30,19 @@
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/SelectRuleFeatureSet.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "platform/heap/Handle.h"
#include "wtf/DoublyLinkedList.h"
-#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
namespace WebCore {
-class ElementShadow {
- WTF_MAKE_NONCOPYABLE(ElementShadow); WTF_MAKE_FAST_ALLOCATED;
+class ElementShadow FINAL : public NoBaseWillBeGarbageCollectedFinalized<ElementShadow> {
+ WTF_MAKE_NONCOPYABLE(ElementShadow);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ElementShadow> create();
+ static PassOwnPtrWillBeRawPtr<ElementShadow> create();
~ElementShadow();
Element* host() const;
@@ -52,15 +52,11 @@ public:
ShadowRoot& addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType);
- bool applyAuthorStyles() const { return m_applyAuthorStyles; }
- bool didAffectApplyAuthorStyles();
- bool containsActiveStyles() const;
+ bool hasSameStyles(const ElementShadow*) const;
void attach(const Node::AttachContext&);
void detach(const Node::AttachContext&);
- void removeAllEventListeners();
-
void didAffectSelector(AffectedSelectorMask);
void willAffectSelector();
const SelectRuleFeatureSet& ensureSelectFeatureSet();
@@ -73,11 +69,14 @@ public:
void didDistributeNode(const Node*, InsertionPoint*);
+ void trace(Visitor*);
+
private:
ElementShadow();
- void removeAllShadowRoots();
- bool resolveApplyAuthorStyles() const;
+#if !ENABLE(OILPAN)
+ void removeDetachedShadowRoots();
+#endif
void distribute();
void clearDistribution();
@@ -88,13 +87,13 @@ private:
bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; }
void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; }
- typedef HashMap<const Node*, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<const Node>, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
NodeToDestinationInsertionPoints m_nodeToInsertionPoints;
SelectRuleFeatureSet m_selectFeatures;
+ // FIXME: Oilpan: add a heap-based version of DoublyLinkedList<>.
DoublyLinkedList<ShadowRoot> m_shadowRoots;
bool m_needsDistributionRecalc;
- bool m_applyAuthorStyles;
bool m_needsSelectFeatureSet;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp
index e3c5d4df9fc..e6b5b63bcf4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp
@@ -31,13 +31,11 @@
#include "config.h"
#include "core/dom/shadow/InsertionPoint.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/QualifiedName.h"
#include "core/dom/StaticNodeList.h"
#include "core/dom/shadow/ElementShadow.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
namespace WebCore {
@@ -100,7 +98,7 @@ void InsertionPoint::setDistribution(ContentDistribution& distribution)
void InsertionPoint::attach(const AttachContext& context)
{
// We need to attach the distribution here so that they're inserted in the right order
- // otherwise the n^2 protection inside NodeRenderingContext will cause them to be
+ // otherwise the n^2 protection inside RenderTreeBuilder will cause them to be
// inserted in the wrong place later. This also lets distributed nodes benefit from
// the n^2 protection.
for (size_t i = 0; i < m_distribution.size(); ++i) {
@@ -124,7 +122,7 @@ void InsertionPoint::willRecalcStyle(StyleRecalcChange change)
if (change < Inherit)
return;
for (size_t i = 0; i < m_distribution.size(); ++i)
- m_distribution.at(i)->setNeedsStyleRecalc(LocalStyleChange);
+ m_distribution.at(i)->setNeedsStyleRecalc(SubtreeStyleChange);
}
bool InsertionPoint::shouldUseFallbackElements() const
@@ -136,16 +134,9 @@ bool InsertionPoint::canBeActive() const
{
if (!isInShadowTree())
return false;
- bool foundShadowElementInAncestors = false;
- bool thisIsContentHTMLElement = isHTMLContentElement(this);
for (Node* node = parentNode(); node; node = node->parentNode()) {
- if (node->isInsertionPoint()) {
- // For HTMLContentElement, at most one HTMLShadowElement may appear in its ancestors.
- if (thisIsContentHTMLElement && isHTMLShadowElement(node) && !foundShadowElementInAncestors)
- foundShadowElementInAncestors = true;
- else
- return false;
- }
+ if (node->isInsertionPoint())
+ return false;
}
return true;
}
@@ -155,15 +146,16 @@ bool InsertionPoint::isActive() const
if (!canBeActive())
return false;
ShadowRoot* shadowRoot = containingShadowRoot();
- ASSERT(shadowRoot);
- if (!isHTMLShadowElement(this) || shadowRoot->descendantShadowElementCount() <= 1)
+ if (!shadowRoot)
+ return false;
+ if (!isHTMLShadowElement(*this) || shadowRoot->descendantShadowElementCount() <= 1)
return true;
// Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case.
- const Vector<RefPtr<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* point = insertionPoints[i].get();
- if (isHTMLShadowElement(point))
+ if (isHTMLShadowElement(*point))
return point == this;
}
return true;
@@ -171,19 +163,19 @@ bool InsertionPoint::isActive() const
bool InsertionPoint::isShadowInsertionPoint() const
{
- return isHTMLShadowElement(this) && isActive();
+ return isHTMLShadowElement(*this) && isActive();
}
bool InsertionPoint::isContentInsertionPoint() const
{
- return isHTMLContentElement(this) && isActive();
+ return isHTMLContentElement(*this) && isActive();
}
-PassRefPtr<NodeList> InsertionPoint::getDistributedNodes()
+PassRefPtrWillBeRawPtr<StaticNodeList> InsertionPoint::getDistributedNodes()
{
document().updateDistributionForNodeIfNeeded(this);
- Vector<RefPtr<Node> > nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
nodes.reserveInitialCapacity(m_distribution.size());
for (size_t i = 0; i < m_distribution.size(); ++i)
nodes.uncheckedAppend(m_distribution.at(i));
@@ -214,7 +206,6 @@ Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* i
if (canBeActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
m_registeredWithShadowRoot = true;
root->didAddInsertionPoint(this);
- rootOwner->didAffectApplyAuthorStyles();
if (canAffectSelector())
rootOwner->willAffectSelector();
}
@@ -246,7 +237,6 @@ void InsertionPoint::removedFrom(ContainerNode* insertionPoint)
m_registeredWithShadowRoot = false;
root->didRemoveInsertionPoint(this);
if (rootOwner) {
- rootOwner->didAffectApplyAuthorStyles();
if (canAffectSelector())
rootOwner->willAffectSelector();
}
@@ -255,24 +245,10 @@ void InsertionPoint::removedFrom(ContainerNode* insertionPoint)
HTMLElement::removedFrom(insertionPoint);
}
-void InsertionPoint::parseAttribute(const QualifiedName& name, const AtomicString& value)
-{
- if (name == reset_style_inheritanceAttr) {
- if (!inDocument() || !isActive())
- return;
- containingShadowRoot()->host()->setNeedsStyleRecalc();
- } else
- HTMLElement::parseAttribute(name, value);
-}
-
-bool InsertionPoint::resetStyleInheritance() const
-{
- return fastHasAttribute(reset_style_inheritanceAttr);
-}
-
-void InsertionPoint::setResetStyleInheritance(bool value)
+void InsertionPoint::trace(Visitor* visitor)
{
- setBooleanAttribute(reset_style_inheritanceAttr, value);
+ visitor->trace(m_distribution);
+ HTMLElement::trace(visitor);
}
const InsertionPoint* resolveReprojection(const Node* projectedNode)
@@ -296,7 +272,7 @@ const InsertionPoint* resolveReprojection(const Node* projectedNode)
return insertionPoint;
}
-void collectDestinationInsertionPoints(const Node& node, Vector<InsertionPoint*, 8>& results)
+void collectDestinationInsertionPoints(const Node& node, WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8>& results)
{
const Node* current = &node;
ElementShadow* lastElementShadow = 0;
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h
index 05f2ac9e070..43e0277261b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h
@@ -35,7 +35,6 @@
#include "core/dom/shadow/ContentDistribution.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLElement.h"
-#include "wtf/Forward.h"
namespace WebCore {
@@ -52,13 +51,10 @@ public:
bool isShadowInsertionPoint() const;
bool isContentInsertionPoint() const;
- PassRefPtr<NodeList> getDistributedNodes();
+ PassRefPtrWillBeRawPtr<StaticNodeList> getDistributedNodes();
virtual bool canAffectSelector() const { return false; }
- bool resetStyleInheritance() const;
- void setResetStyleInheritance(bool);
-
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
@@ -71,13 +67,14 @@ public:
Node* nextTo(const Node* node) const { return m_distribution.nextTo(node); }
Node* previousTo(const Node* node) const { return m_distribution.previousTo(node); }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
InsertionPoint(const QualifiedName&, Document&);
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
private:
@@ -85,9 +82,9 @@ private:
bool m_registeredWithShadowRoot;
};
-typedef Vector<RefPtr<InsertionPoint> > DestinationInsertionPoints;
+typedef WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> > DestinationInsertionPoints;
-DEFINE_NODE_TYPE_CASTS(InsertionPoint, isInsertionPoint());
+DEFINE_ELEMENT_TYPE_CASTS(InsertionPoint, isInsertionPoint());
inline bool isActiveInsertionPoint(const Node& node)
{
@@ -115,7 +112,7 @@ inline ElementShadow* shadowWhereNodeCanBeDistributed(const Node& node)
const InsertionPoint* resolveReprojection(const Node*);
-void collectDestinationInsertionPoints(const Node&, Vector<InsertionPoint*, 8>& results);
+void collectDestinationInsertionPoints(const Node&, WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8>& results);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp
index 4f6f52668ef..25757e6bc74 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp
@@ -33,6 +33,8 @@
#include "core/css/CSSSelector.h"
+#include "wtf/BitVector.h"
+
namespace WebCore {
SelectRuleFeatureSet::SelectRuleFeatureSet()
@@ -52,11 +54,11 @@ void SelectRuleFeatureSet::clear()
m_featureFlags = 0;
}
-void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector* selector)
+void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector)
{
m_cssRuleFeatureSet.collectFeaturesFromSelector(selector);
- switch (selector->pseudoType()) {
+ switch (selector.pseudoType()) {
case CSSSelector::PseudoChecked:
setSelectRuleFeature(AffectedSelectorChecked);
break;
@@ -83,5 +85,53 @@ void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector* select
}
}
+bool SelectRuleFeatureSet::checkSelectorsForClassChange(const SpaceSplitString& changedClasses) const
+{
+ unsigned changedSize = changedClasses.size();
+ for (unsigned i = 0; i < changedSize; ++i) {
+ if (hasSelectorForClass(changedClasses[i]))
+ return true;
+ }
+ return false;
+}
+
+bool SelectRuleFeatureSet::checkSelectorsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses) const
+{
+ if (!oldClasses.size())
+ return checkSelectorsForClassChange(newClasses);
+
+ // Class vectors tend to be very short. This is faster than using a hash table.
+ BitVector remainingClassBits;
+ remainingClassBits.ensureSize(oldClasses.size());
+
+ for (unsigned i = 0; i < newClasses.size(); ++i) {
+ bool found = false;
+ for (unsigned j = 0; j < oldClasses.size(); ++j) {
+ if (newClasses[i] == oldClasses[j]) {
+ // Mark each class that is still in the newClasses so we can skip doing
+ // an n^2 search below when looking for removals. We can't break from
+ // this loop early since a class can appear more than once.
+ remainingClassBits.quickSet(j);
+ found = true;
+ }
+ }
+ // Class was added.
+ if (!found) {
+ if (hasSelectorForClass(newClasses[i]))
+ return true;
+ }
+ }
+
+ for (unsigned i = 0; i < oldClasses.size(); ++i) {
+ if (remainingClassBits.quickGet(i))
+ continue;
+
+ // Class was removed.
+ if (hasSelectorForClass(oldClasses[i]))
+ return true;
+ }
+ return false;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h
index 429d2777699..ad47b1b7e88 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h
@@ -36,13 +36,17 @@
namespace WebCore {
+class Element;
+class SpaceSplitString;
+
class SelectRuleFeatureSet {
+ DISALLOW_ALLOCATION();
public:
SelectRuleFeatureSet();
void add(const SelectRuleFeatureSet&);
void clear();
- void collectFeaturesFromSelector(const CSSSelector*);
+ void collectFeaturesFromSelector(const CSSSelector&);
bool hasSelectorForId(const AtomicString&) const;
bool hasSelectorForClass(const AtomicString&) const;
@@ -58,6 +62,11 @@ public:
bool hasSelectorFor(AffectedSelectorMask features) const { return m_featureFlags & features; }
+ bool checkSelectorsForClassChange(const SpaceSplitString& changedClasses) const;
+ bool checkSelectorsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses) const;
+
+ void trace(Visitor* visitor) { visitor->trace(m_cssRuleFeatureSet); }
+
private:
void setSelectRuleFeature(AffectedSelectorType feature) { m_featureFlags |= feature; }
@@ -68,19 +77,19 @@ private:
inline bool SelectRuleFeatureSet::hasSelectorForId(const AtomicString& idValue) const
{
ASSERT(!idValue.isEmpty());
- return m_cssRuleFeatureSet.idsInRules.contains(idValue);
+ return m_cssRuleFeatureSet.hasSelectorForId(idValue);
}
inline bool SelectRuleFeatureSet::hasSelectorForClass(const AtomicString& classValue) const
{
ASSERT(!classValue.isEmpty());
- return m_cssRuleFeatureSet.classesInRules.contains(classValue);
+ return m_cssRuleFeatureSet.hasSelectorForClass(classValue);
}
inline bool SelectRuleFeatureSet::hasSelectorForAttribute(const AtomicString& attributeName) const
{
ASSERT(!attributeName.isEmpty());
- return m_cssRuleFeatureSet.attrsInRules.contains(attributeName);
+ return m_cssRuleFeatureSet.hasSelectorForAttribute(attributeName);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
index c9f7909eae3..60ad13145f7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
@@ -30,6 +30,7 @@
#include "bindings/v8/ExceptionState.h"
#include "core/css/StyleSheetList.h"
#include "core/css/resolver/StyleResolver.h"
+#include "core/css/resolver/StyleResolverParentScope.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/Text.h"
@@ -37,6 +38,7 @@
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRootRareData.h"
#include "core/editing/markup.h"
+#include "core/html/HTMLShadowElement.h"
#include "public/platform/Platform.h"
namespace WebCore {
@@ -48,42 +50,29 @@ struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope, public
COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_should_stay_small);
-enum ShadowRootUsageOriginType {
- ShadowRootUsageOriginWeb = 0,
- ShadowRootUsageOriginNotWeb,
- ShadowRootUsageOriginMax
-};
-
-ShadowRoot::ShadowRoot(Document* document, ShadowRootType type)
+ShadowRoot::ShadowRoot(Document& document, ShadowRootType type)
: DocumentFragment(0, CreateShadowRoot)
- , TreeScope(this, document)
- , m_prev(0)
- , m_next(0)
+ , TreeScope(*this, document)
+ , m_prev(nullptr)
+ , m_next(nullptr)
, m_numberOfStyles(0)
- , m_applyAuthorStyles(false)
- , m_resetStyleInheritance(false)
, m_type(type)
, m_registeredWithParentShadowRoot(false)
, m_descendantInsertionPointsIsValid(false)
{
- ASSERT(document);
ScriptWrappable::init(this);
-
- if (type == ShadowRoot::AuthorShadowRoot) {
- ShadowRootUsageOriginType usageType = document->url().protocolIsInHTTPFamily() ? ShadowRootUsageOriginWeb : ShadowRootUsageOriginNotWeb;
- blink::Platform::current()->histogramEnumeration("WebCore.ShadowRoot.constructor", usageType, ShadowRootUsageOriginMax);
- }
}
ShadowRoot::~ShadowRoot()
{
+#if !ENABLE(OILPAN)
ASSERT(!m_prev);
ASSERT(!m_next);
if (m_shadowRootRareData && m_shadowRootRareData->styleSheets())
m_shadowRootRareData->styleSheets()->detachFromDocument();
- documentInternal()->styleEngine()->didRemoveShadowRoot(this);
+ document().styleEngine()->didRemoveShadowRoot(this);
// We cannot let ContainerNode destructor call willBeDeletedFromDocument()
// for this ShadowRoot instance because TreeScope destructor
@@ -100,14 +89,17 @@ ShadowRoot::~ShadowRoot()
// as well as Node. See a comment on TreeScope.h for the reason.
if (hasRareData())
clearRareData();
+#endif
}
+#if !ENABLE(OILPAN)
void ShadowRoot::dispose()
{
removeDetachedChildren();
}
+#endif
-ShadowRoot* ShadowRoot::bindingsOlderShadowRoot() const
+ShadowRoot* ShadowRoot::olderShadowRootForBindings() const
{
ShadowRoot* older = olderShadowRoot();
while (older && !older->shouldExposeToBindings())
@@ -116,19 +108,10 @@ ShadowRoot* ShadowRoot::bindingsOlderShadowRoot() const
return older;
}
-bool ShadowRoot::isOldestAuthorShadowRoot() const
-{
- if (type() != AuthorShadowRoot)
- return false;
- if (ShadowRoot* older = olderShadowRoot())
- return older->type() == UserAgentShadowRoot;
- return true;
-}
-
-PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& exceptionState)
{
exceptionState.throwDOMException(DataCloneError, "ShadowRoot nodes are not clonable.");
- return 0;
+ return nullptr;
}
String ShadowRoot::innerHTML() const
@@ -143,35 +126,23 @@ void ShadowRoot::setInnerHTML(const String& markup, ExceptionState& exceptionSta
return;
}
- if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, "innerHTML", exceptionState))
+ if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, "innerHTML", exceptionState))
replaceChildrenWithFragment(this, fragment.release(), exceptionState);
}
-bool ShadowRoot::childTypeAllowed(NodeType type) const
-{
- switch (type) {
- case ELEMENT_NODE:
- case PROCESSING_INSTRUCTION_NODE:
- case COMMENT_NODE:
- case TEXT_NODE:
- case CDATA_SECTION_NODE:
- return true;
- default:
- return false;
- }
-}
-
void ShadowRoot::recalcStyle(StyleRecalcChange change)
{
// ShadowRoot doesn't support custom callbacks.
ASSERT(!hasCustomStyleCallbacks());
- StyleResolver& styleResolver = document().ensureStyleResolver();
- styleResolver.pushParentShadowRoot(*this);
+ StyleResolverParentScope parentScope(*this);
if (styleChangeType() >= SubtreeStyleChange)
change = Force;
+ if (change < Force && hasRareData() && childNeedsStyleRecalc())
+ checkForChildrenAdjacentRuleChanges();
+
// There's no style to update so just calling recalcStyle means we're updated.
clearNeedsStyleRecalc();
@@ -182,73 +153,20 @@ void ShadowRoot::recalcStyle(StyleRecalcChange change)
toText(child)->recalcTextStyle(change, lastTextNode);
lastTextNode = toText(child);
} else if (child->isElementNode()) {
- if (shouldRecalcStyle(change, child))
+ if (child->shouldCallRecalcStyle(change))
toElement(child)->recalcStyle(change, lastTextNode);
if (child->renderer())
lastTextNode = 0;
}
}
- styleResolver.popParentShadowRoot(*this);
-
clearChildNeedsStyleRecalc();
}
-bool ShadowRoot::isActive() const
-{
- for (ShadowRoot* shadowRoot = youngerShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot())
- if (!shadowRoot->containsShadowElements())
- return false;
- return true;
-}
-
-void ShadowRoot::setApplyAuthorStyles(bool value)
-{
- if (isOrphan())
- return;
-
- if (applyAuthorStyles() == value)
- return;
-
- m_applyAuthorStyles = value;
- if (!isActive())
- return;
-
- ASSERT(host());
- ASSERT(host()->shadow());
- if (host()->shadow()->didAffectApplyAuthorStyles())
- host()->setNeedsStyleRecalc();
-
- // Since styles in shadow trees can select shadow hosts, set shadow host's needs-recalc flag true.
- // FIXME: host->setNeedsStyleRecalc() should take care of all elements in its shadow tree.
- // However, when host's recalcStyle is skipped (i.e. host's parent has no renderer),
- // no recalc style is invoked for any elements in its shadow tree.
- // This problem occurs when using getComputedStyle() API.
- // So currently host and shadow root's needsStyleRecalc flags are set to be true.
- setNeedsStyleRecalc();
-}
-
-void ShadowRoot::setResetStyleInheritance(bool value)
-{
- if (isOrphan())
- return;
-
- if (value == resetStyleInheritance())
- return;
-
- m_resetStyleInheritance = value;
- if (!isActive())
- return;
-
- setNeedsStyleRecalc();
-}
-
void ShadowRoot::attach(const AttachContext& context)
{
- StyleResolver& styleResolver = document().ensureStyleResolver();
- styleResolver.pushParentShadowRoot(*this);
+ StyleResolverParentScope parentScope(*this);
DocumentFragment::attach(context);
- styleResolver.popParentShadowRoot(*this);
}
Node::InsertionNotificationRequest ShadowRoot::insertedInto(ContainerNode* insertionPoint)
@@ -289,6 +207,9 @@ void ShadowRoot::removedFrom(ContainerNode* insertionPoint)
void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+
+ checkForSiblingStyleChanges(false, beforeChange, afterChange, childCountDelta);
+
if (InsertionPoint* point = shadowInsertionPointOfYoungerShadowRoot()) {
if (ShadowRoot* root = point->containingShadowRoot())
root->owner()->setNeedsDistributionRecalc();
@@ -298,14 +219,12 @@ void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node*
void ShadowRoot::registerScopedHTMLStyleChild()
{
++m_numberOfStyles;
- setHasScopedHTMLStyleChild(true);
}
void ShadowRoot::unregisterScopedHTMLStyleChild()
{
- ASSERT(hasScopedHTMLStyleChild() && m_numberOfStyles > 0);
+ ASSERT(m_numberOfStyles > 0);
--m_numberOfStyles;
- setHasScopedHTMLStyleChild(m_numberOfStyles > 0);
}
ShadowRootRareData* ShadowRoot::ensureShadowRootRareData()
@@ -313,7 +232,7 @@ ShadowRootRareData* ShadowRoot::ensureShadowRootRareData()
if (m_shadowRootRareData)
return m_shadowRootRareData.get();
- m_shadowRootRareData = adoptPtr(new ShadowRootRareData);
+ m_shadowRootRareData = adoptPtrWillBeNoop(new ShadowRootRareData);
return m_shadowRootRareData.get();
}
@@ -342,7 +261,7 @@ HTMLShadowElement* ShadowRoot::shadowInsertionPointOfYoungerShadowRoot() const
return m_shadowRootRareData ? m_shadowRootRareData->shadowInsertionPointOfYoungerShadowRoot() : 0;
}
-void ShadowRoot::setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint)
+void ShadowRoot::setShadowInsertionPointOfYoungerShadowRoot(PassRefPtrWillBeRawPtr<HTMLShadowElement> shadowInsertionPoint)
{
if (!m_shadowRootRareData && !shadowInsertionPoint)
return;
@@ -385,10 +304,9 @@ void ShadowRoot::invalidateDescendantInsertionPoints()
m_shadowRootRareData->clearDescendantInsertionPoints();
}
-const Vector<RefPtr<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
+const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
{
- DEFINE_STATIC_LOCAL(const Vector<RefPtr<InsertionPoint> >, emptyList, ());
-
+ DEFINE_STATIC_LOCAL(WillBePersistentHeapVector<RefPtrWillBeMember<InsertionPoint> >, emptyList, ());
if (m_shadowRootRareData && m_descendantInsertionPointsIsValid)
return m_shadowRootRareData->descendantInsertionPoints();
@@ -397,7 +315,7 @@ const Vector<RefPtr<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
if (!containsInsertionPoints())
return emptyList;
- Vector<RefPtr<InsertionPoint> > insertionPoints;
+ WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> > insertionPoints;
for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
if (element->isInsertionPoint())
insertionPoints.append(toInsertionPoint(element));
@@ -416,4 +334,13 @@ StyleSheetList* ShadowRoot::styleSheets()
return m_shadowRootRareData->styleSheets();
}
+void ShadowRoot::trace(Visitor* visitor)
+{
+ visitor->trace(m_prev);
+ visitor->trace(m_next);
+ visitor->trace(m_shadowRootRareData);
+ TreeScope::trace(visitor);
+ DocumentFragment::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
index 62fd4238ad1..97d54a61074 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
@@ -43,6 +43,7 @@ class InsertionPoint;
class ShadowRootRareData;
class ShadowRoot FINAL : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot);
friend class WTF::DoublyLinkedListNode<ShadowRoot>;
public:
// FIXME: We will support multiple shadow subtrees, however current implementation does not work well
@@ -54,19 +55,23 @@ public:
AuthorShadowRoot
};
- static PassRefPtr<ShadowRoot> create(Document* document, ShadowRootType type)
+ static PassRefPtrWillBeRawPtr<ShadowRoot> create(Document& document, ShadowRootType type)
{
- return adoptRef(new ShadowRoot(document, type));
+ return adoptRefWillBeNoop(new ShadowRoot(document, type));
}
void recalcStyle(StyleRecalcChange);
+ // Disambiguate between Node and TreeScope hierarchies; TreeScope's implementation is simpler.
+ using TreeScope::document;
+ using TreeScope::getElementById;
+
Element* host() const { return toElement(parentOrShadowHostNode()); }
ElementShadow* owner() const { return host() ? host()->shadow() : 0; }
ShadowRoot* youngerShadowRoot() const { return prev(); }
- ShadowRoot* bindingsOlderShadowRoot() const;
+ ShadowRoot* olderShadowRootForBindings() const;
bool shouldExposeToBindings() const { return type() == AuthorShadowRoot; }
bool isYoungest() const { return !youngerShadowRoot(); }
@@ -78,8 +83,8 @@ public:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void registerScopedHTMLStyleChild() OVERRIDE;
- virtual void unregisterScopedHTMLStyleChild() OVERRIDE;
+ void registerScopedHTMLStyleChild();
+ void unregisterScopedHTMLStyleChild();
bool containsShadowElements() const;
bool containsContentElements() const;
@@ -90,41 +95,44 @@ public:
// For Internals, don't use this.
unsigned childShadowRootCount() const;
+ unsigned numberOfStyles() const { return m_numberOfStyles; }
HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const;
- void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement>);
+ void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtrWillBeRawPtr<HTMLShadowElement>);
void didAddInsertionPoint(InsertionPoint*);
void didRemoveInsertionPoint(InsertionPoint*);
- const Vector<RefPtr<InsertionPoint> >& descendantInsertionPoints();
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& descendantInsertionPoints();
ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
+ // Make protected methods from base class public here.
+ using TreeScope::setDocument;
+ using TreeScope::setParentTreeScope;
+
public:
Element* activeElement() const;
- bool applyAuthorStyles() const { return m_applyAuthorStyles; }
- void setApplyAuthorStyles(bool);
-
- bool resetStyleInheritance() const { return m_resetStyleInheritance; }
- void setResetStyleInheritance(bool);
-
ShadowRoot* olderShadowRoot() const { return next(); }
String innerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
- PassRefPtr<Node> cloneNode(bool, ExceptionState&);
- PassRefPtr<Node> cloneNode(ExceptionState& exceptionState) { return cloneNode(true, exceptionState); }
+ PassRefPtrWillBeRawPtr<Node> cloneNode(bool, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> cloneNode(ExceptionState& exceptionState) { return cloneNode(true, exceptionState); }
StyleSheetList* styleSheets();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ShadowRoot(Document*, ShadowRootType);
+ ShadowRoot(Document&, ShadowRootType);
virtual ~ShadowRoot();
+#if !ENABLE(OILPAN)
virtual void dispose() OVERRIDE;
- virtual bool childTypeAllowed(NodeType) const OVERRIDE;
+#endif
+
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
ShadowRootRareData* ensureShadowRootRareData();
@@ -134,18 +142,15 @@ private:
void invalidateDescendantInsertionPoints();
// ShadowRoots should never be cloned.
- virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; }
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool) OVERRIDE { return nullptr; }
// FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
bool isOrphan() const { return !host(); }
- bool isActive() const;
- ShadowRoot* m_prev;
- ShadowRoot* m_next;
- OwnPtr<ShadowRootRareData> m_shadowRootRareData;
+ RawPtrWillBeMember<ShadowRoot> m_prev;
+ RawPtrWillBeMember<ShadowRoot> m_next;
+ OwnPtrWillBeMember<ShadowRootRareData> m_shadowRootRareData;
unsigned m_numberOfStyles : 27;
- unsigned m_applyAuthorStyles : 1;
- unsigned m_resetStyleInheritance : 1;
unsigned m_type : 1;
unsigned m_registeredWithParentShadowRoot : 1;
unsigned m_descendantInsertionPointsIsValid : 1;
@@ -157,7 +162,7 @@ inline Element* ShadowRoot::activeElement() const
}
DEFINE_NODE_TYPE_CASTS(ShadowRoot, isShadowRoot());
-DEFINE_TYPE_CASTS(ShadowRoot, TreeScope, treeScope, treeScope->rootNode() && treeScope->rootNode()->isShadowRoot(), treeScope.rootNode() && treeScope.rootNode()->isShadowRoot());
+DEFINE_TYPE_CASTS(ShadowRoot, TreeScope, treeScope, treeScope->rootNode().isShadowRoot(), treeScope.rootNode().isShadowRoot());
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
index c84d177cba2..c7d26bb06b8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
@@ -24,27 +24,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject
-] interface ShadowRoot : DocumentFragment {
+interface ShadowRoot : DocumentFragment {
readonly attribute Element activeElement;
- attribute boolean applyAuthorStyles;
- attribute boolean resetStyleInheritance;
- [RuntimeEnabled=ShadowDOM, ImplementedAs=bindingsOlderShadowRoot] readonly attribute ShadowRoot olderShadowRoot;
- [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, RaisesException=Setter] attribute DOMString innerHTML;
+ [ImplementedAs=olderShadowRootForBindings] readonly attribute ShadowRoot olderShadowRoot;
+
+ [TreatNullAs=NullString, CustomElementCallbacks, LogActivity=SetterOnly, RaisesException=Setter] attribute DOMString innerHTML;
[RaisesException] Node cloneNode([Default=Undefined] optional boolean deep);
Selection getSelection();
Element getElementById([Default=Undefined] optional DOMString elementId);
- NodeList getElementsByClassName([Default=Undefined] optional DOMString className);
- NodeList getElementsByTagName([Default=Undefined] optional DOMString tagName);
- NodeList getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
- [Default=Undefined] optional DOMString localName);
+ HTMLCollection getElementsByClassName([Default=Undefined] optional DOMString className);
+ HTMLCollection getElementsByTagName([Default=Undefined] optional DOMString tagName);
+ HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+ [Default=Undefined] optional DOMString localName);
Element elementFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
- [RuntimeEnabled=ShadowDOM] readonly attribute StyleSheetList styleSheets;
- [RuntimeEnabled=ShadowDOM] readonly attribute Element host;
+ readonly attribute StyleSheetList styleSheets;
+ readonly attribute Element host;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
index dae72a7837c..abe5fbc5110 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
@@ -32,14 +32,12 @@
#define ShadowRootRareData_h
#include "core/dom/shadow/InsertionPoint.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
-class ShadowRootRareData {
+class ShadowRootRareData : public NoBaseWillBeGarbageCollected<ShadowRootRareData> {
public:
ShadowRootRareData()
: m_descendantShadowElementCount(0)
@@ -49,7 +47,7 @@ public:
}
HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const { return m_shadowInsertionPointOfYoungerShadowRoot.get(); }
- void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint) { m_shadowInsertionPointOfYoungerShadowRoot = shadowInsertionPoint; }
+ void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtrWillBeRawPtr<HTMLShadowElement> shadowInsertionPoint) { m_shadowInsertionPointOfYoungerShadowRoot = shadowInsertionPoint; }
void didAddInsertionPoint(InsertionPoint*);
void didRemoveInsertionPoint(InsertionPoint*);
@@ -65,27 +63,35 @@ public:
unsigned childShadowRootCount() const { return m_childShadowRootCount; }
- const Vector<RefPtr<InsertionPoint> >& descendantInsertionPoints() { return m_descendantInsertionPoints; }
- void setDescendantInsertionPoints(Vector<RefPtr<InsertionPoint> >& list) { m_descendantInsertionPoints.swap(list); }
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& descendantInsertionPoints() { return m_descendantInsertionPoints; }
+ void setDescendantInsertionPoints(WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& list) { m_descendantInsertionPoints.swap(list); }
void clearDescendantInsertionPoints() { m_descendantInsertionPoints.clear(); }
StyleSheetList* styleSheets() { return m_styleSheetList.get(); }
- void setStyleSheets(PassRefPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
+ void setStyleSheets(PassRefPtrWillBeRawPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_shadowInsertionPointOfYoungerShadowRoot);
+ visitor->trace(m_descendantInsertionPoints);
+ visitor->trace(m_styleSheetList);
+ }
private:
- RefPtr<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
+ RefPtrWillBeMember<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
unsigned m_descendantShadowElementCount;
unsigned m_descendantContentElementCount;
unsigned m_childShadowRootCount;
- Vector<RefPtr<InsertionPoint> > m_descendantInsertionPoints;
- RefPtr<StyleSheetList> m_styleSheetList;
+ WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> > m_descendantInsertionPoints;
+ RefPtrWillBeMember<StyleSheetList> m_styleSheetList;
};
inline void ShadowRootRareData::didAddInsertionPoint(InsertionPoint* point)
{
- if (isHTMLShadowElement(point))
+ ASSERT(point);
+ if (isHTMLShadowElement(*point))
++m_descendantShadowElementCount;
- else if (isHTMLContentElement(point))
+ else if (isHTMLContentElement(*point))
++m_descendantContentElementCount;
else
ASSERT_NOT_REACHED();
@@ -93,9 +99,10 @@ inline void ShadowRootRareData::didAddInsertionPoint(InsertionPoint* point)
inline void ShadowRootRareData::didRemoveInsertionPoint(InsertionPoint* point)
{
- if (isHTMLShadowElement(point))
+ ASSERT(point);
+ if (isHTMLShadowElement(*point))
--m_descendantShadowElementCount;
- else if (isHTMLContentElement(point))
+ else if (isHTMLContentElement(*point))
--m_descendantContentElementCount;
else
ASSERT_NOT_REACHED();