REGRESSION(r179429): Can't type comments in Facebook
[WebKit-https.git] / Source / WebCore / inspector / InspectorFrontendClientLocal.cpp
index dbee707..415ff7c 100644 (file)
  */
 
 #include "config.h"
-
-#if ENABLE(INSPECTOR)
-
 #include "InspectorFrontendClientLocal.h"
 
 #include "Chrome.h"
+#include "DOMWrapperWorld.h"
 #include "Document.h"
 #include "FloatRect.h"
-#include "Frame.h"
 #include "FrameLoadRequest.h"
 #include "FrameLoader.h"
 #include "FrameView.h"
-#include "InspectorBackendDispatcher.h"
 #include "InspectorController.h"
 #include "InspectorFrontendHost.h"
 #include "InspectorPageAgent.h"
+#include "MainFrame.h"
 #include "Page.h"
-#include "ScriptFunctionCall.h"
-#include "ScriptObject.h"
+#include "ScriptController.h"
+#include "ScriptGlobalObject.h"
 #include "ScriptState.h"
 #include "Settings.h"
 #include "Timer.h"
 #include "UserGestureIndicator.h"
 #include "WindowFeatures.h"
+#include <bindings/ScriptValue.h>
+#include <inspector/InspectorBackendDispatchers.h>
 #include <wtf/Deque.h>
 #include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
