1/*
2 * Copyright (C) 2010, 2014, 2016 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include "APIObject.h"
30#include "Attachment.h"
31#include "MessageReceiver.h"
32#include "WebInspectorUtilities.h"
33#include <JavaScriptCore/InspectorFrontendChannel.h>
34#include <WebCore/FloatRect.h>
35#include <wtf/Forward.h>
36#include <wtf/RefPtr.h>
37#include <wtf/text/WTFString.h>
38
39#if PLATFORM(MAC)
40#include "WKGeometry.h"
41#include <WebCore/IntRect.h>
42#include <wtf/HashMap.h>
43#include <wtf/RetainPtr.h>
44#include <wtf/RunLoop.h>
45
46OBJC_CLASS NSURL;
47OBJC_CLASS NSView;
48OBJC_CLASS NSWindow;
49OBJC_CLASS WKWebInspectorProxyObjCAdapter;
50OBJC_CLASS WKInspectorViewController;
51#elif PLATFORM(WIN)
52#include "WebView.h"
53#endif
54
55namespace WebCore {
56class CertificateInfo;
57}
58
59namespace WebKit {
60
61class WebFrameProxy;
62class WebInspectorProxyClient;
63class WebPageProxy;
64class WebPreferences;
65
66enum class AttachmentSide {
67 Bottom,
68 Right,
69 Left,
70};
71
72class WebInspectorProxy
73 : public API::ObjectImpl<API::Object::Type::Inspector>
74 , public IPC::MessageReceiver
75 , public Inspector::FrontendChannel
76#if PLATFORM(WIN)
77 , public WebCore::WindowMessageListener
78#endif
79{
80public:
81 static Ref<WebInspectorProxy> create(WebPageProxy* inspectedPage)
82 {
83 return adoptRef(*new WebInspectorProxy(inspectedPage));
84 }
85
86 ~WebInspectorProxy();
87
88 void invalidate();
89
90 // Public APIs
91 WebPageProxy* inspectedPage() const { return m_inspectedPage; }
92
93 bool isConnected() const { return !!m_inspectorPage; }
94 bool isVisible() const { return m_isVisible; }
95 bool isFront();
96
97 void connect();
98
99 void show();
100 void hide();
101 void close();
102 void closeForCrash();
103 void reopen();
104
105 void reset();
106 void updateForNewPageProcess(WebPageProxy*);
107
108#if PLATFORM(MAC)
109 enum class InspectionTargetType { Local, Remote };
110 static RetainPtr<NSWindow> createFrontendWindow(NSRect savedWindowFrame, InspectionTargetType);
111
112 void updateInspectorWindowTitle() const;
113 void inspectedViewFrameDidChange(CGFloat = 0);
114 void windowFrameDidChange();
115 void windowFullScreenDidChange();
116 NSWindow* inspectorWindow() const { return m_inspectorWindow.get(); }
117
118 void closeFrontendPage();
119 void closeFrontendAfterInactivityTimerFired();
120
121 void attachmentViewDidChange(NSView *oldView, NSView *newView);
122 void attachmentWillMoveFromWindow(NSWindow *oldWindow);
123 void attachmentDidMoveToWindow(NSWindow *newWindow);
124
125 const WebCore::FloatRect& sheetRect() const { return m_sheetRect; }
126#endif
127
128#if PLATFORM(GTK)
129 GtkWidget* inspectorView() const { return m_inspectorView; };
130 void setClient(std::unique_ptr<WebInspectorProxyClient>&&);
131#endif
132
133 void showConsole();
134 void showResources();
135 void showTimelines();
136 void showMainResourceForFrame(WebFrameProxy*);
137
138 AttachmentSide attachmentSide() const { return m_attachmentSide; }
139 bool isAttached() const { return m_isAttached; }
140 void attachRight();
141 void attachLeft();
142 void attachBottom();
143 void attach(AttachmentSide = AttachmentSide::Bottom);
144 void detach();
145
146 void setAttachedWindowHeight(unsigned);
147 void setAttachedWindowWidth(unsigned);
148
149 void setSheetRect(const WebCore::FloatRect&);
150
151 void startWindowDrag();
152
153 bool isProfilingPage() const { return m_isProfilingPage; }
154 void togglePageProfiling();
155
156 bool isElementSelectionActive() const { return m_elementSelectionActive; }
157 void toggleElementSelection();
158
159 bool isUnderTest() const { return m_underTest; }
160
161 // Provided by platform WebInspectorProxy implementations.
162 static String inspectorPageURL();
163 static String inspectorTestPageURL();
164 static String inspectorBaseURL();
165 static bool isMainOrTestInspectorPage(const URL&);
166
167 static const unsigned minimumWindowWidth;
168 static const unsigned minimumWindowHeight;
169
170 static const unsigned initialWindowWidth;
171 static const unsigned initialWindowHeight;
172
173private:
174 explicit WebInspectorProxy(WebPageProxy*);
175
176 void createFrontendPage();
177 void closeFrontendPageAndWindow();
178
179 // IPC::MessageReceiver
180 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
181
182 // Inspector::FrontendChannel
183 void sendMessageToFrontend(const String& message) override;
184 ConnectionType connectionType() const override { return ConnectionType::Local; }
185
186 WebPageProxy* platformCreateFrontendPage();
187 void platformCreateFrontendWindow();
188 void platformCloseFrontendPageAndWindow();
189
190 void platformDidCloseForCrash();
191 void platformInvalidate();
192 void platformBringToFront();
193 void platformBringInspectedPageToFront();
194 void platformHide();
195 bool platformIsFront();
196 void platformAttachAvailabilityChanged(bool);
197 void platformInspectedURLChanged(const String&);
198 void platformShowCertificate(const WebCore::CertificateInfo&);
199 unsigned platformInspectedWindowHeight();
200 unsigned platformInspectedWindowWidth();
201 void platformAttach();
202 void platformDetach();
203 void platformSetAttachedWindowHeight(unsigned);
204 void platformSetAttachedWindowWidth(unsigned);
205 void platformSetSheetRect(const WebCore::FloatRect&);
206 void platformStartWindowDrag();
207 void platformSave(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs);
208 void platformAppend(const String& filename, const String& content);
209
210#if PLATFORM(MAC)
211 bool platformCanAttach(bool webProcessCanAttach);
212#else
213 bool platformCanAttach(bool webProcessCanAttach) { return webProcessCanAttach; }
214#endif
215
216 // Called by WebInspectorProxy messages
217 void openLocalInspectorFrontend(bool canAttach, bool underTest);
218 void setFrontendConnection(IPC::Attachment);
219
220 void sendMessageToBackend(const String&);
221 void frontendLoaded();
222 void didClose();
223 void bringToFront();
224 void attachAvailabilityChanged(bool);
225 void inspectedURLChanged(const String&);
226 void showCertificate(const WebCore::CertificateInfo&);
227 void elementSelectionChanged(bool);
228
229 void save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs);
230 void append(const String& filename, const String& content);
231
232 bool canAttach() const { return m_canAttach; }
233 bool shouldOpenAttached();
234
235 void open();
236
237 unsigned inspectionLevel() const;
238
239 WebPreferences& inspectorPagePreferences() const;
240
241#if PLATFORM(GTK) || PLATFORM(WPE)
242 void updateInspectorWindowTitle() const;
243#endif
244
245#if PLATFORM(WIN)
246 static LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
247 bool registerWindowClass();
248 void windowReceivedMessage(HWND, UINT, WPARAM, LPARAM) override;
249#endif
250
251 WebPageProxy* m_inspectedPage { nullptr };
252 WebPageProxy* m_inspectorPage { nullptr };
253
254 bool m_underTest { false };
255 bool m_isVisible { false };
256 bool m_isAttached { false };
257 bool m_canAttach { false };
258 bool m_isProfilingPage { false };
259 bool m_showMessageSent { false };
260 bool m_ignoreFirstBringToFront { false };
261 bool m_elementSelectionActive { false };
262 bool m_ignoreElementSelectionChange { false };
263 bool m_isOpening { false };
264 bool m_isActiveFrontend { false };
265
266 AttachmentSide m_attachmentSide {AttachmentSide::Bottom};
267
268#if PLATFORM(MAC)
269 RetainPtr<WKInspectorViewController> m_inspectorViewController;
270 RetainPtr<NSWindow> m_inspectorWindow;
271 RetainPtr<WKWebInspectorProxyObjCAdapter> m_objCAdapter;
272 HashMap<String, RetainPtr<NSURL>> m_suggestedToActualURLMap;
273 RunLoop::Timer<WebInspectorProxy> m_closeFrontendAfterInactivityTimer;
274 String m_urlString;
275 WebCore::FloatRect m_sheetRect;
276 bool m_isObservingContentLayoutRect { false };
277#elif PLATFORM(GTK)
278 std::unique_ptr<WebInspectorProxyClient> m_client;
279 GtkWidget* m_inspectorView { nullptr };
280 GtkWidget* m_inspectorWindow { nullptr };
281 GtkWidget* m_headerBar { nullptr };
282 String m_inspectedURLString;
283#elif PLATFORM(WIN)
284 HWND m_inspectedViewWindow { nullptr };
285 HWND m_inspectedViewParentWindow { nullptr };
286 HWND m_inspectorViewWindow { nullptr };
287 HWND m_inspectorDetachWindow { nullptr };
288 RefPtr<WebView> m_inspectorView;
289#endif
290};
291
292} // namespace WebKit
293