Have is<>(T*) function do a null check on the pointer argument
[WebKit-https.git] / Source / WebCore / testing / Internals.cpp
index b1cb517..6549550 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 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
 #include "Element.h"
 #include "EventHandler.h"
 #include "ExceptionCode.h"
+#include "FontCache.h"
 #include "FormController.h"
 #include "FrameLoader.h"
 #include "FrameView.h"
+#include "HTMLIFrameElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "HTMLPlugInElement.h"
 #include "HTMLSelectElement.h"
 #include "HTMLTextAreaElement.h"
 #include "HistoryController.h"
 #include "HistoryItem.h"
 #include "InspectorClient.h"
-#include "InspectorConsoleAgent.h"
 #include "InspectorController.h"
-#include "InspectorCounters.h"
 #include "InspectorForwarding.h"
 #include "InspectorFrontendClientLocal.h"
 #include "InspectorInstrumentation.h"
 #include "InspectorOverlay.h"
 #include "InstrumentingAgents.h"
-#include "InternalSettings.h"
 #include "IntRect.h"
+#include "InternalSettings.h"
 #include "Language.h"
 #include "MainFrame.h"
 #include "MallocStatistics.h"
@@ -88,6 +89,7 @@
 #include "SerializedScriptValue.h"
 #include "Settings.h"
 #include "ShadowRoot.h"
+#include "SourceBuffer.h"
 #include "SpellChecker.h"
 #include "StaticNodeList.h"
 #include "StyleSheetContents.h"
 #include "TreeScope.h"
 #include "TypeConversions.h"
 #include "ViewportArguments.h"
+#include "WebConsoleAgent.h"
 #include "WorkerThread.h"
 #include <bytecode/CodeBlock.h>
 #include <inspector/InspectorAgentBase.h>
 #include <inspector/InspectorValues.h>
+#include <runtime/JSCInlines.h>
 #include <runtime/JSCJSValue.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringBuffer.h>
 #include "BatteryController.h"
 #endif
 
-#if ENABLE(NETWORK_INFO)
-#include "NetworkInfo.h"
-#include "NetworkInfoController.h"
-#endif
-
 #if ENABLE(PROXIMITY_EVENTS)
 #include "DeviceProximityController.h"
 #endif
 #include "MockMediaStreamCenter.h"
 #include "RTCPeerConnection.h"
 #include "RTCPeerConnectionHandlerMock.h"
+#include "UserMediaClientMock.h"
 #endif
 
 #if ENABLE(MEDIA_SOURCE)
@@ -194,7 +194,7 @@ protected:
 };
 
 InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
-    : InspectorFrontendClientLocal(controller, page, adoptPtr(new InspectorFrontendClientLocal::Settings()))
+    : InspectorFrontendClientLocal(controller, page, std::make_unique<InspectorFrontendClientLocal::Settings>())
 {
 }
 
@@ -243,6 +243,10 @@ static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerType
         result =  DocumentMarker::DeletedAutocorrection;
     else if (equalIgnoringCase(markerType, "DictationAlternatives"))
         result =  DocumentMarker::DictationAlternatives;
+#if ENABLE(TELEPHONE_NUMBER_DETECTION)
+    else if (equalIgnoringCase(markerType, "TelephoneNumber"))
+        result =  DocumentMarker::TelephoneNumber;
+#endif
     else
         return false;
 
@@ -271,6 +275,7 @@ void Internals::resetToConsistentState(Page* page)
     if (mainFrameView) {
         mainFrameView->setHeaderHeight(0);
         mainFrameView->setFooterHeight(0);
+        page->setTopContentInset(0);
     }
 
     TextRun::setAllowsRoundingHacks(false);
@@ -279,7 +284,7 @@ void Internals::resetToConsistentState(Page* page)
 #if ENABLE(INSPECTOR)
     page->inspectorController().setProfilerEnabled(false);
 #endif
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
+#if ENABLE(VIDEO_TRACK)
     page->group().captionPreferences()->setCaptionsStyleSheetOverride(emptyString());
     page->group().captionPreferences()->setTestingMode(false);
 #endif
@@ -292,6 +297,7 @@ void Internals::resetToConsistentState(Page* page)
     MediaSessionManager::sharedManager().resetRestrictions();
 #endif
 #if HAVE(ACCESSIBILITY)
