1/*
2 * Copyright (C) 2010, 2014, 2015 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebInspectorClient.h"
28
29#include "DrawingArea.h"
30#include "WebInspector.h"
31#include "WebPage.h"
32#include <WebCore/Frame.h>
33#include <WebCore/InspectorController.h>
34#include <WebCore/Page.h>
35#include <WebCore/PageOverlayController.h>
36#include <WebCore/Settings.h>
37
38#if PLATFORM(IOS_FAMILY)
39#include <WebCore/InspectorOverlay.h>
40#endif
41
42namespace WebKit {
43using namespace WebCore;
44
45class RepaintIndicatorLayerClient final : public GraphicsLayerClient {
46 WTF_MAKE_FAST_ALLOCATED;
47public:
48 RepaintIndicatorLayerClient(WebInspectorClient& inspectorClient)
49 : m_inspectorClient(inspectorClient)
50 {
51 }
52 virtual ~RepaintIndicatorLayerClient() { }
53private:
54 void notifyAnimationEnded(const GraphicsLayer* layer, const String&) override
55 {
56 m_inspectorClient.animationEndedForLayer(layer);
57 }
58
59 WebInspectorClient& m_inspectorClient;
60};
61
62WebInspectorClient::WebInspectorClient(WebPage* page)
63 : m_page(page)
64 , m_highlightOverlay(nullptr)
65{
66}
67
68WebInspectorClient::~WebInspectorClient()
69{
70 for (auto& layer : m_paintRectLayers)
71 layer->removeFromParent();
72
73 m_paintRectLayers.clear();
74
75 if (m_paintRectOverlay && m_page->corePage())
76 m_page->corePage()->pageOverlayController().uninstallPageOverlay(*m_paintRectOverlay, PageOverlay::FadeMode::Fade);
77}
78
79void WebInspectorClient::inspectedPageDestroyed()
80{
81 if (WebInspector* inspector = m_page->inspector(WebPage::LazyCreationPolicy::UseExistingOnly))
82 inspector->close();
83
84 delete this;
85}
86
87void WebInspectorClient::frontendCountChanged(unsigned count)
88{
89 m_page->inspectorFrontendCountChanged(count);
90}
91
92Inspector::FrontendChannel* WebInspectorClient::openLocalFrontend(InspectorController* controller)
93{
94 m_page->inspector()->openLocalInspectorFrontend(controller->isUnderTest());
95
96 return nullptr;
97}
98
99void WebInspectorClient::bringFrontendToFront()
100{
101 if (m_page->inspector())
102 m_page->inspector()->bringToFront();
103}
104
105void WebInspectorClient::didResizeMainFrame(Frame*)
106{
107 if (m_page->inspector())
108 m_page->inspector()->updateDockingAvailability();
109}
110
111void WebInspectorClient::highlight()
112{
113 if (!m_page->corePage()->settings().acceleratedCompositingEnabled())
114 return;
115
116#if !PLATFORM(IOS_FAMILY)
117 if (!m_highlightOverlay) {
118 auto highlightOverlay = PageOverlay::create(*this);
119 m_highlightOverlay = highlightOverlay.ptr();
120 m_page->corePage()->pageOverlayController().installPageOverlay(WTFMove(highlightOverlay), PageOverlay::FadeMode::Fade);
121 m_highlightOverlay->setNeedsDisplay();
122 } else {
123 m_highlightOverlay->stopFadeOutAnimation();
124 m_highlightOverlay->setNeedsDisplay();
125 }
126#else
127 Highlight highlight;
128 m_page->corePage()->inspectorController().getHighlight(highlight, InspectorOverlay::CoordinateSystem::Document);
129 m_page->showInspectorHighlight(highlight);
130#endif
131}
132
133void WebInspectorClient::hideHighlight()
134{
135#if !PLATFORM(IOS_FAMILY)
136 if (m_highlightOverlay)
137 m_page->corePage()->pageOverlayController().uninstallPageOverlay(*m_highlightOverlay, PageOverlay::FadeMode::Fade);
138#else
139 m_page->hideInspectorHighlight();
140#endif
141}
142
143void WebInspectorClient::showPaintRect(const FloatRect& rect)
144{
145 if (!m_page->corePage()->settings().acceleratedCompositingEnabled())
146 return;
147
148 if (!m_paintRectOverlay) {
149 m_paintRectOverlay = PageOverlay::create(*this, PageOverlay::OverlayType::Document);
150 m_page->corePage()->pageOverlayController().installPageOverlay(*m_paintRectOverlay, PageOverlay::FadeMode::DoNotFade);
151 }
152
153 if (!m_paintIndicatorLayerClient)
154 m_paintIndicatorLayerClient = std::make_unique<RepaintIndicatorLayerClient>(*this);
155
156 auto paintLayer = GraphicsLayer::create(m_page->drawingArea()->graphicsLayerFactory(), *m_paintIndicatorLayerClient);
157
158 paintLayer->setName("paint rect");
159 paintLayer->setAnchorPoint(FloatPoint3D());
160 paintLayer->setPosition(rect.location());
161 paintLayer->setSize(rect.size());
162 paintLayer->setBackgroundColor(Color(1.0f, 0.0f, 0.0f, 0.2f));
163
164 KeyframeValueList fadeKeyframes(AnimatedPropertyOpacity);
165 fadeKeyframes.insert(std::make_unique<FloatAnimationValue>(0, 1));
166
167 fadeKeyframes.insert(std::make_unique<FloatAnimationValue>(0.25, 0));
168
169 auto opacityAnimation = Animation::create();
170 opacityAnimation->setDuration(0.25);
171
172 paintLayer->addAnimation(fadeKeyframes, FloatSize(), opacityAnimation.ptr(), "opacity"_s, 0);
173
174 GraphicsLayer& rawLayer = paintLayer.get();
175 m_paintRectLayers.add(WTFMove(paintLayer));
176
177 GraphicsLayer& overlayRootLayer = m_paintRectOverlay->layer();
178 overlayRootLayer.addChild(rawLayer);
179}
180
181void WebInspectorClient::animationEndedForLayer(const GraphicsLayer* layer)
182{
183 GraphicsLayer* nonConstLayer = const_cast<GraphicsLayer*>(layer);
184 nonConstLayer->removeFromParent();
185 m_paintRectLayers.remove(*nonConstLayer);
186}
187
188#if PLATFORM(IOS_FAMILY)
189void WebInspectorClient::showInspectorIndication()
190{
191 m_page->showInspectorIndication();
192}
193
194void WebInspectorClient::hideInspectorIndication()
195{
196 m_page->hideInspectorIndication();
197}
198
199void WebInspectorClient::didSetSearchingForNode(bool enabled)
200{
201 if (enabled)
202 m_page->enableInspectorNodeSearch();
203 else
204 m_page->disableInspectorNodeSearch();
205}
206#endif
207
208void WebInspectorClient::elementSelectionChanged(bool active)
209{
210 if (m_page->inspector())
211 m_page->inspector()->elementSelectionChanged(active);
212}
213
214void WebInspectorClient::willMoveToPage(PageOverlay&, Page* page)
215{
216 if (page)
217 return;
218
219 // The page overlay is moving away from the web page, reset it.
220 ASSERT(m_highlightOverlay);
221 m_highlightOverlay = nullptr;
222}
223
224void WebInspectorClient::didMoveToPage(PageOverlay&, Page*)
225{
226}
227
228void WebInspectorClient::drawRect(PageOverlay&, WebCore::GraphicsContext& context, const WebCore::IntRect& /*dirtyRect*/)
229{
230 m_page->corePage()->inspectorController().drawHighlight(context);
231}
232
233bool WebInspectorClient::mouseEvent(PageOverlay&, const PlatformMouseEvent&)
234{
235 return false;
236}
237
238} // namespace WebKit
239