Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / dom / Document.cpp
index 8eccef9..5f5f33c 100644 (file)
 #include "config.h"
 #include "core/dom/Document.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 "bindings/core/v8/CustomElementConstructorBuilder.h"
+#include "bindings/core/v8/Dictionary.h"
+#include "bindings/core/v8/ExceptionMessages.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionStatePlaceholder.h"
+#include "bindings/core/v8/ScriptController.h"
 #include "core/HTMLElementFactory.h"
 #include "core/HTMLNames.h"
 #include "core/SVGElementFactory.h"
@@ -73,7 +73,6 @@
 #include "core/dom/ExecutionContextTask.h"
 #include "core/dom/MainThreadTaskRunner.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"
 #include "core/dom/NodeWithIndex.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"
+#include "core/dom/StaticNodeList.h"
 #include "core/dom/StyleEngine.h"
 #include "core/dom/TouchList.h"
 #include "core/dom/TransformSource.h"
 #include "core/dom/TreeWalker.h"
 #include "core/dom/VisitedLinkState.h"
 #include "core/dom/XMLDocument.h"
+#include "core/dom/custom/CustomElementMicrotaskRunQueue.h"
 #include "core/dom/custom/CustomElementRegistrationContext.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/Editor.h"
 #include "core/editing/FrameSelection.h"
 #include "core/editing/SpellChecker.h"
+#include "core/editing/markup.h"
 #include "core/events/BeforeUnloadEvent.h"
 #include "core/events/Event.h"
 #include "core/events/EventFactory.h"
 #include "core/events/PageTransitionEvent.h"
 #include "core/events/ScopedEventQueue.h"
 #include "core/fetch/ResourceFetcher.h"
+#include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/FrameConsole.h"
 #include "core/frame/FrameHost.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/html/parser/NestingLevelIncrementer.h"
 #include "core/html/parser/TextResourceDecoder.h"
+#include "core/inspector/ConsoleMessage.h"
 #include "core/inspector/InspectorCounters.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/EventHandler.h"
+#include "core/page/EventWithHitTestResults.h"
 #include "core/page/FocusController.h"
 #include "core/page/FrameTree.h"
-#include "core/page/MouseEventWithHitTestResults.h"
 #include "core/page/Page.h"
 #include "core/page/PointerLockController.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/xml/XSLTProcessor.h"
 #include "core/xml/parser/XMLDocumentParser.h"
 #include "platform/DateComponents.h"
+#include "platform/EventDispatchForbiddenScope.h"
 #include "platform/Language.h"
 #include "platform/RuntimeEnabledFeatures.h"
+#include "platform/ScriptForbiddenScope.h"
 #include "platform/TraceEvent.h"
 #include "platform/network/ContentSecurityPolicyParsers.h"
 #include "platform/network/HTTPParsers.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
 #include "wtf/CurrentTime.h"
+#include "wtf/DateMath.h"
 #include "wtf/HashFunctions.h"
 #include "wtf/MainThread.h"
 #include "wtf/StdLibExtras.h"
 using namespace WTF;
 using namespace Unicode;
 
-namespace WebCore {
+namespace blink {
 
 using namespace HTMLNames;
 
@@ -309,7 +315,7 @@ static Widget* widgetForElement(const Element& focusedElement)
 
 static bool acceptsEditingFocus(const Element& element)
 {
-    ASSERT(element.rendererIsEditable());
+    ASSERT(element.hasEditableStyle());
 
     return element.document().frame() && element.rootEditableElement();
 }
@@ -357,6 +363,15 @@ static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& act
 
 uint64_t Document::s_globalTreeVersion = 0;
 
+#ifndef NDEBUG
+typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<Document> > WeakDocumentSet;
+static WeakDocumentSet& liveDocumentSet()
+{
+    DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrWillBeNoop(new WeakDocumentSet())));
+    return *set;
+}
+#endif
+
 // This class doesn't work with non-Document ExecutionContext.
 class AutofocusTask FINAL : public ExecutionContextTask {
 public:
@@ -486,9 +501,6 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
     , m_taskRunner(MainThreadTaskRunner::create(this))
     , m_registrationContext(initializer.registrationContext(this))
     , m_elementDataCacheClearTimer(this, &Document::elementDataCacheClearTimerFired)
-#ifndef NDEBUG
-    , m_didDispatchViewportPropertiesChanged(false)
-#endif
     , m_timeline(AnimationTimeline::create(this))
     , m_templateDocumentHost(nullptr)
     , m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
@@ -533,6 +545,10 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
     // CSSFontSelector, need to initialize m_styleEngine after initializing
     // m_fetcher.
     m_styleEngine = StyleEngine::create(*this);
+
+#ifndef NDEBUG
+    liveDocumentSet().add(this);
+#endif
 }
 
 Document::~Document()