+    AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
     AXObjectCache::disableAccessibility();
 #endif
 }
@@ -299,7 +305,7 @@ void Internals::resetToConsistentState(Page* page)
 Internals::Internals(Document* document)
     : ContextDestructionObserver(document)
 {
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
+#if ENABLE(VIDEO_TRACK)
     if (document && document->page())
         document->page()->group().captionPreferences()->setTestingMode(true);
 #endif
@@ -307,18 +313,19 @@ Internals::Internals(Document* document)
 #if ENABLE(MEDIA_STREAM)
     MockMediaStreamCenter::registerMockMediaStreamCenter();
     enableMockRTCPeerConnectionHandler();
+    WebCore::provideUserMediaTo(document->page(), new UserMediaClientMock());
 #endif
 }
 
 Document* Internals::contextDocument() const
 {
-    return toDocument(scriptExecutionContext());
+    return downcast<Document>(scriptExecutionContext());
 }
 
 Frame* Internals::frame() const
 {
     if (!contextDocument())
-        return 0;
+        return nullptr;
     return contextDocument()->frame();
 }
 
@@ -340,10 +347,22 @@ unsigned Internals::workerThreadCount() const
 
 String Internals::address(Node* node)
 {
-    char buf[32];
-    sprintf(buf, "%p", node);
+    return String::format("%p", node);
+}
+
+bool Internals::nodeNeedsStyleRecalc(Node* node, ExceptionCode& exception)
+{
+    if (!node) {
+        exception = INVALID_ACCESS_ERR;
+        return false;
+    }
+
+    return node->needsStyleRecalc();
+}
 
-    return String(buf);
+String Internals::description(Deprecated::ScriptValue value)
+{
+    return toString(value.jsValue());
 }
 
 bool Internals::isPreloaded(const String& url)
@@ -354,9 +373,9 @@ bool Internals::isPreloaded(const String& url)
 
 bool Internals::isLoadingFromMemoryCache(const String& url)
 {
-    if (!contextDocument())
+    if (!contextDocument() || !contextDocument()->page())
         return false;
-    CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url));
+    CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url), contextDocument()->page()->sessionID());
     return resource && resource->status() == CachedResource::Cached;
 }
 
@@ -365,20 +384,20 @@ Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
 {
     if (!node) {
         ec = INVALID_ACCESS_ERR;
-        return 0;
+        return nullptr;
     }
 
-    return node->treeScope().rootNode();
+    return &node->treeScope().rootNode();
 }
 
 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
 {
     if (!node) {
         ec = INVALID_ACCESS_ERR;
-        return 0;
+        return nullptr;
     }
     const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
-    return parentTreeScope ? parentTreeScope->rootNode() : 0;
+    return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
 }
 
 unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
@@ -529,7 +548,7 @@ PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisited
     return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
 }
 
-Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
+Node* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
 {
     if (!host) {
         ec = INVALID_ACCESS_ERR;
@@ -542,7 +561,7 @@ Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Eleme
     return host->createShadowRoot(ec).get();
 }
 
-Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
+Node* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
 {
     if (!host) {
         ec = INVALID_ACCESS_ERR;
@@ -551,27 +570,25 @@ Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::createShadowRoot(Eleme
     return host->createShadowRoot(ec).get();
 }
 
-Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::shadowRoot(Element* host, ExceptionCode& ec)
+Node* Internals::shadowRoot(Element* host, ExceptionCode& ec)
 {
     if (!host) {
         ec = INVALID_ACCESS_ERR;
-        return 0;
+        return nullptr;
     }
     return host->shadowRoot();
 }
 
 String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
 {
-    if (!root || !root->isShadowRoot()) {
+    if (!is<ShadowRoot>(root)) {
         ec = INVALID_ACCESS_ERR;
         return String();
     }
 
-    switch (toShadowRoot(root)->type()) {
+    switch (downcast<ShadowRoot>(*root).type()) {
     case ShadowRoot::UserAgentShadowRoot:
         return String("UserAgentShadowRoot");
-    case ShadowRoot::AuthorShadowRoot:
-        return String("AuthorShadowRoot");
     default:
         ASSERT_NOT_REACHED();
         return String("Unknown");
@@ -581,7 +598,7 @@ String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
 Element* Internals::includerFor(Node*, ExceptionCode& ec)
 {
     ec = INVALID_ACCESS_ERR;
-    return 0;
+    return nullptr;
 }
 
 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
@@ -606,9 +623,12 @@ void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionC
 
 String Internals::visiblePlaceholder(Element* element)
 {
-    if (element && isHTMLTextFormControlElement(*element)) {
-        if (toHTMLTextFormControlElement(*element).placeholderShouldBeVisible())
-            return toHTMLTextFormControlElement(*element).placeholderElement()->textContent();
+    if (is<HTMLTextFormControlElement>(element)) {
+        const HTMLTextFormControlElement& textFormControlElement = downcast<HTMLTextFormControlElement>(*element);
+        if (!textFormControlElement.isPlaceholderVisible())
+            return String();
+        if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
+            return placeholderElement->textContent();
     }
 
     return String();
@@ -617,7 +637,7 @@ String Internals::visiblePlaceholder(Element* element)
 #if ENABLE(INPUT_TYPE_COLOR)
 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
 {
-    if (!isHTMLInputElement(element))
+    if (!is<HTMLInputElement>(*element))
         return;
     HTMLInputElement* inputElement = element->toInputElement();
     if (!inputElement)
@@ -667,7 +687,7 @@ void Internals::enableMockSpeechSynthesizer()
     if (!synthesis)
         return;
     
-    synthesis->setPlatformSynthesizer(PlatformSpeechSynthesizerMock::create(synthesis));
+    synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
 }
 #endif
 
@@ -713,7 +733,7 @@ PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
     }
 
     Highlight highlight;
-    document->page()->inspectorController().getHighlight(&highlight);
+    document->page()->inspectorController().getHighlight(&highlight, InspectorOverlay::CoordinateSystem::View);
     return ClientRectList::create(highlight.quads);
 #else
     UNUSED_PARAM(ec);
@@ -750,6 +770,8 @@ unsigned Internals::markerCountForNode(Node* node, const String& markerType, Exc
         return 0;
     }
 
+    node->document().frame()->editor().updateEditorUINowIfScheduled();
+
     return node->document().markers().markersFor(node, markerTypes).size();
 }
 
@@ -767,6 +789,8 @@ DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsign
         return 0;
     }
 
+    node->document().frame()->editor().updateEditorUINowIfScheduled();
+
     Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
     if (markers.size() <= index)
         return 0;
@@ -795,6 +819,21 @@ void Internals::addTextMatchMarker(const Range* range, bool isActive)
     range->ownerDocument().markers().addTextMatchMarker(range, isActive);
 }
 
+void Internals::setMarkedTextMatchesAreHighlighted(bool flag, ExceptionCode& ec)
+{
+    Document* document = contextDocument();
+    if (!document || !document->frame()) {
+        ec = INVALID_ACCESS_ERR;
+        return;
+    }
+    document->frame()->editor().setMarkedTextMatchesAreHighlighted(flag);
+}
+
+void Internals::invalidateFontCache()
+{
+    fontCache().invalidate();
+}
+
 void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
 {
     Document* document = contextDocument();
@@ -873,9 +912,8 @@ bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
     if (HTMLInputElement* inputElement = textField->toInputElement())
         return inputElement->lastChangeWasUserEdit();
 
-    // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
-    if (textField->tagName() == "TEXTAREA")
-        return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
+    if (is<HTMLTextAreaElement>(*textField))
+        return downcast<HTMLTextAreaElement>(*textField).lastChangeWasUserEdit();
 
     ec = INVALID_NODE_TYPE_ERR;
     return false;
@@ -895,38 +933,6 @@ bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
     return false;
 }
 
-String Internals::suggestedValue(Element* element, ExceptionCode& ec)
-{
-    if (!element) {
-        ec = INVALID_ACCESS_ERR;
-        return String();
-    }
-
-    HTMLInputElement* inputElement = element->toInputElement();
-    if (!inputElement) {
-        ec = INVALID_NODE_TYPE_ERR;
-        return String();
-    }
-
-    return inputElement->suggestedValue();
-}
-
-void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
-{
-    if (!element) {
-        ec = INVALID_ACCESS_ERR;
-        return;
-    }
-
-    HTMLInputElement* inputElement = element->toInputElement();
-    if (!inputElement) {
-        ec = INVALID_NODE_TYPE_ERR;
-        return;
-    }
-
-    inputElement->setSuggestedValue(value);
-}
-
 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
 {
     if (!element) {
@@ -1115,7 +1121,7 @@ PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, i
     document->updateLayoutIgnorePendingStylesheets();
 
     float zoomFactor = frame->pageZoomFactor();
-    LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
+    LayoutPoint point(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY());
 
     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
     if (ignoreClipping)
@@ -1153,20 +1159,6 @@ PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, i
     return StaticNodeList::adopt(matches);
 }
 
-void Internals::emitInspectorDidBeginFrame()
-{
-#if ENABLE(INSPECTOR)
-    contextDocument()->frame()->page()->inspectorController().didBeginFrame();
-#endif
-}
-
-void Internals::emitInspectorDidCancelFrame()
-{
-#if ENABLE(INSPECTOR)
-    contextDocument()->frame()->page()->inspectorController().didCancelFrame();
-#endif
-}
-
 class GetCallerCodeBlockFunctor {
 public:
     GetCallerCodeBlockFunctor()
@@ -1194,8 +1186,8 @@ private:
 
 String Internals::parserMetaData(Deprecated::ScriptValue value)
 {
-    JSC::VM* vm = contextDocument()->vm();
-    JSC::ExecState* exec = vm->topCallFrame;
+    JSC::VM& vm = contextDocument()->vm();
+    JSC::ExecState* exec = vm.topCallFrame;
     JSC::JSValue code = value.jsValue();
     ScriptExecutable* executable;
 
@@ -1220,25 +1212,25 @@ String Internals::parserMetaData(Deprecated::ScriptValue value)
     if (executable->isFunctionExecutable()) {
         FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
         String inferredName = funcExecutable->inferredName().string();
-        result.append("function \"");
+        result.appendLiteral("function \"");
         result.append(inferredName);
-        result.append("\"");
+        result.append('"');
     } else if (executable->isEvalExecutable())
-        result.append("eval");
+        result.appendLiteral("eval");
     else {
         ASSERT(executable->isProgramExecutable());
-        result.append("program");
+        result.appendLiteral("program");
     }
 
-    result.append(" { ");
+    result.appendLiteral(" { ");
     result.appendNumber(startLine);
-    result.append(":");
+    result.append(':');
     result.appendNumber(startColumn);
-    result.append(" - ");
+    result.appendLiteral(" - ");
     result.appendNumber(endLine);
-    result.append(":");
+    result.append(':');
     result.appendNumber(endColumn);
-    result.append(" }");
+    result.appendLiteral(" }");
 
     return result.toString();
 }
@@ -1262,23 +1254,6 @@ void Internals::setBatteryStatus(const String& eventType, bool charging, double
 #endif
 }
 
-void Internals::setNetworkInformation(const String& eventType, double bandwidth, bool metered, ExceptionCode& ec)
-{
-    Document* document = contextDocument();
-    if (!document || !document->page()) {
-        ec = INVALID_ACCESS_ERR;
-        return;
-    }
-
-#if ENABLE(NETWORK_INFO)
-    NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered));
-#else
-    UNUSED_PARAM(eventType);
-    UNUSED_PARAM(bandwidth);
-    UNUSED_PARAM(metered);
-#endif
-}
-
 void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
 {
     Document* document = contextDocument();
@@ -1297,12 +1272,34 @@ void Internals::setDeviceProximity(const String& eventType, double value, double
 #endif
 }
 
+void Internals::updateEditorUINowIfScheduled()
+{
+    if (Document* document = contextDocument()) {
+        if (Frame* frame = document->frame())
+            frame->editor().updateEditorUINowIfScheduled();
+    }
+}
+
+Node* Internals::findEditingDeleteButton()
+{
+    Document* document = contextDocument();
+    if (!document || !document->frame())
+        return 0;
+
+    updateEditorUINowIfScheduled();
+
+    // FIXME: We shouldn't pollute the id namespace with this name.
+    return document->getElementById(String(ASCIILiteral("WebKit-Editing-Delete-Button")));
+}
+
 bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
 {
     Document* document = contextDocument();
     if (!document || !document->frame())
         return 0;
 
+    updateEditorUINowIfScheduled();
+
     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
 }
     
@@ -1311,7 +1308,9 @@ bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
     Document* document = contextDocument();
     if (!document || !document->frame())
         return 0;
-    
+
+    updateEditorUINowIfScheduled();
+
     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
 }
 
@@ -1407,17 +1406,35 @@ void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
     document->frame()->editor().toggleOverwriteModeEnabled();
 }
 
-#if ENABLE(INSPECTOR)
+unsigned Internals::countMatchesForText(const String& text, unsigned findOptions, const String& markMatches, ExceptionCode&)
+{
+    Document* document = contextDocument();
+    if (!document || !document->frame())
+        return 0;
+
+    bool mark = markMatches == "mark";
+    return document->frame()->editor().countMatchesForText(text, nullptr, findOptions, 1000, mark, nullptr);
+}
+
+const ProfilesArray& Internals::consoleProfiles() const
+{
+    return contextDocument()->page()->console().profiles();
+}
+
 unsigned Internals::numberOfLiveNodes() const
 {
-    return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
+    unsigned nodeCount = 0;
+    for (auto* document : Document::allDocuments())
+        nodeCount += document->referencingNodeCount();
+    return nodeCount;
 }
 
 unsigned Internals::numberOfLiveDocuments() const
 {
-    return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
+    return Document::allDocuments().size();
 }
 
+#if ENABLE(INSPECTOR)
 Vector<String> Internals::consoleMessageArgumentCounts() const
 {
     Document* document = contextDocument();
@@ -1427,9 +1444,11 @@ Vector<String> Internals::consoleMessageArgumentCounts() const
     InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
     if (!instrumentingAgents)
         return Vector<String>();
-    InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent();
+
+    InspectorConsoleAgent* consoleAgent = instrumentingAgents->webConsoleAgent();
     if (!consoleAgent)
         return Vector<String>();
+
     Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
     Vector<String> result(counts.size());
     for (size_t i = 0; i < counts.size(); i++)
@@ -1451,13 +1470,12 @@ PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
     Page* frontendPage = m_frontendWindow->document()->page();
     ASSERT(frontendPage);
 
-    auto frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
+    m_frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
+    frontendPage->inspectorController().setInspectorFrontendClient(m_frontendClient.get());
 
-    frontendPage->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
-
-    m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
-
-    page->inspectorController().connectFrontend(m_frontendChannel.get());
+    bool isAutomaticInspection = false;
+    m_frontendChannel = std::make_unique<InspectorFrontendChannelDummy>(frontendPage);
+    page->inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection);
 
     return m_frontendWindow;
 }
@@ -1470,23 +1488,25 @@ void Internals::closeDummyInspectorFrontend()
 
     page->inspectorController().disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
 
-    m_frontendChannel.release();
+    m_frontendClient = nullptr;
+    m_frontendChannel = nullptr;
 
     m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
-    m_frontendWindow.release();
+    m_frontendWindow.clear();
 }
 
-void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec)
+void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
 {
     Page* page = contextDocument()->frame()->page();
     if (!page) {
         ec = INVALID_ACCESS_ERR;
         return;
     }
-    page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
+
+    page->inspectorController().setProfilerEnabled(enabled);
 }
 
-void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
+void Internals::setInspectorIsUnderTest(bool isUnderTest, ExceptionCode& ec)
 {
     Page* page = contextDocument()->frame()->page();
     if (!page) {
@@ -1494,7 +1514,7 @@ void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
         return;
     }
 
-    page->inspectorController().setProfilerEnabled(enabled);
+    page->inspectorController().setIsUnderTest(isUnderTest);
 }
 #endif // ENABLE(INSPECTOR)
 
@@ -1654,7 +1674,7 @@ void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
     auto parsedSheet = StyleSheetContents::create(*document);
     parsedSheet.get().setIsUserStyleSheet(false);
     parsedSheet.get().parseString(css);
-    document->styleSheetCollection().addAuthorSheet(std::move(parsedSheet));
+    document->styleSheetCollection().addAuthorSheet(WTF::move(parsedSheet));
 }
 
 void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
