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