+
+using namespace Inspector;
 
 namespace WebCore {
 
@@ -63,13 +63,15 @@ static const char* inspectorAttachedHeightSetting = "inspectorAttachedHeight";
 static const unsigned defaultAttachedHeight = 300;
 static const float minimumAttachedHeight = 250.0f;
 static const float maximumAttachedHeightRatio = 0.75f;
+static const float minimumAttachedWidth = 750.0f;
+static const float minimumAttachedInspectedWidth = 320.0f;
 
 class InspectorBackendDispatchTask {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     InspectorBackendDispatchTask(InspectorController* inspectorController)
         : m_inspectorController(inspectorController)
-        , m_timer(this, &InspectorBackendDispatchTask::onTimer)
+        , m_timer(*this, &InspectorBackendDispatchTask::timerFired)
     {
     }
 
@@ -86,7 +88,7 @@ public:
         m_timer.stop();
     }
 
-    void onTimer(Timer<InspectorBackendDispatchTask>*)
+    void timerFired()
     {
         if (!m_messages.isEmpty()) {
             // Dispatch can lead to the timer destruction -> schedule the next shot first.
@@ -97,7 +99,7 @@ public:
 
 private:
     InspectorController* m_inspectorController;
-    Timer<InspectorBackendDispatchTask> m_timer;
+    Timer m_timer;
     Deque<String> m_messages;
 };
 
@@ -110,14 +112,18 @@ void InspectorFrontendClientLocal::Settings::setProperty(const String&, const St
 {
 }
 
-InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectorController, Page* frontendPage, PassOwnPtr<Settings> settings)
+InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectorController, Page* frontendPage, std::unique_ptr<Settings> settings)
     : m_inspectorController(inspectorController)
     , m_frontendPage(frontendPage)
-    , m_settings(settings)
+    , m_settings(WTF::move(settings))
     , m_frontendLoaded(false)
+    , m_dockSide(DockSide::Undocked)
 {
-    m_frontendPage->settings()->setAllowFileAccessFromFileURLs(true);
-    m_dispatchTask = adoptPtr(new InspectorBackendDispatchTask(inspectorController));
+    m_frontendPage->settings().setAllowFileAccessFromFileURLs(true);
+    m_frontendPage->settings().setJavaScriptRuntimeFlags({
+        JSC::RuntimeFlags::SymbolEnabled
+    });
+    m_dispatchTask = std::make_unique<InspectorBackendDispatchTask>(inspectorController);
 }
 
 InspectorFrontendClientLocal::~InspectorFrontendClientLocal()
@@ -133,15 +139,19 @@ void InspectorFrontendClientLocal::windowObjectCleared()
     if (m_frontendHost)
         m_frontendHost->disconnectClient();
     
-    ScriptState* frontendScriptState = scriptStateFromPage(debuggerWorld(), m_frontendPage);
+    JSC::ExecState* frontendExecState = execStateFromPage(debuggerWorld(), m_frontendPage);
     m_frontendHost = InspectorFrontendHost::create(this, m_frontendPage);
-    ScriptGlobalObject::set(frontendScriptState, "InspectorFrontendHost", m_frontendHost.get());
+    ScriptGlobalObject::set(frontendExecState, "InspectorFrontendHost", m_frontendHost.get());
 }
 
 void InspectorFrontendClientLocal::frontendLoaded()
 {
-    bringToFront();
+    // Call setDockingUnavailable before bringToFront. If we display the inspector window via bringToFront first it causes
+    // the call to canAttachWindow to return the wrong result on Windows.
+    // Calling bringToFront first causes the visibleHeight of the inspected page to always return 0 immediately after. 
+    // Thus if we call canAttachWindow first we can avoid this problem. This change does not cause any regressions on Mac.
     setDockingUnavailable(!canAttachWindow());
+    bringToFront();
     m_frontendLoaded = true;
     for (Vector<String>::iterator it = m_evaluateOnLoad.begin(); it != m_evaluateOnLoad.end(); ++it)
         evaluateOnLoad(*it);
@@ -150,23 +160,31 @@ void InspectorFrontendClientLocal::frontendLoaded()
 
 void InspectorFrontendClientLocal::requestSetDockSide(DockSide dockSide)
 {
-    if (dockSide == UNDOCKED) {
+    if (dockSide == DockSide::Undocked) {
         detachWindow();
-        setAttachedWindow(false);
+        setAttachedWindow(dockSide);
     } else if (canAttachWindow()) {
-        attachWindow();
-        setAttachedWindow(true);
+        attachWindow(dockSide);
+        setAttachedWindow(dockSide);
     }
 }
 
 bool InspectorFrontendClientLocal::canAttachWindow()
 {
-    // Don't allow the attach if the window would be too small to accommodate the minimum inspector height.
-    // Also don't allow attaching to another inspector -- two inspectors in one window is too much!
-    bool isInspectorPage = m_inspectorController->inspectedPage()->inspectorController()->hasInspectorFrontendClient();
-    unsigned inspectedPageHeight = m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight();
+    // Don't allow attaching to another inspector -- two inspectors in one window is too much!
+    bool isInspectorPage = m_inspectorController->hasInspectorFrontendClient();
+    if (isInspectorPage)
+        return false;
+
+    // If we are already attached, allow attaching again to allow switching sides.
+    if (m_dockSide != DockSide::Undocked)
+        return true;
+
+    // Don't allow the attach if the window would be too small to accommodate the minimum inspector size.
+    unsigned inspectedPageHeight = m_inspectorController->inspectedPage().mainFrame().view()->visibleHeight();
+    unsigned inspectedPageWidth = m_inspectorController->inspectedPage().mainFrame().view()->visibleWidth();
     unsigned maximumAttachedHeight = inspectedPageHeight * maximumAttachedHeightRatio;
-    return minimumAttachedHeight <= maximumAttachedHeight && !isInspectorPage;
+    return minimumAttachedHeight <= maximumAttachedHeight && minimumAttachedWidth <= inspectedPageWidth;
 }
 
 void InspectorFrontendClientLocal::setDockingUnavailable(bool unavailable)
@@ -176,47 +194,68 @@ void InspectorFrontendClientLocal::setDockingUnavailable(bool unavailable)
 
 void InspectorFrontendClientLocal::changeAttachedWindowHeight(unsigned height)
 {
-    unsigned totalHeight = m_frontendPage->mainFrame()->view()->visibleHeight() + m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight();
+    unsigned totalHeight = m_frontendPage->mainFrame().view()->visibleHeight() + m_inspectorController->inspectedPage().mainFrame().view()->visibleHeight();
     unsigned attachedHeight = constrainedAttachedWindowHeight(height, totalHeight);
     m_settings->setProperty(inspectorAttachedHeightSetting, String::number(attachedHeight));
     setAttachedWindowHeight(attachedHeight);
 }
 
+void InspectorFrontendClientLocal::changeAttachedWindowWidth(unsigned width)
+{
+    unsigned totalWidth = m_frontendPage->mainFrame().view()->visibleWidth() + m_inspectorController->inspectedPage().mainFrame().view()->visibleWidth();
+    unsigned attachedWidth = constrainedAttachedWindowWidth(width, totalWidth);
+    setAttachedWindowWidth(attachedWidth);
+}
+
 void InspectorFrontendClientLocal::openInNewTab(const String& url)
 {
     UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
-    Page* page = m_inspectorController->inspectedPage();
-    Frame* mainFrame = page->mainFrame();
-    FrameLoadRequest request(mainFrame->document()->securityOrigin(), ResourceRequest(), "_blank");
+    Frame& mainFrame = m_inspectorController->inspectedPage().mainFrame();
+    FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank");
 
     bool created;
     WindowFeatures windowFeatures;
-    Frame* frame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created);
+    RefPtr<Frame> frame = WebCore::createWindow(&mainFrame, &mainFrame, request, windowFeatures, created);
     if (!frame)
         return;
 
-    frame->loader()->setOpener(mainFrame);
+    frame->loader().setOpener(&mainFrame);
     frame->page()->setOpenedByDOM();
 
     // FIXME: Why does one use mainFrame and the other frame?
-    frame->loader()->changeLocation(mainFrame->document()->securityOrigin(), frame->document()->completeURL(url), "", false, false);
+    frame->loader().changeLocation(mainFrame.document()->securityOrigin(), frame->document()->completeURL(url), "", LockHistory::No, LockBackForwardList::No);
 }
 
 void InspectorFrontendClientLocal::moveWindowBy(float x, float y)
 {
-    FloatRect frameRect = m_frontendPage->chrome()->windowRect();
+    FloatRect frameRect = m_frontendPage->chrome().windowRect();
     frameRect.move(x, y);
-    m_frontendPage->chrome()->setWindowRect(frameRect);
+    m_frontendPage->chrome().setWindowRect(frameRect);
 }
 
-void InspectorFrontendClientLocal::setAttachedWindow(bool attached)
+void InspectorFrontendClientLocal::setAttachedWindow(DockSide dockSide)
 {
-    evaluateOnLoad(String::format("[\"setDockSide\", %s]", attached ? "bottom" : "undocked"));
+    const char* side = "undocked";
+    switch (dockSide) {
+    case DockSide::Undocked:
+        side = "undocked";
+        break;
+    case DockSide::Right:
+        side = "right";
+        break;
+    case DockSide::Bottom:
+        side = "bottom";
+        break;
+    }
+
+    m_dockSide = dockSide;
+
+    evaluateOnLoad(String::format("[\"setDockSide\", \"%s\"]", side));
 }
 
 void InspectorFrontendClientLocal::restoreAttachedWindowHeight()
 {
-    unsigned inspectedPageHeight = m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight();
+    unsigned inspectedPageHeight = m_inspectorController->inspectedPage().mainFrame().view()->visibleHeight();
     String value = m_settings->getProperty(inspectorAttachedHeightSetting);
     unsigned preferredHeight = value.isEmpty() ? defaultAttachedHeight : value.toUInt();
     
@@ -285,8 +324,12 @@ void InspectorFrontendClientLocal::showMainResourceForFrame(Frame* frame)
 
 unsigned InspectorFrontendClientLocal::constrainedAttachedWindowHeight(unsigned preferredHeight, unsigned totalWindowHeight)
 {
-    using namespace std;
-    return roundf(max(minimumAttachedHeight, min<float>(preferredHeight, totalWindowHeight * maximumAttachedHeightRatio)));
+    return roundf(std::max(minimumAttachedHeight, std::min<float>(preferredHeight, totalWindowHeight * maximumAttachedHeightRatio)));
+}
+
+unsigned InspectorFrontendClientLocal::constrainedAttachedWindowWidth(unsigned preferredWidth, unsigned totalWindowWidth)
+{
+    return roundf(std::max(minimumAttachedWidth, std::min<float>(preferredWidth, totalWindowWidth - minimumAttachedInspectedWidth)));
 }
 
 void InspectorFrontendClientLocal::sendMessageToBackend(const String& message)
@@ -294,22 +337,23 @@ void InspectorFrontendClientLocal::sendMessageToBackend(const String& message)
     m_dispatchTask->dispatch(message);
 }
 
+bool InspectorFrontendClientLocal::isUnderTest()
+{
+    return m_inspectorController->isUnderTest();
+}
+
 bool InspectorFrontendClientLocal::evaluateAsBoolean(const String& expression)
 {
-    if (!m_frontendPage->mainFrame())
-        return false;
-    ScriptValue value = m_frontendPage->mainFrame()->script()->executeScript(expression);
-    return value.toString(mainWorldScriptState(m_frontendPage->mainFrame())) == "true";
+    Deprecated::ScriptValue value = m_frontendPage->mainFrame().script().executeScript(expression);
+    return value.toString(mainWorldExecState(&m_frontendPage->mainFrame())) == "true";
 }
 
 void InspectorFrontendClientLocal::evaluateOnLoad(const String& expression)
 {
     if (m_frontendLoaded)
-        m_frontendPage->mainFrame()->script()->executeScript("InspectorFrontendAPI.dispatch(" + expression + ")");
+        m_frontendPage->mainFrame().script().executeScript("InspectorFrontendAPI.dispatch(" + expression + ")");
     else
         m_evaluateOnLoad.append(expression);
 }
 
 } // namespace WebCore
-
-#endif