@@ -1668,7 +1688,7 @@ void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
     auto parsedSheet = StyleSheetContents::create(*document);
     parsedSheet.get().setIsUserStyleSheet(true);
     parsedSheet.get().parseString(css);
-    document->styleSheetCollection().addUserSheet(std::move(parsedSheet));
+    document->styleSheetCollection().addUserSheet(WTF::move(parsedSheet));
 }
 
 String Internals::counterValue(Element* element)
@@ -1748,6 +1768,17 @@ void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCod
     page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
 }
 
+void Internals::setPageZoomFactor(float zoomFactor, ExceptionCode& ec)
+{
+    Document* document = contextDocument();
+    if (!document || !document->frame()) {
+        ec = INVALID_ACCESS_ERR;
+        return;
+    }
+    Frame* frame = document->frame();
+    frame->setPageZoomFactor(zoomFactor);
+}
+
 void Internals::setHeaderHeight(float height)
 {
     Document* document = contextDocument();
@@ -1767,6 +1798,16 @@ void Internals::setFooterHeight(float height)
     FrameView* frameView = document->view();
     frameView->setFooterHeight(height);
 }
+    
+void Internals::setTopContentInset(float contentInset)
+{
+    Document* document = contextDocument();
+    if (!document)
+        return;
+    
+    Page* page = document->page();
+    page->setTopContentInset(contentInset);
+}
 
 #if ENABLE(FULLSCREEN_API)
 void Internals::webkitWillEnterFullScreenForElement(Element* element)