@@ -603,6 +619,10 @@ Document::~Document()
 
     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
         ASSERT(!m_nodeListCounts[i]);
+
+#ifndef NDEBUG
+    liveDocumentSet().remove(this);
+#endif
 #endif
 
     setClient(0);
@@ -670,7 +690,7 @@ SelectorQueryCache& Document::selectorQueryCache()
 MediaQueryMatcher& Document::mediaQueryMatcher()
 {
     if (!m_mediaQueryMatcher)
-        m_mediaQueryMatcher = MediaQueryMatcher::create(this);
+        m_mediaQueryMatcher = MediaQueryMatcher::create(*this);
     return *m_mediaQueryMatcher;
 }
 
@@ -732,12 +752,17 @@ Location* Document::location() const
     return &domWindow()->location();
 }
 
-void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+void Document::childrenChanged(const ChildrenChange& change)
 {
-    ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+    ContainerNode::childrenChanged(change);
     m_documentElement = ElementTraversal::firstWithin(*this);
 }
 
+AtomicString Document::convertLocalName(const AtomicString& name)
+{
+    return isHTMLDocument() ? name.lower() : name;
+}
+
 PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
 {
     if (!isValidName(name)) {
@@ -746,7 +771,7 @@ PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& name
     }
 
     if (isXHTMLDocument() || isHTMLDocument())
-        return HTMLElementFactory::createHTMLElement(isHTMLDocument() ? name.lower() : name, *this, 0, false);
+        return HTMLElementFactory::createHTMLElement(convertLocalName(name), *this, 0, false);
 
     return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
 }
@@ -761,7 +786,7 @@ PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& loca
     RefPtrWillBeRawPtr<Element> element;
 
     if (CustomElement::isValidName(localName) && registrationContext()) {
-        element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
+        element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, convertLocalName(localName), xhtmlNamespaceURI));
     } else {
         element = createElement(localName, exceptionState);
         if (exceptionState.hadException())
@@ -816,12 +841,12 @@ PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& na
     return element.release();
 }
 
-ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, ExceptionState& exceptionState)
+ScriptValue Document::registerElement(ScriptState* scriptState, const AtomicString& name, ExceptionState& exceptionState)
 {
     return registerElement(scriptState, name, Dictionary(), exceptionState);
 }
 
-ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
+ScriptValue Document::registerElement(ScriptState* scriptState, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
 {
     if (!registrationContext()) {
         exceptionState.throwDOMException(NotSupportedError, "No element registration context is available.");
@@ -833,6 +858,13 @@ ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const A
     return constructorBuilder.bindingsReturnValue();
 }
 
+CustomElementMicrotaskRunQueue* Document::customElementMicrotaskRunQueue()
+{
+    if (!m_customElementMicrotaskRunQueue)
+        m_customElementMicrotaskRunQueue = CustomElementMicrotaskRunQueue::create();
+    return m_customElementMicrotaskRunQueue.get();
+}
+
 void Document::setImportsController(HTMLImportsController* controller)
 {
     ASSERT(!m_importsController || !controller);
@@ -930,19 +962,8 @@ bool Document::importContainerNodeChildren(ContainerNode* oldContainerNode, Pass
     return true;
 }
 
-PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, ExceptionState& ec)
-{
-    UseCounter::countDeprecation(this, UseCounter::DocumentImportNodeOptionalArgument);
-    return importNode(importedNode, true, ec);
-}
-
 PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
 {
-    if (!importedNode) {
-        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
-
     switch (importedNode->nodeType()) {
     case TEXT_NODE:
         return createTextNode(importedNode->nodeValue());
@@ -1005,16 +1026,10 @@ PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, bool deep,
 
 PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState)
 {
-    if (!source) {
-        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
-
     EventQueueScope scope;
 
     switch (source->nodeType()) {
     case DOCUMENT_NODE:
-    case DOCUMENT_TYPE_NODE:
         exceptionState.throwDOMException(NotSupportedError, "The node provided is of type '" + source->nodeName() + "', which may not be adopted.");
         return nullptr;
     case ATTRIBUTE_NODE: {
@@ -1285,7 +1300,7 @@ PassRefPtrWillBeRawPtr<Range> Document::caretRangeFromPoint(int x, int y)
         return Range::create(*this, container, offset, container, offset);
     }
 
-    PositionWithAffinity positionWithAffinity = renderer->positionForPoint(result.localPoint());
+    PositionWithAffinity positionWithAffinity = result.position();
     if (positionWithAffinity.position().isNull())
         return nullptr;
 
@@ -1546,61 +1561,15 @@ PassRefPtrWillBeRawPtr<Range> Document::createRange()
     return Range::create(*this);
 }
 
-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.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
-    return NodeIterator::create(root, NodeFilter::SHOW_ALL, nullptr);
-}
-
-PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
 {
-    if (!root) {
-        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, nullptr);
-}
-
-PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
-{
-    if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
-    // FIXME: Ditto.
     return NodeIterator::create(root, whatToShow, filter);
 }
 
-PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
-{
-    if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
-    return TreeWalker::create(root, NodeFilter::SHOW_ALL, nullptr);
-}
-
-PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
-{
-    if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
-    return TreeWalker::create(root, whatToShow, nullptr);
-}
-
 PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
 {
-    if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
-        return nullptr;
-    }
     return TreeWalker::create(root, whatToShow, filter);
 }
 
@@ -1677,7 +1646,7 @@ void Document::updateDistributionIfNeeded()
 
     if (!childNeedsDistributionRecalc())
         return;
-    TRACE_EVENT0("webkit", "Document::updateDistributionIfNeeded");
+    TRACE_EVENT0("blink", "Document::updateDistributionIfNeeded");
     recalcDistribution();
 }
 
@@ -1689,7 +1658,7 @@ void Document::updateStyleInvalidationIfNeeded()
         return;
     if (!childNeedsStyleInvalidation())
         return;
-    TRACE_EVENT0("webkit", "Document::updateStyleInvalidationIfNeeded");
+    TRACE_EVENT0("blink", "Document::updateStyleInvalidationIfNeeded");
     ASSERT(styleResolver());
 
     styleResolver()->ruleFeatureSet().styleInvalidator().invalidate(*this);
@@ -1815,6 +1784,8 @@ void Document::updateRenderTree(StyleRecalcChange change)
 {
     ASSERT(isMainThread());
 
+    ScriptForbiddenScope forbidScript;
+
     if (!view() || !isActive())
         return;
 
@@ -1831,11 +1802,14 @@ void Document::updateRenderTree(StyleRecalcChange change)
     RELEASE_ASSERT(!view()->isPainting());
 
     // Script can run below in WidgetUpdates, so protect the LocalFrame.
+    // FIXME: Can this still happen? How does script run inside
+    // UpdateSuspendScope::performDeferredWidgetTreeOperations() ?
     RefPtr<LocalFrame> protect(m_frame);
 
-    TRACE_EVENT0("webkit", "Document::updateRenderTree");
-    TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "UpdateRenderTree");
+    TRACE_EVENT_BEGIN0("blink", "Document::updateRenderTree");
+    TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "UpdateRenderTree");
 
+    // FIXME: Remove m_styleRecalcElementCounter, we should just use the accessCount() on the resolver.
     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());
@@ -1843,11 +1817,7 @@ void Document::updateRenderTree(StyleRecalcChange change)
     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
 
     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();
@@ -1881,15 +1851,15 @@ void Document::updateRenderTree(StyleRecalcChange change)
     ASSERT(!m_timeline->hasOutdatedAnimationPlayer());
 
     TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "elementCount", m_styleRecalcElementCounter);
+    TRACE_EVENT_END1("blink", "Document::updateRenderTree", "elementCount", m_styleRecalcElementCounter);
     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
     InspectorInstrumentation::didRecalculateStyle(cookie, m_styleRecalcElementCounter);
 }
 
 void Document::updateStyle(StyleRecalcChange change)
 {
-    TRACE_EVENT0("webkit", "Document::updateStyle");
+    TRACE_EVENT0("blink", "Document::updateStyle");
 
-    ScriptForbiddenScope forbidScript;
     HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
     m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc);
 
@@ -1932,7 +1902,6 @@ void Document::updateStyle(StyleRecalcChange change)
     ensureStyleResolver().printStats();
 
     view()->recalcOverflowAfterStyleChange();
