• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 "core/inspector/InspectorPageAgent.h"
33 
34 #include "bindings/core/v8/DOMWrapperWorld.h"
35 #include "bindings/core/v8/ScriptController.h"
36 #include "bindings/core/v8/ScriptRegexp.h"
37 #include "core/HTMLNames.h"
38 #include "core/UserAgentStyleSheets.h"
39 #include "core/css/StyleSheetContents.h"
40 #include "core/css/resolver/StyleResolver.h"
41 #include "core/css/resolver/ViewportStyleResolver.h"
42 #include "core/dom/DOMImplementation.h"
43 #include "core/dom/Document.h"
44 #include "core/fetch/CSSStyleSheetResource.h"
45 #include "core/fetch/FontResource.h"
46 #include "core/fetch/ImageResource.h"
47 #include "core/fetch/MemoryCache.h"
48 #include "core/fetch/Resource.h"
49 #include "core/fetch/ResourceFetcher.h"
50 #include "core/fetch/ScriptResource.h"
51 #include "core/frame/FrameView.h"
52 #include "core/frame/LocalFrame.h"
53 #include "core/frame/Settings.h"
54 #include "core/html/HTMLFrameOwnerElement.h"
55 #include "core/html/VoidCallback.h"
56 #include "core/html/imports/HTMLImport.h"
57 #include "core/html/imports/HTMLImportLoader.h"
58 #include "core/html/imports/HTMLImportsController.h"
59 #include "core/html/parser/TextResourceDecoder.h"
60 #include "core/inspector/ContentSearchUtils.h"
61 #include "core/inspector/DOMPatchSupport.h"
62 #include "core/inspector/IdentifiersFactory.h"
63 #include "core/inspector/InjectedScriptManager.h"
64 #include "core/inspector/InspectorClient.h"
65 #include "core/inspector/InspectorInstrumentation.h"
66 #include "core/inspector/InspectorOverlay.h"
67 #include "core/inspector/InspectorResourceContentLoader.h"
68 #include "core/inspector/InspectorState.h"
69 #include "core/inspector/InstrumentingAgents.h"
70 #include "core/loader/CookieJar.h"
71 #include "core/loader/DocumentLoader.h"
72 #include "core/loader/FrameLoadRequest.h"
73 #include "core/loader/FrameLoader.h"
74 #include "core/page/Page.h"
75 #include "platform/Cookie.h"
76 #include "platform/JSONValues.h"
77 #include "platform/UserGestureIndicator.h"
78 #include "platform/weborigin/SecurityOrigin.h"
79 #include "wtf/CurrentTime.h"
80 #include "wtf/ListHashSet.h"
81 #include "wtf/Vector.h"
82 #include "wtf/text/Base64.h"
83 #include "wtf/text/TextEncoding.h"
84 
85 namespace blink {
86 
87 namespace PageAgentState {
88 static const char pageAgentEnabled[] = "pageAgentEnabled";
89 static const char pageAgentScriptExecutionDisabled[] = "pageAgentScriptExecutionDisabled";
90 static const char pageAgentScriptsToEvaluateOnLoad[] = "pageAgentScriptsToEvaluateOnLoad";
91 static const char deviceMetricsOverrideEnabled[] = "deviceMetricsOverrideEnabled";
92 static const char pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
93 static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
94 static const char pageAgentDeviceScaleFactorOverride[] = "pageAgentDeviceScaleFactorOverride";
95 static const char pageAgentEmulateMobile[] = "pageAgentEmulateMobile";
96 static const char pageAgentFitWindow[] = "pageAgentFitWindow";
97 static const char deviceScale[] = "deviceScale";
98 static const char deviceOffsetX[] = "deviceOffsetX";
99 static const char deviceOffsetY[] = "deviceOffsetY";
100 static const char pageAgentShowFPSCounter[] = "pageAgentShowFPSCounter";
101 static const char pageAgentContinuousPaintingEnabled[] = "pageAgentContinuousPaintingEnabled";
102 static const char pageAgentShowPaintRects[] = "pageAgentShowPaintRects";
103 static const char pageAgentShowDebugBorders[] = "pageAgentShowDebugBorders";
104 static const char pageAgentShowScrollBottleneckRects[] = "pageAgentShowScrollBottleneckRects";
105 static const char touchEventEmulationEnabled[] = "touchEventEmulationEnabled";
106 static const char pageAgentEmulatedMedia[] = "pageAgentEmulatedMedia";
107 static const char showSizeOnResize[] = "showSizeOnResize";
108 static const char showGridOnResize[] = "showGridOnResize";
109 static const char screencastEnabled[] = "screencastEnabled";
110 }
111 
112 namespace {
113 
urlWithoutFragment(const KURL & url)114 KURL urlWithoutFragment(const KURL& url)
115 {
116     KURL result = url;
117     result.removeFragmentIdentifier();
118     return result;
119 }
120 
calculateFontScaleFactor(int width,int height,float deviceScaleFactor)121 static float calculateFontScaleFactor(int width, int height, float deviceScaleFactor)
122 {
123     // Chromium on Android uses a device scale adjustment for fonts used in text autosizing for
124     // improved legibility. This function computes this adjusted value for text autosizing.
125     // For a description of the Android device scale adjustment algorithm, see:
126     // chrome/browser/chrome_content_browser_client.cc, GetDeviceScaleAdjustment(...)
127     if (!width || !height || !deviceScaleFactor)
128         return 1;
129 
130     static const float kMinFSM = 1.05f;
131     static const int kWidthForMinFSM = 320;
132     static const float kMaxFSM = 1.3f;
133     static const int kWidthForMaxFSM = 800;
134 
135     float minWidth = std::min(width, height) / deviceScaleFactor;
136     if (minWidth <= kWidthForMinFSM)
137         return kMinFSM;
138     if (minWidth >= kWidthForMaxFSM)
139         return kMaxFSM;
140 
141     // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
142     float ratio = static_cast<float>(minWidth - kWidthForMinFSM) / (kWidthForMaxFSM - kWidthForMinFSM);
143     return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
144 }
145 
146 }
147 
148 class InspectorPageAgent::GetResourceContentLoadListener FINAL : public VoidCallback {
149 public:
150     GetResourceContentLoadListener(InspectorPageAgent*, const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback>);
151     virtual void trace(Visitor*) OVERRIDE;
152     virtual void handleEvent() OVERRIDE;
153 private:
154     RawPtrWillBeMember<InspectorPageAgent> m_pageAgent;
155     String m_frameId;
156     String m_url;
157     RefPtrWillBeMember<GetResourceContentCallback> m_callback;
158 };
159 
GetResourceContentLoadListener(InspectorPageAgent * pageAgent,const String & frameId,const String & url,PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)160 InspectorPageAgent::GetResourceContentLoadListener::GetResourceContentLoadListener(InspectorPageAgent* pageAgent, const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)
161     : m_pageAgent(pageAgent)
162     , m_frameId(frameId)
163     , m_url(url)
164     , m_callback(callback)
165 {
166 }
167 
trace(Visitor * visitor)168 void InspectorPageAgent::GetResourceContentLoadListener::trace(Visitor* visitor)
169 {
170     visitor->trace(m_pageAgent);
171     visitor->trace(m_callback);
172     VoidCallback::trace(visitor);
173 }
174 
handleEvent()175 void InspectorPageAgent::GetResourceContentLoadListener::handleEvent()
176 {
177     if (!m_callback->isActive())
178         return;
179     m_pageAgent->getResourceContentAfterResourcesContentLoaded(m_frameId, m_url, m_callback);
180 }
181 
decodeBuffer(const char * buffer,unsigned size,const String & textEncodingName,String * result)182 static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
183 {
184     if (buffer) {
185         WTF::TextEncoding encoding(textEncodingName);
186         if (!encoding.isValid())
187             encoding = WindowsLatin1Encoding();
188         *result = encoding.decode(buffer, size);
189         return true;
190     }
191     return false;
192 }
193 
prepareResourceBuffer(Resource * cachedResource,bool * hasZeroSize)194 static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize)
195 {
196     *hasZeroSize = false;
197     if (!cachedResource)
198         return false;
199 
200     if (cachedResource->dataBufferingPolicy() == DoNotBufferData)
201         return false;
202 
203     // Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0.
204     if (!cachedResource->encodedSize()) {
205         *hasZeroSize = true;
206         return true;
207     }
208 
209     if (cachedResource->isPurgeable()) {
210         // If the resource is purgeable then make it unpurgeable to get
211         // get its data. This might fail, in which case we return an
212         // empty String.
213         // FIXME: should we do something else in the case of a purged
214         // resource that informs the user why there is no data in the
215         // inspector?
216         if (!cachedResource->lock())
217             return false;
218     }
219 
220     return true;
221 }
222 
hasTextContent(Resource * cachedResource)223 static bool hasTextContent(Resource* cachedResource)
224 {
225     InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource);
226     return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource;
227 }
228 
createXHRTextDecoder(const String & mimeType,const String & textEncodingName)229 static PassOwnPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName)
230 {
231     if (!textEncodingName.isEmpty())
232         return TextResourceDecoder::create("text/plain", textEncodingName);
233     if (DOMImplementation::isXMLMIMEType(mimeType)) {
234         OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
235         decoder->useLenientXMLDecoding();
236         return decoder.release();
237     }
238     if (equalIgnoringCase(mimeType, "text/html"))
239         return TextResourceDecoder::create("text/html", "UTF-8");
240     return TextResourceDecoder::create("text/plain", "UTF-8");
241 }
242 
resourceContent(ErrorString * errorString,LocalFrame * frame,const KURL & url,String * result,bool * base64Encoded)243 static void resourceContent(ErrorString* errorString, LocalFrame* frame, const KURL& url, String* result, bool* base64Encoded)
244 {
245     DocumentLoader* loader = InspectorPageAgent::assertDocumentLoader(errorString, frame);
246     if (!loader)
247         return;
248 
249     if (!InspectorPageAgent::cachedResourceContent(InspectorPageAgent::cachedResource(frame, url), result, base64Encoded))
250         *errorString = "No resource with given URL found";
251 }
252 
cachedResourceContent(Resource * cachedResource,String * result,bool * base64Encoded)253 bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded)
254 {
255     bool hasZeroSize;
256     bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize);
257     if (!prepared)
258         return false;
259 
260     *base64Encoded = !hasTextContent(cachedResource);
261     if (*base64Encoded) {
262         RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer();
263 
264         if (!buffer)
265             return false;
266 
267         *result = base64Encode(buffer->data(), buffer->size());
268         return true;
269     }
270 
271     if (hasZeroSize) {
272         *result = "";
273         return true;
274     }
275 
276     if (cachedResource) {
277         switch (cachedResource->type()) {
278         case Resource::CSSStyleSheet:
279             *result = toCSSStyleSheetResource(cachedResource)->sheetText(false);
280             return true;
281         case Resource::Script:
282             *result = toScriptResource(cachedResource)->script();
283             return true;
284         case Resource::Raw: {
285             SharedBuffer* buffer = cachedResource->resourceBuffer();
286             if (!buffer)
287                 return false;
288             OwnPtr<TextResourceDecoder> decoder = createXHRTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName());
289             String content = decoder->decode(buffer->data(), buffer->size());
290             *result = content + decoder->flush();
291             return true;
292         }
293         default:
294             SharedBuffer* buffer = cachedResource->resourceBuffer();
295             return decodeBuffer(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, cachedResource->response().textEncodingName(), result);
296         }
297     }
298     return false;
299 }
300 
301 // static
sharedBufferContent(PassRefPtr<SharedBuffer> buffer,const String & textEncodingName,bool withBase64Encode,String * result)302 bool InspectorPageAgent::sharedBufferContent(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, bool withBase64Encode, String* result)
303 {
304     return dataContent(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, textEncodingName, withBase64Encode, result);
305 }
306 
dataContent(const char * data,unsigned size,const String & textEncodingName,bool withBase64Encode,String * result)307 bool InspectorPageAgent::dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result)
308 {
309     if (withBase64Encode) {
310         *result = base64Encode(data, size);
311         return true;
312     }
313 
314     return decodeBuffer(data, size, textEncodingName, result);
315 }
316 
create(Page * page,InjectedScriptManager * injectedScriptManager,InspectorClient * client,InspectorOverlay * overlay)317 PassOwnPtrWillBeRawPtr<InspectorPageAgent> InspectorPageAgent::create(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
318 {
319     return adoptPtrWillBeNoop(new InspectorPageAgent(page, injectedScriptManager, client, overlay));
320 }
321 
cachedResource(LocalFrame * frame,const KURL & url)322 Resource* InspectorPageAgent::cachedResource(LocalFrame* frame, const KURL& url)
323 {
324     Document* document = frame->document();
325     if (!document)
326         return 0;
327     Resource* cachedResource = document->fetcher()->cachedResource(url);
328     if (!cachedResource) {
329         Vector<Document*> allImports = InspectorPageAgent::importsForFrame(frame);
330         for (Vector<Document*>::const_iterator it = allImports.begin(); it != allImports.end(); ++it) {
331             Document* import = *it;
332             cachedResource = import->fetcher()->cachedResource(url);
333             if (cachedResource)
334                 break;
335         }
336     }
337     if (!cachedResource)
338         cachedResource = memoryCache()->resourceForURL(url);
339     return cachedResource;
340 }
341 
resourceTypeJson(InspectorPageAgent::ResourceType resourceType)342 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType)
343 {
344     switch (resourceType) {
345     case DocumentResource:
346         return TypeBuilder::Page::ResourceType::Document;
347     case FontResource:
348         return TypeBuilder::Page::ResourceType::Font;
349     case ImageResource:
350         return TypeBuilder::Page::ResourceType::Image;
351     case MediaResource:
352         return TypeBuilder::Page::ResourceType::Media;
353     case ScriptResource:
354         return TypeBuilder::Page::ResourceType::Script;
355     case StylesheetResource:
356         return TypeBuilder::Page::ResourceType::Stylesheet;
357     case TextTrackResource:
358         return TypeBuilder::Page::ResourceType::TextTrack;
359     case XHRResource:
360         return TypeBuilder::Page::ResourceType::XHR;
361     case WebSocketResource:
362         return TypeBuilder::Page::ResourceType::WebSocket;
363     case OtherResource:
364         return TypeBuilder::Page::ResourceType::Other;
365     }
366     return TypeBuilder::Page::ResourceType::Other;
367 }
368 
cachedResourceType(const Resource & cachedResource)369 InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Resource& cachedResource)
370 {
371     switch (cachedResource.type()) {
372     case Resource::Image:
373         return InspectorPageAgent::ImageResource;
374     case Resource::Font:
375         return InspectorPageAgent::FontResource;
376     case Resource::Media:
377         return InspectorPageAgent::MediaResource;
378     case Resource::TextTrack:
379         return InspectorPageAgent::TextTrackResource;
380     case Resource::CSSStyleSheet:
381         // Fall through.
382     case Resource::XSLStyleSheet:
383         return InspectorPageAgent::StylesheetResource;
384     case Resource::Script:
385         return InspectorPageAgent::ScriptResource;
386     case Resource::Raw:
387         return InspectorPageAgent::XHRResource;
388     case Resource::ImportResource:
389         // Fall through.
390     case Resource::MainResource:
391         return InspectorPageAgent::DocumentResource;
392     default:
393         break;
394     }
395     return InspectorPageAgent::OtherResource;
396 }
397 
cachedResourceTypeJson(const Resource & cachedResource)398 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson(const Resource& cachedResource)
399 {
400     return resourceTypeJson(cachedResourceType(cachedResource));
401 }
402 
InspectorPageAgent(Page * page,InjectedScriptManager * injectedScriptManager,InspectorClient * client,InspectorOverlay * overlay)403 InspectorPageAgent::InspectorPageAgent(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
404     : InspectorBaseAgent<InspectorPageAgent>("Page")
405     , m_page(page)
406     , m_injectedScriptManager(injectedScriptManager)
407     , m_client(client)
408     , m_frontend(0)
409     , m_overlay(overlay)
410     , m_lastScriptIdentifier(0)
411     , m_enabled(false)
412     , m_ignoreScriptsEnabledNotification(false)
413     , m_deviceMetricsOverridden(false)
414     , m_emulateMobileEnabled(false)
415     , m_touchEmulationEnabled(false)
416     , m_originalTouchEnabled(false)
417     , m_originalDeviceSupportsMouse(false)
418     , m_originalDeviceSupportsTouch(false)
419     , m_originalMaxTouchPoints(0)
420     , m_embedderTextAutosizingEnabled(m_page->settings().textAutosizingEnabled())
421     , m_embedderFontScaleFactor(m_page->settings().deviceScaleAdjustment())
422     , m_embedderPreferCompositingToLCDTextEnabled(m_page->settings().preferCompositingToLCDTextEnabled())
423 {
424 }
425 
setTextAutosizingEnabled(bool enabled)426 void InspectorPageAgent::setTextAutosizingEnabled(bool enabled)
427 {
428     m_embedderTextAutosizingEnabled = enabled;
429     bool emulateMobileEnabled = m_enabled && m_deviceMetricsOverridden && m_emulateMobileEnabled;
430     if (!emulateMobileEnabled)
431         m_page->settings().setTextAutosizingEnabled(enabled);
432 }
433 
setDeviceScaleAdjustment(float deviceScaleAdjustment)434 void InspectorPageAgent::setDeviceScaleAdjustment(float deviceScaleAdjustment)
435 {
436     m_embedderFontScaleFactor = deviceScaleAdjustment;
437     bool emulateMobileEnabled = m_enabled && m_deviceMetricsOverridden && m_emulateMobileEnabled;
438     if (!emulateMobileEnabled)
439         m_page->settings().setDeviceScaleAdjustment(deviceScaleAdjustment);
440 }
441 
setPreferCompositingToLCDTextEnabled(bool enabled)442 void InspectorPageAgent::setPreferCompositingToLCDTextEnabled(bool enabled)
443 {
444     m_embedderPreferCompositingToLCDTextEnabled = enabled;
445     bool emulateMobileEnabled = m_enabled && m_deviceMetricsOverridden && m_emulateMobileEnabled;
446     if (!emulateMobileEnabled)
447         m_page->settings().setPreferCompositingToLCDTextEnabled(enabled);
448 }
449 
setFrontend(InspectorFrontend * frontend)450 void InspectorPageAgent::setFrontend(InspectorFrontend* frontend)
451 {
452     m_frontend = frontend->page();
453 }
454 
clearFrontend()455 void InspectorPageAgent::clearFrontend()
456 {
457     ErrorString error;
458     disable(&error);
459     m_frontend = 0;
460 }
461 
restore()462 void InspectorPageAgent::restore()
463 {
464     if (m_state->getBoolean(PageAgentState::pageAgentEnabled)) {
465         ErrorString error;
466         enable(&error);
467         bool scriptExecutionDisabled = m_state->getBoolean(PageAgentState::pageAgentScriptExecutionDisabled);
468         setScriptExecutionDisabled(0, scriptExecutionDisabled);
469         bool showPaintRects = m_state->getBoolean(PageAgentState::pageAgentShowPaintRects);
470         setShowPaintRects(0, showPaintRects);
471         bool showDebugBorders = m_state->getBoolean(PageAgentState::pageAgentShowDebugBorders);
472         setShowDebugBorders(0, showDebugBorders);
473         bool showFPSCounter = m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter);
474         setShowFPSCounter(0, showFPSCounter);
475         String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
476         setEmulatedMedia(0, emulatedMedia);
477         bool continuousPaintingEnabled = m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled);
478         setContinuousPaintingEnabled(0, continuousPaintingEnabled);
479         bool showScrollBottleneckRects = m_state->getBoolean(PageAgentState::pageAgentShowScrollBottleneckRects);
480         setShowScrollBottleneckRects(0, showScrollBottleneckRects);
481 
482         updateViewMetricsFromState();
483         updateTouchEventEmulationInPage(m_state->getBoolean(PageAgentState::touchEventEmulationEnabled));
484     }
485 }
486 
enable(ErrorString *)487 void InspectorPageAgent::enable(ErrorString*)
488 {
489     m_enabled = true;
490     m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
491     m_instrumentingAgents->setInspectorPageAgent(this);
492     if (m_inspectorResourceContentLoader)
493         m_inspectorResourceContentLoader->dispose();
494     m_inspectorResourceContentLoader = adoptPtrWillBeNoop(new InspectorResourceContentLoader(m_page));
495 }
496 
discardAgent()497 void InspectorPageAgent::discardAgent()
498 {
499     if (!m_inspectorResourceContentLoader)
500         return;
501     m_inspectorResourceContentLoader->dispose();
502     m_inspectorResourceContentLoader.clear();
503 }
504 
disable(ErrorString *)505 void InspectorPageAgent::disable(ErrorString*)
506 {
507     m_enabled = false;
508     m_state->setBoolean(PageAgentState::pageAgentEnabled, false);
509     m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
510     m_overlay->hide();
511     m_instrumentingAgents->setInspectorPageAgent(0);
512     if (m_inspectorResourceContentLoader) {
513         m_inspectorResourceContentLoader->dispose();
514         m_inspectorResourceContentLoader.clear();
515     }
516     m_deviceMetricsOverridden = false;
517 
518     setShowPaintRects(0, false);
519     setShowDebugBorders(0, false);
520     setShowFPSCounter(0, false);
521     setEmulatedMedia(0, String());
522     if (m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled))
523         setContinuousPaintingEnabled(0, false);
524     setShowScrollBottleneckRects(0, false);
525     setShowViewportSizeOnResize(0, false, 0);
526     stopScreencast(0);
527 
528     if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled)) {
529         updateTouchEventEmulationInPage(false);
530         m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, false);
531     }
532 
533     if (!deviceMetricsChanged(false, 0, 0, 0, false, false, 1, 0, 0))
534         return;
535 
536     // When disabling the agent, reset the override values if necessary.
537     updateViewMetrics(false, 0, 0, 0, false, false, 1, 0, 0);
538     m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
539     m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
540     m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
541     m_state->setBoolean(PageAgentState::pageAgentEmulateMobile, false);
542     m_state->setBoolean(PageAgentState::pageAgentFitWindow, false);
543     m_state->setDouble(PageAgentState::deviceScale, 1);
544     m_state->setDouble(PageAgentState::deviceOffsetX, 0);
545     m_state->setDouble(PageAgentState::deviceOffsetY, 0);
546 }
547 
addScriptToEvaluateOnLoad(ErrorString *,const String & source,String * identifier)548 void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier)
549 {
550     RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
551     if (!scripts) {
552         scripts = JSONObject::create();
553         m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
554     }
555     // Assure we don't override existing ids -- m_lastScriptIdentifier could get out of sync WRT actual
556     // scripts once we restored the scripts from the cookie during navigation.
557     do {
558         *identifier = String::number(++m_lastScriptIdentifier);
559     } while (scripts->find(*identifier) != scripts->end());
560     scripts->setString(*identifier, source);
561 
562     // Force cookie serialization.
563     m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
564 }
565 
removeScriptToEvaluateOnLoad(ErrorString * error,const String & identifier)566 void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const String& identifier)
567 {
568     RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
569     if (!scripts || scripts->find(identifier) == scripts->end()) {
570         *error = "Script not found";
571         return;
572     }
573     scripts->remove(identifier);
574 }
575 
reload(ErrorString *,const bool * const optionalIgnoreCache,const String * optionalScriptToEvaluateOnLoad,const String * optionalScriptPreprocessor)576 void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor)
577 {
578     m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
579     m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
580     m_page->deprecatedLocalMainFrame()->loader().reload(asBool(optionalIgnoreCache) ? EndToEndReload : NormalReload);
581 }
582 
navigate(ErrorString *,const String & url,String * outFrameId)583 void InspectorPageAgent::navigate(ErrorString*, const String& url, String* outFrameId)
584 {
585     LocalFrame* frame = m_page->deprecatedLocalMainFrame();
586     *outFrameId = frameId(frame);
587 }
588 
buildObjectForCookie(const Cookie & cookie)589 static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
590 {
591     return TypeBuilder::Page::Cookie::create()
592         .setName(cookie.name)
593         .setValue(cookie.value)
594         .setDomain(cookie.domain)
595         .setPath(cookie.path)
596         .setExpires(cookie.expires)
597         .setSize((cookie.name.length() + cookie.value.length()))
598         .setHttpOnly(cookie.httpOnly)
599         .setSecure(cookie.secure)
600         .setSession(cookie.session)
601         .release();
602 }
603 
buildArrayForCookies(ListHashSet<Cookie> & cookiesList)604 static PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > buildArrayForCookies(ListHashSet<Cookie>& cookiesList)
605 {
606     RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > cookies = TypeBuilder::Array<TypeBuilder::Page::Cookie>::create();
607 
608     ListHashSet<Cookie>::iterator end = cookiesList.end();
609     ListHashSet<Cookie>::iterator it = cookiesList.begin();
610     for (int i = 0; it != end; ++it, i++)
611         cookies->addItem(buildObjectForCookie(*it));
612 
613     return cookies;
614 }
615 
cachedResourcesForDocument(Document * document,Vector<Resource * > & result,bool skipXHRs)616 static void cachedResourcesForDocument(Document* document, Vector<Resource*>& result, bool skipXHRs)
617 {
618     const ResourceFetcher::DocumentResourceMap& allResources = document->fetcher()->allResources();
619     ResourceFetcher::DocumentResourceMap::const_iterator end = allResources.end();
620     for (ResourceFetcher::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
621         Resource* cachedResource = it->value.get();
622 
623         switch (cachedResource->type()) {
624         case Resource::Image:
625             // Skip images that were not auto loaded (images disabled in the user agent).
626             if (toImageResource(cachedResource)->stillNeedsLoad())
627                 continue;
628             break;
629         case Resource::Font:
630             // Skip fonts that were referenced in CSS but never used/downloaded.
631             if (toFontResource(cachedResource)->stillNeedsLoad())
632                 continue;
633             break;
634         case Resource::Raw:
635             if (skipXHRs)
636                 continue;
637             break;
638         default:
639             // All other Resource types download immediately.
640             break;
641         }
642 
643         result.append(cachedResource);
644     }
645 }
646 
647 // static
importsForFrame(LocalFrame * frame)648 Vector<Document*> InspectorPageAgent::importsForFrame(LocalFrame* frame)
649 {
650     Vector<Document*> result;
651     Document* rootDocument = frame->document();
652 
653     if (HTMLImportsController* controller = rootDocument->importsController()) {
654         for (size_t i = 0; i < controller->loaderCount(); ++i) {
655             if (Document* document = controller->loaderAt(i)->document())
656                 result.append(document);
657         }
658     }
659 
660     return result;
661 }
662 
cachedResourcesForFrame(LocalFrame * frame,bool skipXHRs)663 static Vector<Resource*> cachedResourcesForFrame(LocalFrame* frame, bool skipXHRs)
664 {
665     Vector<Resource*> result;
666     Document* rootDocument = frame->document();
667     Vector<Document*> loaders = InspectorPageAgent::importsForFrame(frame);
668 
669     cachedResourcesForDocument(rootDocument, result, skipXHRs);
670     for (size_t i = 0; i < loaders.size(); ++i)
671         cachedResourcesForDocument(loaders[i], result, skipXHRs);
672 
673     return result;
674 }
675 
allResourcesURLsForFrame(LocalFrame * frame)676 static Vector<KURL> allResourcesURLsForFrame(LocalFrame* frame)
677 {
678     Vector<KURL> result;
679 
680     result.append(urlWithoutFragment(frame->loader().documentLoader()->url()));
681 
682     Vector<Resource*> allResources = cachedResourcesForFrame(frame, false);
683     for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it)
684         result.append(urlWithoutFragment((*it)->url()));
685 
686     return result;
687 }
688 
getCookies(ErrorString *,RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie>> & cookies)689 void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies)
690 {
691     ListHashSet<Cookie> rawCookiesList;
692 
693     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
694         if (!frame->isLocalFrame())
695             continue;
696         Document* document = toLocalFrame(frame)->document();
697         Vector<KURL> allURLs = allResourcesURLsForFrame(toLocalFrame(frame));
698         for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
699             Vector<Cookie> docCookiesList;
700             getRawCookies(document, *it, docCookiesList);
701             int cookiesSize = docCookiesList.size();
702             for (int i = 0; i < cookiesSize; i++) {
703                 if (!rawCookiesList.contains(docCookiesList[i]))
704                     rawCookiesList.add(docCookiesList[i]);
705             }
706         }
707     }
708 
709     cookies = buildArrayForCookies(rawCookiesList);
710 }
711 
deleteCookie(ErrorString *,const String & cookieName,const String & url)712 void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
713 {
714     KURL parsedURL(ParsedURLString, url);
715     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame())) {
716         if (frame->isLocalFrame())
717             blink::deleteCookie(toLocalFrame(frame)->document(), parsedURL, cookieName);
718     }
719 }
720 
getResourceTree(ErrorString *,RefPtr<TypeBuilder::Page::FrameResourceTree> & object)721 void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>& object)
722 {
723     object = buildObjectForFrameTree(m_page->deprecatedLocalMainFrame());
724 }
725 
getResourceContentAfterResourcesContentLoaded(const String & frameId,const String & url,PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)726 void InspectorPageAgent::getResourceContentAfterResourcesContentLoaded(const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)
727 {
728     ErrorString errorString;
729     LocalFrame* frame = assertFrame(&errorString, frameId);
730     if (!frame) {
731         callback->sendFailure(errorString);
732         return;
733     }
734     String content;
735     bool base64Encoded;
736     resourceContent(&errorString, frame, KURL(ParsedURLString, url), &content, &base64Encoded);
737     if (!errorString.isEmpty()) {
738         callback->sendFailure(errorString);
739         return;
740     }
741     callback->sendSuccess(content, base64Encoded);
742 }
743 
getResourceContent(ErrorString * errorString,const String & frameId,const String & url,PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)744 void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)
745 {
746     String content;
747     if (getEditedResourceContent(url, &content)) {
748         callback->sendSuccess(content, false);
749         return;
750     }
751     if (!m_inspectorResourceContentLoader) {
752         callback->sendFailure("Agent is not enabled.");
753         return;
754     }
755     m_inspectorResourceContentLoader->ensureResourcesContentLoaded(new GetResourceContentLoadListener(this, frameId, url, callback));
756 }
757 
textContentForResource(Resource * cachedResource,String * result)758 static bool textContentForResource(Resource* cachedResource, String* result)
759 {
760     if (hasTextContent(cachedResource)) {
761         String content;
762         bool base64Encoded;
763         if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {
764             ASSERT(!base64Encoded);
765             return true;
766         }
767     }
768     return false;
769 }
770 
searchInResource(ErrorString *,const String & frameId,const String & url,const String & query,const bool * const optionalCaseSensitive,const bool * const optionalIsRegex,RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch>> & results)771 void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >& results)
772 {
773     results = TypeBuilder::Array<TypeBuilder::Page::SearchMatch>::create();
774 
775     LocalFrame* frame = frameForId(frameId);
776     KURL kurl(ParsedURLString, url);
777 
778     FrameLoader* frameLoader = frame ? &frame->loader() : 0;
779     DocumentLoader* loader = frameLoader ? frameLoader->documentLoader() : 0;
780     if (!loader)
781         return;
782 
783     String content;
784     bool success = false;
785     Resource* resource = cachedResource(frame, kurl);
786     if (resource)
787         success = textContentForResource(resource, &content);
788 
789     if (!success)
790         return;
791 
792     results = ContentSearchUtils::searchInTextByLines(content, query, asBool(optionalCaseSensitive), asBool(optionalIsRegex));
793 }
794 
setDocumentContent(ErrorString * errorString,const String & frameId,const String & html)795 void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
796 {
797     LocalFrame* frame = assertFrame(errorString, frameId);
798     if (!frame)
799         return;
800 
801     Document* document = frame->document();
802     if (!document) {
803         *errorString = "No Document instance to set HTML for";
804         return;
805     }
806     DOMPatchSupport::patchDocument(*document, html);
807 }
808 
setDeviceMetricsOverride(ErrorString * errorString,int width,int height,double deviceScaleFactor,bool mobile,bool fitWindow,const double * optionalScale,const double * optionalOffsetX,const double * optionalOffsetY)809 void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int width, int height, double deviceScaleFactor, bool mobile, bool fitWindow, const double* optionalScale, const double* optionalOffsetX, const double* optionalOffsetY)
810 {
811     const static long maxDimension = 10000000;
812     const static double maxScale = 10;
813 
814     double scale = optionalScale ? *optionalScale : 1;
815     double offsetX = optionalOffsetX ? *optionalOffsetX : 0;
816     double offsetY = optionalOffsetY ? *optionalOffsetY : 0;
817 
818     if (width < 0 || height < 0 || width > maxDimension || height > maxDimension) {
819         *errorString = "Width and height values must be positive, not greater than " + String::number(maxDimension);
820         return;
821     }
822 
823     if (deviceScaleFactor < 0) {
824         *errorString = "deviceScaleFactor must be non-negative";
825         return;
826     }
827 
828     if (scale <= 0 || scale > maxScale) {
829         *errorString = "scale must be positive, not greater than " + String::number(maxScale);
830         return;
831     }
832 
833     Settings& settings = m_page->settings();
834     if (!settings.acceleratedCompositingEnabled()) {
835         if (errorString)
836             *errorString = "Compositing mode is not supported";
837         return;
838     }
839 
840     if (!deviceMetricsChanged(true, width, height, deviceScaleFactor, mobile, fitWindow, scale, offsetX, offsetY))
841         return;
842 
843     m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, true);
844     m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
845     m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
846     m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, deviceScaleFactor);
847     m_state->setBoolean(PageAgentState::pageAgentEmulateMobile, mobile);
848     m_state->setBoolean(PageAgentState::pageAgentFitWindow, fitWindow);
849     m_state->setDouble(PageAgentState::deviceScale, scale);
850     m_state->setDouble(PageAgentState::deviceOffsetX, offsetX);
851     m_state->setDouble(PageAgentState::deviceOffsetY, offsetY);
852     updateViewMetricsFromState();
853 }
854 
clearDeviceMetricsOverride(ErrorString *)855 void InspectorPageAgent::clearDeviceMetricsOverride(ErrorString*)
856 {
857     if (m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled)) {
858         m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, false);
859         updateViewMetricsFromState();
860     }
861 }
862 
resetScrollAndPageScaleFactor(ErrorString *)863 void InspectorPageAgent::resetScrollAndPageScaleFactor(ErrorString*)
864 {
865     m_client->resetScrollAndPageScaleFactor();
866 }
867 
setPageScaleFactor(ErrorString *,double pageScaleFactor)868 void InspectorPageAgent::setPageScaleFactor(ErrorString*, double pageScaleFactor)
869 {
870     m_client->setPageScaleFactor(static_cast<float>(pageScaleFactor));
871 }
872 
deviceMetricsChanged(bool enabled,int width,int height,double deviceScaleFactor,bool mobile,bool fitWindow,double scale,double offsetX,double offsetY)873 bool InspectorPageAgent::deviceMetricsChanged(bool enabled, int width, int height, double deviceScaleFactor, bool mobile, bool fitWindow, double scale, double offsetX, double offsetY)
874 {
875     bool currentEnabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
876     // These two always fit an int.
877     int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
878     int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
879     double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
880     bool currentMobile = m_state->getBoolean(PageAgentState::pageAgentEmulateMobile);
881     bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
882     double currentScale = m_state->getDouble(PageAgentState::deviceScale, 1);
883     double currentOffsetX = m_state->getDouble(PageAgentState::deviceOffsetX, 0);
884     double currentOffsetY = m_state->getDouble(PageAgentState::deviceOffsetY, 0);
885 
886     return enabled != currentEnabled
887         || width != currentWidth
888         || height != currentHeight
889         || deviceScaleFactor != currentDeviceScaleFactor
890         || mobile != currentMobile
891         || fitWindow != currentFitWindow
892         || scale != currentScale
893         || offsetX != currentOffsetX
894         || offsetY != currentOffsetY;
895 }
896 
setShowPaintRects(ErrorString *,bool show)897 void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
898 {
899     m_state->setBoolean(PageAgentState::pageAgentShowPaintRects, show);
900     m_client->setShowPaintRects(show);
901 
902     if (!show && mainFrame() && mainFrame()->view())
903         mainFrame()->view()->invalidate();
904 }
905 
setShowDebugBorders(ErrorString * errorString,bool show)906 void InspectorPageAgent::setShowDebugBorders(ErrorString* errorString, bool show)
907 {
908     m_state->setBoolean(PageAgentState::pageAgentShowDebugBorders, show);
909     if (show && !compositingEnabled(errorString))
910         return;
911     m_client->setShowDebugBorders(show);
912 }
913 
setShowFPSCounter(ErrorString * errorString,bool show)914 void InspectorPageAgent::setShowFPSCounter(ErrorString* errorString, bool show)
915 {
916     // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
917     m_state->setBoolean(PageAgentState::pageAgentShowFPSCounter, show);
918     if (show && !compositingEnabled(errorString))
919         return;
920     m_client->setShowFPSCounter(show && !m_deviceMetricsOverridden);
921 }
922 
setContinuousPaintingEnabled(ErrorString * errorString,bool enabled)923 void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString* errorString, bool enabled)
924 {
925     m_state->setBoolean(PageAgentState::pageAgentContinuousPaintingEnabled, enabled);
926     if (enabled && !compositingEnabled(errorString))
927         return;
928     m_client->setContinuousPaintingEnabled(enabled && !m_deviceMetricsOverridden);
929 }
930 
setShowScrollBottleneckRects(ErrorString * errorString,bool show)931 void InspectorPageAgent::setShowScrollBottleneckRects(ErrorString* errorString, bool show)
932 {
933     m_state->setBoolean(PageAgentState::pageAgentShowScrollBottleneckRects, show);
934     if (show && !compositingEnabled(errorString))
935         return;
936     m_client->setShowScrollBottleneckRects(show);
937 }
938 
getScriptExecutionStatus(ErrorString *,PageCommandHandler::Result::Enum * status)939 void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum* status)
940 {
941     bool disabledByScriptController = false;
942     bool disabledInSettings = false;
943     LocalFrame* frame = mainFrame();
944     if (frame) {
945         disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript);
946         if (frame->settings())
947             disabledInSettings = !frame->settings()->scriptEnabled();
948     }
949 
950     // Order is important.
951     if (disabledInSettings)
952         *status = PageCommandHandler::Result::Disabled;
953     else if (disabledByScriptController)
954         *status = PageCommandHandler::Result::Forbidden;
955     else
956         *status = PageCommandHandler::Result::Allowed;
957 }
958 
setScriptExecutionDisabled(ErrorString *,bool value)959 void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
960 {
961     m_state->setBoolean(PageAgentState::pageAgentScriptExecutionDisabled, value);
962     if (!mainFrame())
963         return;
964 
965     Settings* settings = mainFrame()->settings();
966     if (settings) {
967         m_ignoreScriptsEnabledNotification = true;
968         settings->setScriptEnabled(!value);
969         m_ignoreScriptsEnabledNotification = false;
970     }
971 }
972 
didClearDocumentOfWindowObject(LocalFrame * frame)973 void InspectorPageAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
974 {
975     if (frame == m_page->mainFrame())
976         m_injectedScriptManager->discardInjectedScripts();
977 
978     if (!m_frontend)
979         return;
980 
981     RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
982     if (scripts) {
983         JSONObject::const_iterator end = scripts->end();
984         for (JSONObject::const_iterator it = scripts->begin(); it != end; ++it) {
985             String scriptText;
986             if (it->value->asString(&scriptText))
987                 frame->script().executeScriptInMainWorld(scriptText);
988         }
989     }
990     if (!m_scriptToEvaluateOnLoadOnce.isEmpty())
991         frame->script().executeScriptInMainWorld(m_scriptToEvaluateOnLoadOnce);
992 }
993 
domContentLoadedEventFired(LocalFrame * frame)994 void InspectorPageAgent::domContentLoadedEventFired(LocalFrame* frame)
995 {
996     if (!frame->isMainFrame())
997         return;
998     m_frontend->domContentEventFired(currentTime());
999 }
1000 
loadEventFired(LocalFrame * frame)1001 void InspectorPageAgent::loadEventFired(LocalFrame* frame)
1002 {
1003     if (!frame->isMainFrame())
1004         return;
1005     m_frontend->loadEventFired(currentTime());
1006 }
1007 
didCommitLoad(LocalFrame *,DocumentLoader * loader)1008 void InspectorPageAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
1009 {
1010     // FIXME: If "frame" is always guaranteed to be in the same Page as loader->frame()
1011     // then all we need to check here is loader->frame()->isMainFrame()
1012     // and we don't need "frame" at all.
1013     if (loader->frame() == m_page->mainFrame()) {
1014         m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce;
1015         m_scriptPreprocessorSource = m_pendingScriptPreprocessor;
1016         m_pendingScriptToEvaluateOnLoadOnce = String();
1017         m_pendingScriptPreprocessor = String();
1018         if (m_inspectorResourceContentLoader)
1019             m_inspectorResourceContentLoader->stop();
1020     }
1021     m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
1022     viewportChanged();
1023 }
1024 
frameAttachedToParent(LocalFrame * frame)1025 void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame)
1026 {
1027     Frame* parentFrame = frame->tree().parent();
1028     if (!parentFrame->isLocalFrame())
1029         parentFrame = 0;
1030     m_frontend->frameAttached(frameId(frame), frameId(toLocalFrame(parentFrame)));
1031 }
1032 
frameDetachedFromParent(LocalFrame * frame)1033 void InspectorPageAgent::frameDetachedFromParent(LocalFrame* frame)
1034 {
1035     HashMap<LocalFrame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
1036     if (iterator != m_frameToIdentifier.end()) {
1037         m_frontend->frameDetached(iterator->value);
1038         m_identifierToFrame.remove(iterator->value);
1039         m_frameToIdentifier.remove(iterator);
1040     }
1041 }
1042 
mainFrame()1043 LocalFrame* InspectorPageAgent::mainFrame()
1044 {
1045     return m_page->deprecatedLocalMainFrame();
1046 }
1047 
frameForId(const String & frameId)1048 LocalFrame* InspectorPageAgent::frameForId(const String& frameId)
1049 {
1050     return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
1051 }
1052 
frameId(LocalFrame * frame)1053 String InspectorPageAgent::frameId(LocalFrame* frame)
1054 {
1055     if (!frame)
1056         return "";
1057     String identifier = m_frameToIdentifier.get(frame);
1058     if (identifier.isNull()) {
1059         identifier = IdentifiersFactory::createIdentifier();
1060         m_frameToIdentifier.set(frame, identifier);
1061         m_identifierToFrame.set(identifier, frame);
1062     }
1063     return identifier;
1064 }
1065 
hasIdForFrame(LocalFrame * frame) const1066 bool InspectorPageAgent::hasIdForFrame(LocalFrame* frame) const
1067 {
1068     return frame && m_frameToIdentifier.contains(frame);
1069 }
1070 
loaderId(DocumentLoader * loader)1071 String InspectorPageAgent::loaderId(DocumentLoader* loader)
1072 {
1073     if (!loader)
1074         return "";
1075     String identifier = m_loaderToIdentifier.get(loader);
1076     if (identifier.isNull()) {
1077         identifier = IdentifiersFactory::createIdentifier();
1078         m_loaderToIdentifier.set(loader, identifier);
1079     }
1080     return identifier;
1081 }
1082 
findFrameWithSecurityOrigin(const String & originRawString)1083 LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
1084 {
1085     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
1086         // FIXME: RemoteFrame security origins are not yet available.
1087         if (!frame->isLocalFrame())
1088             continue;
1089         RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin();
1090         if (documentOrigin->toRawString() == originRawString)
1091             return toLocalFrame(frame);
1092     }
1093     return 0;
1094 }
1095 
assertFrame(ErrorString * errorString,const String & frameId)1096 LocalFrame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
1097 {
1098     LocalFrame* frame = frameForId(frameId);
1099     if (!frame)
1100         *errorString = "No frame for given id found";
1101     return frame;
1102 }
1103 
resourceSourceMapURL(const String & url)1104 const AtomicString& InspectorPageAgent::resourceSourceMapURL(const String& url)
1105 {
1106     DEFINE_STATIC_LOCAL(const AtomicString, sourceMapHttpHeader, ("SourceMap", AtomicString::ConstructFromLiteral));
1107     DEFINE_STATIC_LOCAL(const AtomicString, deprecatedSourceMapHttpHeader, ("X-SourceMap", AtomicString::ConstructFromLiteral));
1108     if (url.isEmpty())
1109         return nullAtom;
1110     LocalFrame* frame = mainFrame();
1111     if (!frame)
1112         return nullAtom;
1113     Resource* resource = cachedResource(frame, KURL(ParsedURLString, url));
1114     if (!resource)
1115         return nullAtom;
1116     const AtomicString& deprecatedHeaderSourceMapURL = resource->response().httpHeaderField(deprecatedSourceMapHttpHeader);
1117     if (!deprecatedHeaderSourceMapURL.isEmpty()) {
1118         // FIXME: add deprecated console message here.
1119         return deprecatedHeaderSourceMapURL;
1120     }
1121     return resource->response().httpHeaderField(sourceMapHttpHeader);
1122 }
1123 
deviceMetricsOverrideEnabled()1124 bool InspectorPageAgent::deviceMetricsOverrideEnabled()
1125 {
1126     return m_enabled && m_deviceMetricsOverridden;
1127 }
1128 
screencastEnabled()1129 bool InspectorPageAgent::screencastEnabled()
1130 {
1131     return m_enabled && m_state->getBoolean(PageAgentState::screencastEnabled);
1132 }
1133 
1134 // static
assertDocumentLoader(ErrorString * errorString,LocalFrame * frame)1135 DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, LocalFrame* frame)
1136 {
1137     DocumentLoader* documentLoader = frame->loader().documentLoader();
1138     if (!documentLoader)
1139         *errorString = "No documentLoader for given frame found";
1140     return documentLoader;
1141 }
1142 
loaderDetachedFromFrame(DocumentLoader * loader)1143 void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
1144 {
1145     HashMap<DocumentLoader*, String>::iterator iterator = m_loaderToIdentifier.find(loader);
1146     if (iterator != m_loaderToIdentifier.end())
1147         m_loaderToIdentifier.remove(iterator);
1148 }
1149 
frameStartedLoading(LocalFrame * frame)1150 void InspectorPageAgent::frameStartedLoading(LocalFrame* frame)
1151 {
1152     m_frontend->frameStartedLoading(frameId(frame));
1153 }
1154 
frameStoppedLoading(LocalFrame * frame)1155 void InspectorPageAgent::frameStoppedLoading(LocalFrame* frame)
1156 {
1157     m_frontend->frameStoppedLoading(frameId(frame));
1158 }
1159 
frameScheduledNavigation(LocalFrame * frame,double delay)1160 void InspectorPageAgent::frameScheduledNavigation(LocalFrame* frame, double delay)
1161 {
1162     m_frontend->frameScheduledNavigation(frameId(frame), delay);
1163 }
1164 
frameClearedScheduledNavigation(LocalFrame * frame)1165 void InspectorPageAgent::frameClearedScheduledNavigation(LocalFrame* frame)
1166 {
1167     m_frontend->frameClearedScheduledNavigation(frameId(frame));
1168 }
1169 
willRunJavaScriptDialog(const String & message)1170 void InspectorPageAgent::willRunJavaScriptDialog(const String& message)
1171 {
1172     m_frontend->javascriptDialogOpening(message);
1173 }
1174 
didRunJavaScriptDialog()1175 void InspectorPageAgent::didRunJavaScriptDialog()
1176 {
1177     m_frontend->javascriptDialogClosed();
1178 }
1179 
didPaint(RenderObject *,const GraphicsLayer *,GraphicsContext * context,const LayoutRect & rect)1180 void InspectorPageAgent::didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext* context, const LayoutRect& rect)
1181 {
1182     if (!m_enabled || m_client->overridesShowPaintRects() || !m_state->getBoolean(PageAgentState::pageAgentShowPaintRects))
1183         return;
1184 
1185     static int colorSelector = 0;
1186     const Color colors[] = {
1187         Color(0, 0x5F, 0, 0x3F),
1188         Color(0, 0xAF, 0, 0x3F),
1189         Color(0, 0xFF, 0, 0x3F),
1190     };
1191 
1192     LayoutRect inflatedRect(rect);
1193     inflatedRect.inflate(-1);
1194     m_overlay->drawOutline(context, inflatedRect, colors[colorSelector++ % WTF_ARRAY_LENGTH(colors)]);
1195 }
1196 
didLayout(RenderObject *)1197 void InspectorPageAgent::didLayout(RenderObject*)
1198 {
1199     if (!m_enabled)
1200         return;
1201     m_overlay->update();
1202     viewportChanged();
1203 }
1204 
didScroll()1205 void InspectorPageAgent::didScroll()
1206 {
1207     if (m_enabled)
1208         m_overlay->update();
1209     viewportChanged();
1210 }
1211 
viewportChanged()1212 void InspectorPageAgent::viewportChanged()
1213 {
1214     if (!m_enabled || !m_deviceMetricsOverridden)
1215         return;
1216     IntSize contentsSize = m_page->deprecatedLocalMainFrame()->view()->contentsSize();
1217     IntRect viewRect = m_page->deprecatedLocalMainFrame()->view()->visibleContentRect();
1218     RefPtr<TypeBuilder::Page::Viewport> viewport = TypeBuilder::Page::Viewport::create()
1219         .setScrollX(viewRect.x())
1220         .setScrollY(viewRect.y())
1221         .setContentsWidth(contentsSize.width())
1222         .setContentsHeight(contentsSize.height())
1223         .setPageScaleFactor(m_page->pageScaleFactor())
1224         .setMinimumPageScaleFactor(m_client->minimumPageScaleFactor())
1225         .setMaximumPageScaleFactor(m_client->maximumPageScaleFactor());
1226     m_frontend->viewportChanged(viewport);
1227 }
1228 
didResizeMainFrame()1229 void InspectorPageAgent::didResizeMainFrame()
1230 {
1231 #if !OS(ANDROID)
1232     if (m_enabled && m_state->getBoolean(PageAgentState::showSizeOnResize))
1233         m_overlay->showAndHideViewSize(m_state->getBoolean(PageAgentState::showGridOnResize));
1234 #endif
1235     m_frontend->frameResized();
1236     viewportChanged();
1237 }
1238 
didRecalculateStyle(int)1239 void InspectorPageAgent::didRecalculateStyle(int)
1240 {
1241     if (m_enabled)
1242         m_overlay->update();
1243 }
1244 
deviceOrPageScaleFactorChanged()1245 void InspectorPageAgent::deviceOrPageScaleFactorChanged()
1246 {
1247     if (m_enabled)
1248         m_overlay->update();
1249     viewportChanged();
1250 }
1251 
scriptsEnabled(bool isEnabled)1252 void InspectorPageAgent::scriptsEnabled(bool isEnabled)
1253 {
1254     if (m_ignoreScriptsEnabledNotification)
1255         return;
1256 
1257     m_frontend->scriptsEnabled(isEnabled);
1258 }
1259 
buildObjectForFrame(LocalFrame * frame)1260 PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(LocalFrame* frame)
1261 {
1262     RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
1263         .setId(frameId(frame))
1264         .setLoaderId(loaderId(frame->loader().documentLoader()))
1265         .setUrl(urlWithoutFragment(frame->document()->url()).string())
1266         .setMimeType(frame->loader().documentLoader()->responseMIMEType())
1267         .setSecurityOrigin(frame->document()->securityOrigin()->toRawString());
1268     // FIXME: This doesn't work for OOPI.
1269     Frame* parentFrame = frame->tree().parent();
1270     if (parentFrame && parentFrame->isLocalFrame())
1271         frameObject->setParentId(frameId(toLocalFrame(parentFrame)));
1272     if (frame->deprecatedLocalOwner()) {
1273         AtomicString name = frame->deprecatedLocalOwner()->getNameAttribute();
1274         if (name.isEmpty())
1275             name = frame->deprecatedLocalOwner()->getAttribute(HTMLNames::idAttr);
1276         frameObject->setName(name);
1277     }
1278 
1279     return frameObject;
1280 }
1281 
buildObjectForFrameTree(LocalFrame * frame)1282 PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(LocalFrame* frame)
1283 {
1284     RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
1285     RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
1286     RefPtr<TypeBuilder::Page::FrameResourceTree> result = TypeBuilder::Page::FrameResourceTree::create()
1287          .setFrame(frameObject)
1288          .setResources(subresources);
1289 
1290     Vector<Resource*> allResources = cachedResourcesForFrame(frame, true);
1291     for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) {
1292         Resource* cachedResource = *it;
1293 
1294         RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
1295             .setUrl(urlWithoutFragment(cachedResource->url()).string())
1296             .setType(cachedResourceTypeJson(*cachedResource))
1297             .setMimeType(cachedResource->response().mimeType());
1298         if (cachedResource->wasCanceled())
1299             resourceObject->setCanceled(true);
1300         else if (cachedResource->status() == Resource::LoadError)
1301             resourceObject->setFailed(true);
1302         subresources->addItem(resourceObject);
1303     }
1304 
1305     Vector<Document*> allImports = InspectorPageAgent::importsForFrame(frame);
1306     for (Vector<Document*>::const_iterator it = allImports.begin(); it != allImports.end(); ++it) {
1307         Document* import = *it;
1308         RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
1309             .setUrl(urlWithoutFragment(import->url()).string())
1310             .setType(resourceTypeJson(InspectorPageAgent::DocumentResource))
1311             .setMimeType(import->suggestedMIMEType());
1312         subresources->addItem(resourceObject);
1313     }
1314 
1315     RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
1316     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1317         if (!child->isLocalFrame())
1318             continue;
1319         if (!childrenArray) {
1320             childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
1321             result->setChildFrames(childrenArray);
1322         }
1323         childrenArray->addItem(buildObjectForFrameTree(toLocalFrame(child)));
1324     }
1325     return result;
1326 }
1327 
updateViewMetricsFromState()1328 void InspectorPageAgent::updateViewMetricsFromState()
1329 {
1330     bool enabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
1331     int width = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
1332     int height = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
1333     bool mobile = m_state->getBoolean(PageAgentState::pageAgentEmulateMobile);
1334     double deviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride);
1335     bool fitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
1336     double scale = m_state->getDouble(PageAgentState::deviceScale, 1);
1337     double offsetX = m_state->getDouble(PageAgentState::deviceOffsetX, 0);
1338     double offsetY = m_state->getDouble(PageAgentState::deviceOffsetY, 0);
1339     updateViewMetrics(enabled, width, height, deviceScaleFactor, mobile, fitWindow, scale, offsetX, offsetY);
1340 }
1341 
updateViewMetrics(bool enabled,int width,int height,double deviceScaleFactor,bool mobile,bool fitWindow,double scale,double offsetX,double offsetY)1342 void InspectorPageAgent::updateViewMetrics(bool enabled, int width, int height, double deviceScaleFactor, bool mobile, bool fitWindow, double scale, double offsetX, double offsetY)
1343 {
1344     if (enabled && !m_page->settings().acceleratedCompositingEnabled())
1345         return;
1346 
1347     m_deviceMetricsOverridden = enabled;
1348     m_emulateMobileEnabled = mobile;
1349     if (enabled)
1350         m_client->setDeviceMetricsOverride(width, height, static_cast<float>(deviceScaleFactor), mobile, fitWindow, static_cast<float>(scale), static_cast<float>(offsetX), static_cast<float>(offsetY));
1351     else
1352         m_client->clearDeviceMetricsOverride();
1353 
1354     Document* document = mainFrame()->document();
1355     if (document) {
1356         document->styleResolverChanged();
1357         document->mediaQueryAffectingValueChanged();
1358     }
1359     InspectorInstrumentation::mediaQueryResultChanged(document);
1360 
1361     if (m_deviceMetricsOverridden) {
1362         m_page->settings().setTextAutosizingEnabled(mobile);
1363         m_page->settings().setPreferCompositingToLCDTextEnabled(mobile);
1364         m_page->settings().setDeviceScaleAdjustment(calculateFontScaleFactor(width, height, static_cast<float>(deviceScaleFactor)));
1365     } else {
1366         m_page->settings().setTextAutosizingEnabled(m_embedderTextAutosizingEnabled);
1367         m_page->settings().setPreferCompositingToLCDTextEnabled(m_embedderPreferCompositingToLCDTextEnabled);
1368         m_page->settings().setDeviceScaleAdjustment(m_embedderFontScaleFactor);
1369     }
1370 
1371     // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
1372     m_client->setShowFPSCounter(m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter) && !m_deviceMetricsOverridden);
1373     m_client->setContinuousPaintingEnabled(m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled) && !m_deviceMetricsOverridden);
1374 }
1375 
updateTouchEventEmulationInPage(bool enabled)1376 void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled)
1377 {
1378     if (!m_touchEmulationEnabled) {
1379         m_originalTouchEnabled = RuntimeEnabledFeatures::touchEnabled();
1380         m_originalDeviceSupportsMouse = m_page->settings().deviceSupportsMouse();
1381         m_originalDeviceSupportsTouch = m_page->settings().deviceSupportsTouch();
1382         m_originalMaxTouchPoints = m_page->settings().maxTouchPoints();
1383     }
1384     RuntimeEnabledFeatures::setTouchEnabled(enabled ? true : m_originalTouchEnabled);
1385     if (!m_originalDeviceSupportsTouch) {
1386         m_page->settings().setDeviceSupportsMouse(enabled ? false : m_originalDeviceSupportsMouse);
1387         m_page->settings().setDeviceSupportsTouch(enabled ? true : m_originalDeviceSupportsTouch);
1388         // Currently emulation does not provide multiple touch points.
1389         m_page->settings().setMaxTouchPoints(enabled ? 1 : m_originalMaxTouchPoints);
1390     }
1391     m_touchEmulationEnabled = enabled;
1392     m_client->setTouchEventEmulationEnabled(enabled);
1393     m_page->deprecatedLocalMainFrame()->view()->layout();
1394 }
1395 
setTouchEmulationEnabled(ErrorString *,bool enabled)1396 void InspectorPageAgent::setTouchEmulationEnabled(ErrorString*, bool enabled)
1397 {
1398     if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
1399         return;
1400 
1401     m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
1402     updateTouchEventEmulationInPage(enabled);
1403 }
1404 
setEmulatedMedia(ErrorString *,const String & media)1405 void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media)
1406 {
1407     String currentMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
1408     if (media == currentMedia)
1409         return;
1410 
1411     m_state->setString(PageAgentState::pageAgentEmulatedMedia, media);
1412     Document* document = 0;
1413     if (m_page->mainFrame())
1414         document = m_page->deprecatedLocalMainFrame()->document();
1415     if (document) {
1416         document->mediaQueryAffectingValueChanged();
1417         document->styleResolverChanged();
1418         document->updateLayout();
1419     }
1420 }
1421 
applyViewportStyleOverride(StyleResolver * resolver)1422 bool InspectorPageAgent::applyViewportStyleOverride(StyleResolver* resolver)
1423 {
1424     if (!m_deviceMetricsOverridden || !m_emulateMobileEnabled)
1425         return false;
1426 
1427     RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
1428     styleSheet->parseString(String(viewportAndroidCss, sizeof(viewportAndroidCss)));
1429     OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
1430     ruleSet->addRulesFromSheet(styleSheet.get(), MediaQueryEvaluator("screen"));
1431     resolver->viewportStyleResolver()->collectViewportRules(ruleSet.get(), ViewportStyleResolver::UserAgentOrigin);
1432     return true;
1433 }
1434 
applyEmulatedMedia(String * media)1435 void InspectorPageAgent::applyEmulatedMedia(String* media)
1436 {
1437     String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
1438     if (!emulatedMedia.isEmpty())
1439         *media = emulatedMedia;
1440 }
1441 
compositingEnabled(ErrorString * errorString)1442 bool InspectorPageAgent::compositingEnabled(ErrorString* errorString)
1443 {
1444     if (!m_page->settings().acceleratedCompositingEnabled()) {
1445         if (errorString)
1446             *errorString = "Compositing mode is not supported";
1447         return false;
1448     }
1449     return true;
1450 }
1451 
startScreencast(ErrorString *,const String * format,const int * quality,const int * maxWidth,const int * maxHeight)1452 void InspectorPageAgent::startScreencast(ErrorString*, const String* format, const int* quality, const int* maxWidth, const int* maxHeight)
1453 {
1454     m_state->setBoolean(PageAgentState::screencastEnabled, true);
1455 }
1456 
stopScreencast(ErrorString *)1457 void InspectorPageAgent::stopScreencast(ErrorString*)
1458 {
1459     m_state->setBoolean(PageAgentState::screencastEnabled, false);
1460 }
1461 
setShowViewportSizeOnResize(ErrorString *,bool show,const bool * showGrid)1462 void InspectorPageAgent::setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid)
1463 {
1464     m_state->setBoolean(PageAgentState::showSizeOnResize, show);
1465     m_state->setBoolean(PageAgentState::showGridOnResize, asBool(showGrid));
1466 }
1467 
clearEditedResourcesContent()1468 void InspectorPageAgent::clearEditedResourcesContent()
1469 {
1470     m_editedResourceContent.clear();
1471 }
1472 
addEditedResourceContent(const String & url,const String & content)1473 void InspectorPageAgent::addEditedResourceContent(const String& url, const String& content)
1474 {
1475     m_editedResourceContent.set(url, content);
1476 }
1477 
getEditedResourceContent(const String & url,String * content)1478 bool InspectorPageAgent::getEditedResourceContent(const String& url, String* content)
1479 {
1480     if (!m_editedResourceContent.contains(url))
1481         return false;
1482     *content = m_editedResourceContent.get(url);
1483     return true;
1484 }
1485 
trace(Visitor * visitor)1486 void InspectorPageAgent::trace(Visitor* visitor)
1487 {
1488     visitor->trace(m_page);
1489     visitor->trace(m_injectedScriptManager);
1490     visitor->trace(m_inspectorResourceContentLoader);
1491     InspectorBaseAgent::trace(visitor);
1492 }
1493 
1494 } // namespace blink
1495 
1496