@@ -1865,6 +1906,28 @@ void Internals::stopTrackingRepaints(ExceptionCode& ec)
     frameView->setTracksRepaints(false);
 }
 
+void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode& ec)
+{
+    updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(nullptr, ec);
+}
+
+void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node, ExceptionCode& ec)
+{
+    Document* document;
+    if (!node)
+        document = contextDocument();
+    else if (is<Document>(*node))
+        document = downcast<Document>(node);
+    else if (is<HTMLIFrameElement>(*node))
+        document = downcast<HTMLIFrameElement>(*node).contentDocument();
+    else {
+        ec = TypeError;
+        return;
+    }
+
+    document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
+}
+
 #if !PLATFORM(IOS)
 static const char* cursorTypeToString(Cursor::Type cursorType)
 {
@@ -1932,22 +1995,22 @@ String Internals::getCurrentCursorInfo(ExceptionCode& ec)
     Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
 
     StringBuilder result;
-    result.append("type=");
+    result.appendLiteral("type=");
     result.append(cursorTypeToString(cursor.type()));
-    result.append(" hotSpot=");
+    result.appendLiteral(" hotSpot=");
     result.appendNumber(cursor.hotSpot().x());
-    result.append(",");
+    result.append(',');
     result.appendNumber(cursor.hotSpot().y());
     if (cursor.image()) {
-        IntSize size = cursor.image()->size();
-        result.append(" image=");
+        FloatSize size = cursor.image()->size();
+        result.appendLiteral(" image=");
         result.appendNumber(size.width());
-        result.append("x");
+        result.append('x');
         result.appendNumber(size.height());
     }
 #if ENABLE(MOUSE_CURSOR_SCALE)
     if (cursor.imageScaleFactor() != 1) {
-        result.append(" scale=");
+        result.appendLiteral(" scale=");
         NumberToStringBuffer buffer;
         result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
     }
@@ -2010,7 +2073,7 @@ String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
 void Internals::simulateAudioInterruption(Node* node)
 {
 #if USE(GSTREAMER)
-    HTMLMediaElement* element = toHTMLMediaElement(node);
+    HTMLMediaElement* element = downcast<HTMLMediaElement>(node);
     element->player()->simulateAudioInterruption();
 #else
     UNUSED_PARAM(node);
@@ -2020,12 +2083,12 @@ void Internals::simulateAudioInterruption(Node* node)
 
 bool Internals::isSelectPopupVisible(Node* node)
 {
-    if (!isHTMLSelectElement(node))
+    if (!is<HTMLSelectElement>(*node))
         return false;
 
-    HTMLSelectElement* select = toHTMLSelectElement(node);
+    HTMLSelectElement& select = downcast<HTMLSelectElement>(*node);
 
-    auto renderer = select->renderer();
+    auto renderer = select.renderer();
     if (!renderer->isMenuList())
         return false;
 
@@ -2045,7 +2108,7 @@ String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
         return emptyString();
     }
 
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
+#if ENABLE(VIDEO_TRACK)
     return document->page()->group().captionPreferences()->captionsStyleSheetOverride();
 #else
     return emptyString();
@@ -2060,7 +2123,7 @@ void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionC
         return;
     }
 
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
+#if ENABLE(VIDEO_TRACK)
     document->page()->group().captionPreferences()->setCaptionsStyleSheetOverride(override);
 #else
     UNUSED_PARAM(override);
@@ -2075,7 +2138,7 @@ void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, Exc
         return;
     }
 
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
+#if ENABLE(VIDEO_TRACK)
     document->page()->group().captionPreferences()->setPrimaryAudioTrackLanguageOverride(language);
 #else
     UNUSED_PARAM(language);
