InspectorFrontendClientLocal.cpp revision cad810f21b803229eb11403f9209855525a25d57
1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "InspectorFrontendClientLocal.h"
33
34#if ENABLE(INSPECTOR)
35
36#include "Chrome.h"
37#include "FloatRect.h"
38#include "Frame.h"
39#include "FrameView.h"
40#include "InspectorBackendDispatcher.h"
41#include "InspectorController.h"
42#include "InspectorFrontendHost.h"
43#include "Page.h"
44#include "PlatformString.h"
45#include "ScriptFunctionCall.h"
46#include "ScriptObject.h"
47
48namespace WebCore {
49
50static const unsigned defaultAttachedHeight = 300;
51static const float minimumAttachedHeight = 250.0f;
52static const float maximumAttachedHeightRatio = 0.75f;
53
54InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectorController, Page* frontendPage)
55    : m_inspectorController(inspectorController)
56    , m_frontendPage(frontendPage)
57    , m_frontendScriptState(0)
58{
59}
60
61InspectorFrontendClientLocal::~InspectorFrontendClientLocal()
62{
63    if (m_frontendHost)
64        m_frontendHost->disconnectClient();
65    m_frontendScriptState = 0;
66    m_frontendPage = 0;
67    m_inspectorController = 0;
68}
69
70void InspectorFrontendClientLocal::windowObjectCleared()
71{
72    // FIXME: don't keep reference to the script state
73    m_frontendScriptState = scriptStateFromPage(debuggerWorld(), m_frontendPage);
74    m_frontendHost = InspectorFrontendHost::create(this, m_frontendPage);
75    ScriptGlobalObject::set(m_frontendScriptState, "InspectorFrontendHost", m_frontendHost.get());
76}
77
78void InspectorFrontendClientLocal::frontendLoaded()
79{
80    bringToFront();
81    m_inspectorController->connectFrontend();
82}
83
84void InspectorFrontendClientLocal::requestAttachWindow()
85{
86    if (!canAttachWindow())
87        return;
88    attachWindow();
89    setAttachedWindow(true);
90}
91
92void InspectorFrontendClientLocal::requestDetachWindow()
93{
94    detachWindow();
95    setAttachedWindow(false);
96}
97
98bool InspectorFrontendClientLocal::canAttachWindow()
99{
100    unsigned inspectedPageHeight = m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight();
101
102    // Don't allow the attach if the window would be too small to accommodate the minimum inspector height.
103    return minimumAttachedHeight <= inspectedPageHeight * maximumAttachedHeightRatio;
104}
105
106void InspectorFrontendClientLocal::changeAttachedWindowHeight(unsigned height)
107{
108    unsigned totalHeight = m_frontendPage->mainFrame()->view()->visibleHeight() + m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight();
109    unsigned attachedHeight = constrainedAttachedWindowHeight(height, totalHeight);
110    m_inspectorController->setInspectorAttachedHeight(attachedHeight);
111    setAttachedWindowHeight(attachedHeight);
112}
113
114void InspectorFrontendClientLocal::moveWindowBy(float x, float y)
115{
116    FloatRect frameRect = m_frontendPage->chrome()->windowRect();
117    frameRect.move(x, y);
118    m_frontendPage->chrome()->setWindowRect(frameRect);
119}
120
121void InspectorFrontendClientLocal::setAttachedWindow(bool attached)
122{
123    ScriptObject webInspectorObj;
124    if (!ScriptGlobalObject::get(m_frontendScriptState, "WebInspector", webInspectorObj)) {
125        ASSERT_NOT_REACHED();
126        return;
127    }
128    ScriptFunctionCall function(webInspectorObj, "setAttachedWindow");
129    function.appendArgument(attached);
130    function.call();
131}
132
133void InspectorFrontendClientLocal::restoreAttachedWindowHeight()
134{
135    unsigned inspectedPageHeight = m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight();
136    int attachedHeight = m_inspectorController->inspectorAttachedHeight();
137    bool success = true;
138    unsigned preferredHeight = success ? static_cast<unsigned>(attachedHeight) : defaultAttachedHeight;
139
140    // This call might not go through (if the window starts out detached), but if the window is initially created attached,
141    // InspectorController::attachWindow is never called, so we need to make sure to set the attachedWindowHeight.
142    // FIXME: Clean up code so we only have to call setAttachedWindowHeight in InspectorController::attachWindow
143    setAttachedWindowHeight(constrainedAttachedWindowHeight(preferredHeight, inspectedPageHeight));
144}
145
146unsigned InspectorFrontendClientLocal::constrainedAttachedWindowHeight(unsigned preferredHeight, unsigned totalWindowHeight)
147{
148    using namespace std;
149    return roundf(max(minimumAttachedHeight, min<float>(preferredHeight, totalWindowHeight * maximumAttachedHeightRatio)));
150}
151
152void InspectorFrontendClientLocal::sendMessageToBackend(const String& message)
153{
154    m_inspectorController->inspectorBackendDispatcher()->dispatch(message);
155}
156
157} // namespace WebCore
158
159#endif
160