-    renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
 
     clearChildNeedsStyleRecalc();
 
@@ -1964,6 +1933,8 @@ void Document::updateLayout()
 {
     ASSERT(isMainThread());
 
+    ScriptForbiddenScope forbidScript;
+
     RefPtr<FrameView> frameView = view();
     if (frameView && frameView->isInPerformLayout()) {
         // View layout should not be re-entrant.
@@ -2051,6 +2022,7 @@ PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Elem
 
 PassRefPtr<RenderStyle> Document::styleForPage(int pageIndex)
 {
+    updateDistributionIfNeeded();
     return ensureStyleResolver().styleForPage(pageIndex);
 }
 
@@ -2188,9 +2160,9 @@ void Document::attach(const AttachContext& context)
 
     ContainerNode::attach(context);
 
-    // 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();
+    // The TextAutosizer can't update render view info while the Document is detached, so update now in case anything changed.
+    if (TextAutosizer* autosizer = textAutosizer())
+        autosizer->updatePageInfo();
 
     m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
 }
@@ -2243,8 +2215,7 @@ void Document::detach(const AttachContext& context)
 
     m_styleEngine->didDetach();
 
-    if (Document* parentDoc = parentDocument())
-        parentDoc->didClearTouchEventHandlers(this);
+    frameHost()->eventHandlerRegistry().documentDetached(*this);
 
     // 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
@@ -2254,17 +2225,11 @@ void Document::detach(const AttachContext& context)
     m_frame = 0;
 
     if (m_mediaQueryMatcher)
-        m_mediaQueryMatcher->documentDestroyed();
+        m_mediaQueryMatcher->documentDetached();
 
     lifecycleNotifier().notifyDocumentWasDetached();
     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();
@@ -2439,7 +2404,7 @@ HTMLElement* Document::body() const
     if (!documentElement())
         return 0;
 
-    for (HTMLElement* child = Traversal<HTMLElement>::firstWithin(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+    for (HTMLElement* child = Traversal<HTMLElement>::firstChild(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
         if (isHTMLFrameSetElement(*child) || isHTMLBodyElement(*child))
             return child;
     }
@@ -2659,7 +2624,7 @@ bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigatio
         return true;
 
     if (didAllowNavigation) {
-        addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show multiple 'beforeunload' confirmation panels for a single navigation.");
+        addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show multiple 'beforeunload' confirmation panels for a single navigation."));
         return true;
     }
 
@@ -2778,7 +2743,7 @@ void Document::write(const SegmentedString& text, Document* ownerDocument, Excep
     bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
 
     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."));
+        addConsoleMessage(ConsoleMessage::create(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;
     }
 
@@ -2827,7 +2792,9 @@ EventTarget* Document::errorEventTarget()
 
 void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
 {
-    internalAddMessage(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack, 0);
+    RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber);
+    consoleMessage->setCallStack(callStack);
+    addMessage(consoleMessage.release());
 }
 
 void Document::setURL(const KURL& url)
@@ -3030,6 +2997,9 @@ void Document::didLoadAllScriptBlockingResources()
 {
     m_executeScriptsWaitingForResourcesTimer.startOneShot(0, FROM_HERE);
 
+    if (frame())
+        frame()->loader().client()->didRemoveAllPendingStylesheet();
+
     if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
         view()->scrollToFragment(m_url);
 }
@@ -3119,13 +3089,13 @@ void Document::maybeHandleHttpRefresh(const String& content, HttpRefreshType htt
 
     if (protocolIsJavaScript(refreshURL)) {
         String message = "Refused to refresh " + m_url.elidedString() + " to a javascript: URL";
-        addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+        addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
         return;
     }
 
     if (httpRefreshType == HttpRefreshFromMetaTag && isSandboxed(SandboxAutomaticFeatures)) {
         String message = "Refused to execute the redirect specified via '<meta http-equiv='refresh' content='...'>'. The document is sandboxed, and the 'allow-scripts' keyword is not set.";
-        addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+        addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
         return;
     }
     m_frame->navigationScheduler().scheduleRedirect(delay, refreshURL);
@@ -3156,7 +3126,9 @@ void Document::processHttpEquivXFrameOptions(const AtomicString& content)
         // 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(), Referrer());
-        addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
+        RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message);
+        consoleMessage->setRequestIdentifier(requestIdentifier);
+        addMessage(consoleMessage.release());
     }
 }
 
@@ -3197,9 +3169,6 @@ void Document::setViewportDescription(const ViewportDescription& viewportDescrip
 void Document::updateViewportDescription()
 {
     if (frame() && frame()->isMainFrame()) {
-#ifndef NDEBUG
-        m_didDispatchViewportPropertiesChanged = true;
-#endif
         frameHost()->chrome().dispatchViewportPropertiesDidChange(m_viewportDescription);
     }
 }
@@ -3217,7 +3186,7 @@ void Document::processReferrerPolicy(const String& policy)
     } 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'.");
+        addConsoleMessage(ConsoleMessage::create(RenderingMessageSource, ErrorMessageLevel, "Failed to set referrer policy: The value '" + policy + "' is not one of 'always', 'default', 'never', or 'origin'. Defaulting to 'never'."));
         setReferrerPolicy(ReferrerPolicyNever);
     }
 }
@@ -3438,11 +3407,13 @@ void Document::evaluateMediaQueryListIfNeeded()
 void Document::evaluateMediaQueryList()
 {
     if (m_mediaQueryMatcher)
-        m_mediaQueryMatcher->styleResolverChanged();
+        m_mediaQueryMatcher->mediaFeaturesChanged();
 }
 
 void Document::notifyResizeForViewportUnits()
 {
+    if (m_mediaQueryMatcher)
+        m_mediaQueryMatcher->viewportChanged();
     if (!hasViewportUnits())
         return;
     ensureStyleResolver().notifyResizeForViewportUnits();
@@ -3465,7 +3436,7 @@ void Document::styleResolverChanged(StyleResolverUpdateMode updateMode)
 
         ASSERT(renderView() || importsController());
         if (renderView())
-            renderView()->repaintViewAndCompositedLayers();
+            renderView()->invalidatePaintForViewAndCompositedLayers();
     }
 }
 