@@ -2090,7 +2153,7 @@ void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
         return;
     }
     
-#if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
+#if ENABLE(VIDEO_TRACK)
     CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
     
     if (equalIgnoringCase(mode, "Automatic"))
@@ -2133,7 +2196,7 @@ PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
         return ClientRect::create();
     }
 
-    return ClientRect::create(document->frame()->selection().bounds());
+    return ClientRect::create(document->frame()->selection().selectionBounds());
 }
 
 #if ENABLE(VIBRATION)
@@ -2162,7 +2225,17 @@ bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, Except
     RenderEmbeddedObject* embed = toRenderEmbeddedObject(renderer);
     return embed->isReplacementObscured();
 }
-
+    
+bool Internals::isPluginSnapshotted(Element* element, ExceptionCode& ec)
+{
+    if (!element) {
+        ec = INVALID_ACCESS_ERR;
+        return false;
+    }
+    HTMLPlugInElement* pluginElement = downcast<HTMLPlugInElement>(element);
+    return pluginElement->displayState() <= HTMLPlugInElement::DisplayingSnapshot;
+}
+    
 #if ENABLE(MEDIA_SOURCE)
 void Internals::initializeMockMediaSource()
 {
@@ -2171,11 +2244,20 @@ void Internals::initializeMockMediaSource()
 #endif
     MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
 }
