Web Inspector: Remove unused WebInspectorProxy code
[WebKit-https.git] / Source / WebKit / UIProcess / WebInspectorProxy.cpp
1 /*
2  * Copyright (C) 2010-2017 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 #include "config.h"
28 #include "WebInspectorProxy.h"
29
30 #include "APINavigation.h"
31 #include "APIProcessPoolConfiguration.h"
32 #include "WebAutomationSession.h"
33 #include "WebFrameProxy.h"
34 #include "WebInspectorInterruptDispatcherMessages.h"
35 #include "WebInspectorMessages.h"
36 #include "WebInspectorProxyMessages.h"
37 #include "WebInspectorUIMessages.h"
38 #include "WebPageGroup.h"
39 #include "WebPageProxy.h"
40 #include "WebPreferences.h"
41 #include "WebProcessPool.h"
42 #include "WebProcessProxy.h"
43 #include <WebCore/NotImplemented.h>
44 #include <WebCore/TextEncoding.h>
45 #include <wtf/SetForScope.h>
46
47 #if PLATFORM(GTK)
48 #include "WebInspectorProxyClient.h"
49 #endif
50
51 namespace WebKit {
52 using namespace WebCore;
53
54 const unsigned WebInspectorProxy::minimumWindowWidth = 500;
55 const unsigned WebInspectorProxy::minimumWindowHeight = 400;
56
57 const unsigned WebInspectorProxy::initialWindowWidth = 1000;
58 const unsigned WebInspectorProxy::initialWindowHeight = 650;
59
60 WebInspectorProxy::WebInspectorProxy(WebPageProxy* inspectedPage)
61     : m_inspectedPage(inspectedPage)
62 #if PLATFORM(MAC) && WK_API_ENABLED
63     , m_closeFrontendAfterInactivityTimer(RunLoop::main(), this, &WebInspectorProxy::closeFrontendAfterInactivityTimerFired)
64 #endif
65 {
66     m_inspectedPage->process().addMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID(), *this);
67 }
68
69 WebInspectorProxy::~WebInspectorProxy()
70 {
71 }
72
73 unsigned WebInspectorProxy::inspectionLevel() const
74 {
75     return inspectorLevelForPage(inspectedPage());
76 }
77
78 WebPreferences& WebInspectorProxy::inspectorPagePreferences() const
79 {
80     ASSERT(m_inspectorPage);
81     return m_inspectorPage->pageGroup().preferences();
82 }
83
84 void WebInspectorProxy::invalidate()
85 {
86     m_inspectedPage->process().removeMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID());
87
88     closeFrontendPageAndWindow();
89     platformInvalidate();
90
91     m_inspectedPage = nullptr;
92 }
93
94 // Public APIs
95 bool WebInspectorProxy::isFront()
96 {
97     if (!m_inspectedPage)
98         return false;
99
100     return platformIsFront();
101 }
102
103 void WebInspectorProxy::connect()
104 {
105     if (!m_inspectedPage)
106         return;
107
108     if (m_showMessageSent)
109         return;
110
111     m_showMessageSent = true;
112     m_ignoreFirstBringToFront = true;
113
114     createFrontendPage();
115
116     m_inspectedPage->process().send(Messages::WebInspectorInterruptDispatcher::NotifyNeedDebuggerBreak(), 0);
117     m_inspectedPage->process().send(Messages::WebInspector::Show(), m_inspectedPage->pageID());
118 }
119
120 void WebInspectorProxy::show()
121 {
122     if (!m_inspectedPage)
123         return;
124
125     if (isConnected()) {
126         bringToFront();
127         return;
128     }
129
130     connect();
131
132     // Don't ignore the first bringToFront so it opens the Inspector.
133     m_ignoreFirstBringToFront = false;
134 }
135
136 void WebInspectorProxy::hide()
137 {
138     if (!m_inspectedPage)
139         return;
140
141     m_isVisible = false;
142
143     platformHide();
144 }
145
146 void WebInspectorProxy::close()
147 {
148     if (!m_inspectedPage)
149         return;
150
151     m_inspectedPage->process().send(Messages::WebInspector::Close(), m_inspectedPage->pageID());
152
153     closeFrontendPageAndWindow();
154 }
155
156 void WebInspectorProxy::closeForCrash()
157 {
158     close();
159
160     platformDidCloseForCrash();
161 }
162
163 void WebInspectorProxy::showConsole()
164 {
165     if (!m_inspectedPage)
166         return;
167
168     createFrontendPage();
169
170     m_inspectedPage->process().send(Messages::WebInspector::ShowConsole(), m_inspectedPage->pageID());
171 }
172
173 void WebInspectorProxy::showResources()
174 {
175     if (!m_inspectedPage)
176         return;
177
178     createFrontendPage();
179
180     m_inspectedPage->process().send(Messages::WebInspector::ShowResources(), m_inspectedPage->pageID());
181 }
182
183 void WebInspectorProxy::showTimelines()
184 {
185     if (!m_inspectedPage)
186         return;
187
188     createFrontendPage();
189
190     m_inspectedPage->process().send(Messages::WebInspector::ShowTimelines(), m_inspectedPage->pageID());
191 }
192
193 void WebInspectorProxy::showMainResourceForFrame(WebFrameProxy* frame)
194 {
195     if (!m_inspectedPage)
196         return;
197
198     createFrontendPage();
199
200     m_inspectedPage->process().send(Messages::WebInspector::ShowMainResourceForFrame(frame->frameID()), m_inspectedPage->pageID());
201 }
202
203 void WebInspectorProxy::attachBottom()
204 {
205     attach(AttachmentSide::Bottom);
206 }
207
208 void WebInspectorProxy::attachRight()
209 {
210     attach(AttachmentSide::Right);
211 }
212
213 void WebInspectorProxy::attachLeft()
214 {
215     attach(AttachmentSide::Left);
216 }
217
218 void WebInspectorProxy::attach(AttachmentSide side)
219 {
220     if (!m_inspectedPage || !canAttach())
221         return;
222
223     m_isAttached = true;
224     m_attachmentSide = side;
225
226     inspectorPagePreferences().setInspectorAttachmentSide(static_cast<uint32_t>(side));
227
228     if (m_isVisible)
229         inspectorPagePreferences().setInspectorStartsAttached(true);
230
231     m_inspectedPage->process().send(Messages::WebInspector::SetAttached(true), m_inspectedPage->pageID());
232
233     switch (m_attachmentSide) {
234     case AttachmentSide::Bottom:
235         m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedBottom(), m_inspectorPage->pageID());
236         break;
237
238     case AttachmentSide::Right:
239         m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedRight(), m_inspectorPage->pageID());
240         break;
241
242     case AttachmentSide::Left:
243         m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedLeft(), m_inspectorPage->pageID());
244         break;
245     }
246
247     platformAttach();
248 }
249
250 void WebInspectorProxy::detach()
251 {
252     if (!m_inspectedPage)
253         return;
254
255     m_isAttached = false;
256
257     if (m_isVisible)
258         inspectorPagePreferences().setInspectorStartsAttached(false);
259
260     m_inspectedPage->process().send(Messages::WebInspector::SetAttached(false), m_inspectedPage->pageID());
261     m_inspectorPage->process().send(Messages::WebInspectorUI::Detached(), m_inspectorPage->pageID());
262
263     platformDetach();
264 }
265
266 void WebInspectorProxy::setAttachedWindowHeight(unsigned height)
267 {
268     inspectorPagePreferences().setInspectorAttachedHeight(height);
269     platformSetAttachedWindowHeight(height);
270 }
271
272 void WebInspectorProxy::setAttachedWindowWidth(unsigned width)
273 {
274     inspectorPagePreferences().setInspectorAttachedWidth(width);
275     platformSetAttachedWindowWidth(width);
276 }
277
278 void WebInspectorProxy::startWindowDrag()
279 {
280     platformStartWindowDrag();
281 }
282
283 void WebInspectorProxy::togglePageProfiling()
284 {
285     if (!m_inspectedPage)
286         return;
287
288     if (m_isProfilingPage)
289         m_inspectedPage->process().send(Messages::WebInspector::StopPageProfiling(), m_inspectedPage->pageID());
290     else
291         m_inspectedPage->process().send(Messages::WebInspector::StartPageProfiling(), m_inspectedPage->pageID());
292
293     // FIXME: have the WebProcess notify us on state changes.
294     m_isProfilingPage = !m_isProfilingPage;
295 }
296
297 void WebInspectorProxy::toggleElementSelection()
298 {
299     if (!m_inspectedPage)
300         return;
301
302     if (m_elementSelectionActive) {
303         m_ignoreElementSelectionChange = true;
304         m_inspectedPage->process().send(Messages::WebInspector::StopElementSelection(), m_inspectedPage->pageID());
305     } else {
306         connect();
307         m_inspectedPage->process().send(Messages::WebInspector::StartElementSelection(), m_inspectedPage->pageID());
308     }
309 }
310
311 bool WebInspectorProxy::isMainOrTestInspectorPage(const URL& url)
312 {
313     // Use URL so we can compare the paths and protocols.
314     URL mainPageURL(URL(), WebInspectorProxy::inspectorPageURL());
315     if (url.protocol() == mainPageURL.protocol() && decodeURLEscapeSequences(url.path()) == decodeURLEscapeSequences(mainPageURL.path()))
316         return true;
317
318     // We might not have a Test URL in Production builds.
319     String testPageURLString = WebInspectorProxy::inspectorTestPageURL();
320     if (testPageURLString.isNull())
321         return false;
322
323     URL testPageURL(URL(), testPageURLString);
324     return url.protocol() == testPageURL.protocol() && decodeURLEscapeSequences(url.path()) == decodeURLEscapeSequences(testPageURL.path());
325 }
326
327 void WebInspectorProxy::createFrontendPage()
328 {
329     if (m_inspectorPage)
330         return;
331
332     m_inspectorPage = platformCreateFrontendPage();
333     ASSERT(m_inspectorPage);
334     if (!m_inspectorPage)
335         return;
336
337     trackInspectorPage(m_inspectorPage);
338
339     m_inspectorPage->process().addMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID(), *this);
340     m_inspectorPage->process().assumeReadAccessToBaseURL(WebInspectorProxy::inspectorBaseURL());
341 }
342
343 // Called by WebInspectorProxy messages
344 void WebInspectorProxy::createInspectorPage(IPC::Attachment connectionIdentifier, bool canAttach, bool underTest)
345 {
346     if (!m_inspectedPage)
347         return;
348
349     m_underTest = underTest;
350     createFrontendPage();
351
352     ASSERT(m_inspectorPage);
353     if (!m_inspectorPage)
354         return;
355
356     m_inspectorPage->process().send(Messages::WebInspectorUI::EstablishConnection(WTFMove(connectionIdentifier), m_inspectedPage->pageID(), m_underTest, inspectionLevel()), m_inspectorPage->pageID());
357
358     if (!m_underTest) {
359         m_canAttach = platformCanAttach(canAttach);
360         m_isAttached = shouldOpenAttached();
361         m_attachmentSide = static_cast<AttachmentSide>(inspectorPagePreferences().inspectorAttachmentSide());
362
363         m_inspectedPage->process().send(Messages::WebInspector::SetAttached(m_isAttached), m_inspectedPage->pageID());
364
365         if (m_isAttached) {
366             switch (m_attachmentSide) {
367             case AttachmentSide::Bottom:
368                 m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedBottom(), m_inspectorPage->pageID());
369                 break;
370
371             case AttachmentSide::Right:
372                 m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedRight(), m_inspectorPage->pageID());
373                 break;
374
375             case AttachmentSide::Left:
376                 m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedLeft(), m_inspectorPage->pageID());
377                 break;
378             }
379         } else
380             m_inspectorPage->process().send(Messages::WebInspectorUI::Detached(), m_inspectorPage->pageID());
381
382         m_inspectorPage->process().send(Messages::WebInspectorUI::SetDockingUnavailable(!m_canAttach), m_inspectorPage->pageID());
383     }
384
385     m_inspectorPage->loadRequest(URL(URL(), m_underTest ? WebInspectorProxy::inspectorTestPageURL() : WebInspectorProxy::inspectorPageURL()));
386 }
387
388 void WebInspectorProxy::open()
389 {
390     if (m_underTest)
391         return;
392
393     if (!m_inspectorPage)
394         return;
395
396     SetForScope<bool> isOpening(m_isOpening, true);
397     m_isVisible = true;
398     m_inspectorPage->process().send(Messages::WebInspectorUI::SetIsVisible(m_isVisible), m_inspectorPage->pageID());
399
400     if (m_isAttached)
401         platformAttach();
402     else
403         platformCreateFrontendWindow();
404
405     platformBringToFront();
406 }
407
408 void WebInspectorProxy::didClose()
409 {
410     closeFrontendPageAndWindow();
411 }
412
413 void WebInspectorProxy::closeFrontendPageAndWindow()
414 {
415     if (!m_inspectorPage)
416         return;
417
418     m_isVisible = false;
419     m_isProfilingPage = false;
420     m_showMessageSent = false;
421     m_ignoreFirstBringToFront = false;
422
423     untrackInspectorPage(m_inspectorPage);
424
425     m_inspectorPage->process().send(Messages::WebInspectorUI::SetIsVisible(m_isVisible), m_inspectorPage->pageID());
426     m_inspectorPage->process().removeMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID());
427
428     if (m_isAttached)
429         platformDetach();
430
431     // Null out m_inspectorPage after platformDetach(), so the views can be cleaned up correctly.
432     m_inspectorPage = nullptr;
433
434     m_isAttached = false;
435     m_canAttach = false;
436     m_underTest = false;
437
438     platformCloseFrontendPageAndWindow();
439 }
440
441 void WebInspectorProxy::frontendLoaded()
442 {
443     if (auto* automationSession = m_inspectedPage->process().processPool().automationSession())
444         automationSession->inspectorFrontendLoaded(*m_inspectedPage);
445 }
446
447 void WebInspectorProxy::bringToFront()
448 {
449     // WebCore::InspectorFrontendClientLocal tells us to do this on load. We want to
450     // ignore it once if we only wanted to connect. This allows the Inspector to later
451     // request to be brought to the front when a breakpoint is hit or some other action.
452     if (m_ignoreFirstBringToFront) {
453         m_ignoreFirstBringToFront = false;
454         return;
455     }
456
457     if (m_isVisible)
458         platformBringToFront();
459     else
460         open();
461 }
462
463 void WebInspectorProxy::attachAvailabilityChanged(bool available)
464 {
465     bool previousCanAttach = m_canAttach;
466
467     m_canAttach = platformCanAttach(available);
468
469     if (previousCanAttach == m_canAttach)
470         return;
471
472     if (m_inspectorPage && !m_underTest)
473         m_inspectorPage->process().send(Messages::WebInspectorUI::SetDockingUnavailable(!m_canAttach), m_inspectorPage->pageID());
474
475     platformAttachAvailabilityChanged(m_canAttach);
476 }
477
478 void WebInspectorProxy::inspectedURLChanged(const String& urlString)
479 {
480     platformInspectedURLChanged(urlString);
481 }
482
483 void WebInspectorProxy::elementSelectionChanged(bool active)
484 {
485     m_elementSelectionActive = active;
486
487     if (m_ignoreElementSelectionChange) {
488         m_ignoreElementSelectionChange = false;
489         if (!m_isVisible)
490             close();
491         return;
492     }
493
494     if (active)
495         platformBringInspectedPageToFront();
496     else if (isConnected())
497         bringToFront();
498 }
499
500 void WebInspectorProxy::save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs)
501 {
502     platformSave(filename, content, base64Encoded, forceSaveAs);
503 }
504
505 void WebInspectorProxy::append(const String& filename, const String& content)
506 {
507     platformAppend(filename, content);
508 }
509
510 bool WebInspectorProxy::shouldOpenAttached()
511 {
512     return inspectorPagePreferences().inspectorStartsAttached() && canAttach();
513 }
514
515 // Unsupported configurations can use the stubs provided here.
516
517 #if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && !WK_API_ENABLED)
518
519 WebPageProxy* WebInspectorProxy::platformCreateFrontendPage()
520 {
521     notImplemented();
522     return nullptr;
523 }
524
525 void WebInspectorProxy::platformCreateFrontendWindow()
526 {
527     notImplemented();
528 }
529
530 void WebInspectorProxy::platformCloseFrontendPageAndWindow()
531 {
532     notImplemented();
533 }
534
535 void WebInspectorProxy::platformDidCloseForCrash()
536 {
537     notImplemented();
538 }
539
540 void WebInspectorProxy::platformInvalidate()
541 {
542     notImplemented();
543 }
544
545 void WebInspectorProxy::platformBringToFront()
546 {
547     notImplemented();
548 }
549
550 void WebInspectorProxy::platformBringInspectedPageToFront()
551 {
552     notImplemented();
553 }
554
555 void WebInspectorProxy::platformHide()
556 {
557     notImplemented();
558 }
559
560 bool WebInspectorProxy::platformIsFront()
561 {
562     notImplemented();
563     return false;
564 }
565
566 void WebInspectorProxy::platformInspectedURLChanged(const String&)
567 {
568     notImplemented();
569 }
570
571 void WebInspectorProxy::platformSave(const String& suggestedURL, const String& content, bool base64Encoded, bool forceSaveDialog)
572 {
573     notImplemented();
574 }
575
576 void WebInspectorProxy::platformAppend(const String& suggestedURL, const String& content)
577 {
578     notImplemented();
579 }
580
581 unsigned WebInspectorProxy::platformInspectedWindowHeight()
582 {
583     notImplemented();
584     return 0;
585 }
586
587 unsigned WebInspectorProxy::platformInspectedWindowWidth()
588 {
589     notImplemented();
590     return 0;
591 }
592
593 void WebInspectorProxy::platformAttach()
594 {
595     notImplemented();
596 }
597
598 void WebInspectorProxy::platformDetach()
599 {
600     notImplemented();
601 }
602
603 void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned)
604 {
605     notImplemented();
606 }
607
608 void WebInspectorProxy::platformStartWindowDrag()
609 {
610     notImplemented();
611 }
612
613 String WebInspectorProxy::inspectorPageURL()
614 {
615     notImplemented();
616     return String();
617 }
618
619 String WebInspectorProxy::inspectorTestPageURL()
620 {
621     notImplemented();
622     return String();
623 }
624
625 String WebInspectorProxy::inspectorBaseURL()
626 {
627     notImplemented();
628     return String();
629 }
630
631 void WebInspectorProxy::platformSetAttachedWindowWidth(unsigned)
632 {
633     notImplemented();
634 }
635
636 void WebInspectorProxy::platformAttachAvailabilityChanged(bool)
637 {
638     notImplemented();
639 }
640
641 #endif // PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && !WK_API_ENABLED)
642
643 } // namespace WebKit