@@ -3529,7 +3500,7 @@ void Document::activeChainNodeDetached(Node* node)
     if (!m_activeHoverElement)
         return;
 
-    if (node != m_activeHoverElement && (!m_activeHoverElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeHoverElement.get())))
+    if (node != m_activeHoverElement)
         return;
 
     Node* activeNode = NodeRenderingTraversal::parent(node);
@@ -3791,7 +3762,7 @@ void Document::updateRangesAfterNodeMovedToAnotherDocument(const Node& node)
 
 void Document::nodeChildrenWillBeRemoved(ContainerNode& container)
 {
-    NoEventDispatchAssertion assertNoEventDispatch;
+    EventDispatchForbiddenScope assertNoEventDispatch;
     if (!m_ranges.isEmpty()) {
         AttachedRangeSet::const_iterator end = m_ranges.end();
         for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
@@ -3929,6 +3900,12 @@ void Document::enqueueResizeEvent()
     ensureScriptedAnimationController().enqueuePerFrameEvent(event.release());
 }
 
+void Document::enqueueMediaQueryChangeListeners(WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> >& listeners)
+{
+    ensureScriptedAnimationController().enqueueMediaQueryChangeListeners(listeners);
+}
+
+
 Document::EventFactorySet& Document::eventFactories()
 {
     DEFINE_STATIC_LOCAL(EventFactorySet, s_eventFactory, ());
@@ -4116,7 +4093,7 @@ String Document::lastModified() const
         if (DocumentLoader* documentLoader = loader()) {
             const AtomicString& httpLastModified = documentLoader->response().httpHeaderField("Last-Modified");
             if (!httpLastModified.isEmpty()) {
-                date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
+                date.setMillisecondsSinceEpochForDateTime(convertToLocalTime(parseDate(httpLastModified)));
                 foundDate = true;
             }
         }
@@ -4125,7 +4102,7 @@ String Document::lastModified() const
     // specificiation tells us to read the last modification date from the file
     // system.
     if (!foundDate)
-        date.setMillisecondsSinceEpochForDateTime(currentTimeMS());
+        date.setMillisecondsSinceEpochForDateTime(convertToLocalTime(currentTimeMS()));
     return String::format("%02d/%02d/%04d %02d:%02d:%02d", date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
 }
 
@@ -4367,7 +4344,7 @@ bool Document::execCommand(const String& commandName, bool userInterface, const
     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);
+        addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
         return false;
     }
     TemporaryChange<bool> executeScope(inExecCommand, true);
@@ -4376,7 +4353,7 @@ bool Document::execCommand(const String& commandName, bool userInterface, const
     // DOM tree against implementation assumption.
     EventQueueScope eventQueueScope;
     Editor::Command editorCommand = command(this, commandName, userInterface);
-    blink::Platform::current()->histogramSparse("WebCore.Document.execCommand", editorCommand.idForHistogram());
+    Platform::current()->histogramSparse("WebCore.Document.execCommand", editorCommand.idForHistogram());
     return editorCommand.execute(value);
 }
 
@@ -4524,8 +4501,7 @@ 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()))
+    for (Element* element = doc->ownerElement(); element; element = doc->ownerElement())
         doc = &element->document();
 
     ASSERT(doc);