+
+Vector<String> Internals::bufferedSamplesForTrackID(SourceBuffer* buffer, const AtomicString& trackID)
+{
+    if (!buffer)
+        return Vector<String>();
+
+    return buffer->bufferedSamplesForTrackID(trackID);
+}
 #endif
 
+#if ENABLE(VIDEO)
 void Internals::beginMediaSessionInterruption()
 {
-    MediaSessionManager::sharedManager().beginInterruption();
+    MediaSessionManager::sharedManager().beginInterruption(MediaSession::SystemInterruption);
 }
 
 void Internals::endMediaSessionInterruption(const String& flagsString)
@@ -2230,5 +2312,48 @@ void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const
 
     MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
 }
+    
+void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
+{
+    MediaSession::RemoteControlCommandType command;
+    
+    if (equalIgnoringCase(commandString, "Play"))
+        command = MediaSession::PlayCommand;
+    else if (equalIgnoringCase(commandString, "Pause"))
+        command = MediaSession::PauseCommand;
+    else if (equalIgnoringCase(commandString, "Stop"))
+        command = MediaSession::StopCommand;
+    else if (equalIgnoringCase(commandString, "TogglePlayPause"))
+        command = MediaSession::TogglePlayPauseCommand;
+    else if (equalIgnoringCase(commandString, "BeginSeekingBackward"))
+        command = MediaSession::BeginSeekingBackwardCommand;
+    else if (equalIgnoringCase(commandString, "EndSeekingBackward"))
+        command = MediaSession::EndSeekingBackwardCommand;
+    else if (equalIgnoringCase(commandString, "BeginSeekingForward"))
+        command = MediaSession::BeginSeekingForwardCommand;
+    else if (equalIgnoringCase(commandString, "EndSeekingForward"))
+        command = MediaSession::EndSeekingForwardCommand;
+    else {
+        ec = INVALID_ACCESS_ERR;
+        return;
+    }
+    
+    MediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
+}
+#endif // ENABLE(VIDEO)
+
+void Internals::simulateSystemSleep() const
+{
+#if ENABLE(VIDEO)
+    MediaSessionManager::sharedManager().systemWillSleep();
+#endif
+}
+
+void Internals::simulateSystemWake() const
+{
+#if ENABLE(VIDEO)
+    MediaSessionManager::sharedManager().systemDidWake();
+#endif
+}
 
 }