@@ -4584,44 +4560,39 @@ bool Document::hasSVGRootNode() const
     return isSVGSVGElement(documentElement());
 }
 
-PassRefPtrWillBeRawPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
-{
-    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
-}
-
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::images()
 {
-    return ensureCachedCollection(DocImages);
+    return ensureCachedCollection<HTMLCollection>(DocImages);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::applets()
 {
-    return ensureCachedCollection(DocApplets);
+    return ensureCachedCollection<HTMLCollection>(DocApplets);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::embeds()
 {
-    return ensureCachedCollection(DocEmbeds);
+    return ensureCachedCollection<HTMLCollection>(DocEmbeds);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::scripts()
 {
-    return ensureCachedCollection(DocScripts);
+    return ensureCachedCollection<HTMLCollection>(DocScripts);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::links()
 {
-    return ensureCachedCollection(DocLinks);
+    return ensureCachedCollection<HTMLCollection>(DocLinks);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::forms()
 {
-    return ensureCachedCollection(DocForms);
+    return ensureCachedCollection<HTMLCollection>(DocForms);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::anchors()
 {
-    return ensureCachedCollection(DocAnchors);
+    return ensureCachedCollection<HTMLCollection>(DocAnchors);
 }
 
 PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::allForBinding()
@@ -4632,17 +4603,17 @@ PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::allForBinding()
 
 PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::all()
 {
-    return ensureRareData().ensureNodeLists().addCache<HTMLAllCollection>(*this, DocAll);
+    return ensureCachedCollection<HTMLAllCollection>(DocAll);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
 {
-    return ensureRareData().ensureNodeLists().addCache<WindowNameCollection>(*this, WindowNamedItems, name);
+    return ensureCachedCollection<WindowNameCollection>(WindowNamedItems, name);
 }
 
 PassRefPtrWillBeRawPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
 {
-    return ensureRareData().ensureNodeLists().addCache<DocumentNameCollection>(*this, DocumentNamedItems, name);
+    return ensureCachedCollection<DocumentNameCollection>(DocumentNamedItems, name);
 }
 
 void Document::finishedParsing()
@@ -4656,14 +4627,6 @@ 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.
@@ -4766,7 +4729,7 @@ Color Document::themeColor() const
         return Color();
 
     for (HTMLMetaElement* metaElement = head() ? Traversal<HTMLMetaElement>::firstChild(*head()) : 0; metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
-        RGBA32 rgb;
+        RGBA32 rgb = Color::transparent;
         if (equalIgnoringCase(metaElement->name(), "theme-color") && BisonCSSParser::parseColor(rgb, metaElement->content().string().stripWhiteSpace(), true))
             return Color(rgb);
     }
@@ -4983,7 +4946,7 @@ void Document::detachRange(Range* range)
     m_ranges.remove(range);
 }
 
-void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
+void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
 {
     HTMLCanvasElement& element = getCSSCanvasElement(name);
     element.setSize(IntSize(width, height));
@@ -4992,10 +4955,8 @@ void Document::getCSSCanvasContext(const String& type, const String& name, int w
         return;
 
     if (context->is2d()) {
-        is2d = true;
         context2d = toCanvasRenderingContext2D(context);
     } else if (context->is3d()) {
-        is3d = true;
         context3d = toWebGLRenderingContext(context);
     }
 }
@@ -5040,42 +5001,25 @@ 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* scriptState)
-{
-    internalAddMessage(source, level, message, sourceURL, lineNumber, nullptr, scriptState);
-}
-
-void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState)
+void Document::addMessage(PassRefPtrWillBeRawPtr<ConsoleMessage> consoleMessage)
 {
     if (!isContextThread()) {
-        m_taskRunner->postTask(AddConsoleMessageTask::create(source, level, message));
+        m_taskRunner->postTask(AddConsoleMessageTask::create(consoleMessage->source(), consoleMessage->level(), consoleMessage->message()));
         return;
     }
 
     if (!m_frame)
         return;
 
-    String messageURL = sourceURL;
-    if (!scriptState && sourceURL.isNull() && !lineNumber) {
-        messageURL = url().string();
+    if (!consoleMessage->scriptState() && consoleMessage->url().isNull() && !consoleMessage->lineNumber()) {
+        consoleMessage->setURL(url().string());
         if (parsing() && !isInDocumentWrite() && scriptableDocumentParser()) {
             ScriptableDocumentParser* parser = scriptableDocumentParser();
             if (!parser->isWaitingForScripts() && !parser->isExecutingScript())
-                lineNumber = parser->lineNumber().oneBasedInt();
+                consoleMessage->setLineNumber(parser->lineNumber().oneBasedInt());
         }
     }
-    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)
-{
-    if (!isContextThread()) {
-        m_taskRunner->postTask(AddConsoleMessageTask::create(source, level, message));
-        return;
-    }
-
-    if (m_frame)
-        m_frame->console().addMessage(source, level, message, String(), 0, 0, nullptr, 0, requestIdentifier);
+    m_frame->console().addMessage(consoleMessage);
 }
 
 // FIXME(crbug.com/305497): This should be removed after ExecutionContext-LocalDOMWindow migration.
@@ -5084,6 +5028,11 @@ void Document::postTask(PassOwnPtr<ExecutionContextTask> task)
     m_taskRunner->postTask(task);
 }
 
+void Document::postInspectorTask(PassOwnPtr<ExecutionContextTask> task)
+{
+    m_taskRunner->postInspectorTask(task);
+}
+
 void Document::tasksWereSuspended()
 {
     scriptRunner()->suspend();
@@ -5295,80 +5244,6 @@ PassRefPtrWillBeRawPtr<TouchList> Document::createTouchList(WillBeHeapVector<Ref
     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);
-    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 (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, 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;
-
-    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;
-    }
-
-    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);
-        }
-    }
-
-    // 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
 {
     if (!m_frame)
@@ -5439,9 +5314,6 @@ void Document::decrementActiveParserCount()
     --m_activeParserCount;
     if (!frame())
         return;
-    // 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
     frame()->loader().checkLoadComplete();
 }
 
@@ -5480,13 +5352,12 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
 
     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()) {
-            if (curr->node()) {
-                ASSERT(!curr->node()->isTextNode());
-                curr->node()->setActive(false);
-                m_userActionElements.setInActiveChain(curr->node(), false);
-            }
+        // The oldActiveElement renderer is null, dropped on :active by setting display: none,
+        // for instance. We still need to clear the ActiveChain as the mouse is released.
+        for (Node* node = oldActiveElement; node; node = NodeRenderingTraversal::parent(node)) {
+            ASSERT(!node->isTextNode());
+            node->setActive(false);
+            m_userActionElements.setInActiveChain(node, false);
         }
         setActiveHoverElement(nullptr);
     } else {
@@ -5494,11 +5365,10 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
         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()) {
-                if (curr->node() && !curr->isText())
-                    m_userActionElements.setInActiveChain(curr->node(), true);
+            for (Node* node = newActiveElement; node; node = NodeRenderingTraversal::parent(node)) {
+                ASSERT(!node->isTextNode());
+                m_userActionElements.setInActiveChain(node, true);
             }
-
             setActiveHoverElement(newActiveElement);
         }
     }
@@ -5702,18 +5572,11 @@ void Document::modifiedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode upd
 
 TextAutosizer* Document::textAutosizer()
 {
-    if (!m_textAutosizer && !RuntimeEnabledFeatures::fastTextAutosizingEnabled())
+    if (!m_textAutosizer)
         m_textAutosizer = TextAutosizer::create(this);
     return m_textAutosizer.get();
 }
 
-FastTextAutosizer* Document::fastTextAutosizer()
-{
-    if (!m_fastTextAutosizer && RuntimeEnabledFeatures::fastTextAutosizingEnabled())
-        m_fastTextAutosizer = FastTextAutosizer::create(this);
-    return m_fastTextAutosizer.get();
-}
-
 void Document::setAutofocusElement(Element* element)
 {
     if (!element) {
@@ -5735,6 +5598,58 @@ Element* Document::activeElement() const
     return body();
 }
 
+void Document::getTransitionElementData(Vector<TransitionElementData>& elementData)
+{
+    if (!head())
+        return;
+
+    for (HTMLMetaElement* metaElement = Traversal<HTMLMetaElement>::firstChild(*head()); metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
+        if (metaElement->name() != "transition-elements")
+            continue;
+
+        const String& metaElementContents = metaElement->content().string();
+        size_t firstSemicolon = metaElementContents.find(';');
+        if (firstSemicolon == kNotFound)
+            continue;
+
+        TrackExceptionState exceptionState;
+        AtomicString selector(metaElementContents.substring(0, firstSemicolon));
+        RefPtrWillBeRawPtr<StaticElementList> elementList = querySelectorAll(selector, exceptionState);
+        if (!elementList || exceptionState.hadException())
+            continue;
+
+        unsigned nodeListLength = elementList->length();
+        if (!nodeListLength)
+            continue;
+
+        StringBuilder markup;
+        for (unsigned nodeIndex = 0; nodeIndex < nodeListLength; ++nodeIndex) {
+            Element* element = elementList->item(nodeIndex);
+            markup.append(createStyledMarkupForNavigationTransition(element));
+        }
+
+        TransitionElementData newElements;
+        newElements.scope = metaElementContents.substring(firstSemicolon + 1).stripWhiteSpace();
+        newElements.selector = selector;
+        newElements.markup = markup.toString();
+        elementData.append(newElements);
+    }
+}
+
+void Document::hideTransitionElements(const AtomicString& cssSelector)
+{
+    TrackExceptionState exceptionState;
+    RefPtrWillBeRawPtr<StaticElementList> elementList = querySelectorAll(cssSelector, exceptionState);
+    if (elementList && !exceptionState.hadException()) {
+        unsigned nodeListLength = elementList->length();
+
+        for (unsigned nodeIndex = 0; nodeIndex < nodeListLength; ++nodeIndex) {
+            Element* element = elementList->item(nodeIndex);
+            element->setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);
+        }
+    }
+}
+
 bool Document::hasFocus() const
 {
     Page* page = this->page();
@@ -5813,21 +5728,11 @@ 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)
 {
+#if ENABLE(OILPAN)
     visitor->trace(m_importsController);
     visitor->trace(m_docType);
     visitor->trace(m_implementation);
@@ -5843,10 +5748,8 @@ void Document::trace(Visitor* visitor)
     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);
@@ -5854,6 +5757,7 @@ void Document::trace(Visitor* visitor)
     visitor->trace(m_ranges);
     visitor->trace(m_styleEngine);
     visitor->trace(m_formController);
+    visitor->trace(m_visitedLinkState);
     visitor->trace(m_domWindow);
     visitor->trace(m_fetcher);
     visitor->trace(m_parser);
@@ -5861,7 +5765,10 @@ void Document::trace(Visitor* visitor)
     visitor->trace(m_styleSheetList);
     visitor->trace(m_mediaQueryMatcher);
     visitor->trace(m_scriptedAnimationController);
+    visitor->trace(m_textAutosizer);
     visitor->trace(m_registrationContext);
+    visitor->trace(m_customElementMicrotaskRunQueue);
+    visitor->trace(m_elementDataCache);
     visitor->trace(m_associatedFormControls);
     visitor->trace(m_useElementsNeedingUpdate);
     visitor->trace(m_layerUpdateSVGFilterElements);
@@ -5874,10 +5781,24 @@ void Document::trace(Visitor* visitor)
     visitor->trace(m_compositorPendingAnimations);
     visitor->trace(m_contextDocument);
     visitor->registerWeakMembers<Document, &Document::clearWeakMembers>(this);
+#endif
     DocumentSupplementable::trace(visitor);
     TreeScope::trace(visitor);
     ContainerNode::trace(visitor);
     ExecutionContext::trace(visitor);
+    LifecycleContext<Document>::trace(visitor);
 }
 
-} // namespace WebCore
+} // namespace blink
+
+#ifndef NDEBUG
+using namespace blink;
+void showLiveDocumentInstances()
+{
+    WeakDocumentSet& set = liveDocumentSet();
+    fprintf(stderr, "There are %u documents currently alive:\n", set.size());
+    for (WeakDocumentSet::const_iterator it = set.begin(); it != set.end(); ++it) {
+        fprintf(stderr, "- Document %p URL: %s\n", *it, (*it)->url().string().utf8().data());
+    }
+}
+#endif