2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "core/inspector/InspectorPageAgent.h"
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/MIMETypeRegistry.h"
78 #include "platform/UserGestureIndicator.h"
79 #include "platform/weborigin/SecurityOrigin.h"
80 #include "wtf/CurrentTime.h"
81 #include "wtf/ListHashSet.h"
82 #include "wtf/Vector.h"
83 #include "wtf/text/Base64.h"
84 #include "wtf/text/TextEncoding.h"
88 namespace PageAgentState {
89 static const char pageAgentEnabled[] = "pageAgentEnabled";
90 static const char pageAgentScriptExecutionDisabled[] = "pageAgentScriptExecutionDisabled";
91 static const char pageAgentScriptsToEvaluateOnLoad[] = "pageAgentScriptsToEvaluateOnLoad";
92 static const char deviceMetricsOverrideEnabled[] = "deviceMetricsOverrideEnabled";
93 static const char pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
94 static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
95 static const char pageAgentDeviceScaleFactorOverride[] = "pageAgentDeviceScaleFactorOverride";
96 static const char pageAgentEmulateMobile[] = "pageAgentEmulateMobile";
97 static const char pageAgentFitWindow[] = "pageAgentFitWindow";
98 static const char deviceScale[] = "deviceScale";
99 static const char deviceOffsetX[] = "deviceOffsetX";
100 static const char deviceOffsetY[] = "deviceOffsetY";
101 static const char pageAgentShowFPSCounter[] = "pageAgentShowFPSCounter";
102 static const char pageAgentContinuousPaintingEnabled[] = "pageAgentContinuousPaintingEnabled";
103 static const char pageAgentShowPaintRects[] = "pageAgentShowPaintRects";
104 static const char pageAgentShowDebugBorders[] = "pageAgentShowDebugBorders";
105 static const char pageAgentShowScrollBottleneckRects[] = "pageAgentShowScrollBottleneckRects";
106 static const char touchEventEmulationEnabled[] = "touchEventEmulationEnabled";
107 static const char pageAgentEmulatedMedia[] = "pageAgentEmulatedMedia";
108 static const char showSizeOnResize[] = "showSizeOnResize";
109 static const char showGridOnResize[] = "showGridOnResize";
110 static const char screencastEnabled[] = "screencastEnabled";
115 KURL urlWithoutFragment(const KURL& url)
118 result.removeFragmentIdentifier();
122 static float calculateFontScaleFactor(int width, int height, float deviceScaleFactor)
124 // Chromium on Android uses a device scale adjustment for fonts used in text autosizing for
125 // improved legibility. This function computes this adjusted value for text autosizing.
126 // For a description of the Android device scale adjustment algorithm, see:
127 // chrome/browser/chrome_content_browser_client.cc, GetDeviceScaleAdjustment(...)
128 if (!width || !height || !deviceScaleFactor)
131 static const float kMinFSM = 1.05f;
132 static const int kWidthForMinFSM = 320;
133 static const float kMaxFSM = 1.3f;
134 static const int kWidthForMaxFSM = 800;
136 float minWidth = std::min(width, height) / deviceScaleFactor;
137 if (minWidth <= kWidthForMinFSM)
139 if (minWidth >= kWidthForMaxFSM)
142 // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
143 float ratio = static_cast<float>(minWidth - kWidthForMinFSM) / (kWidthForMaxFSM - kWidthForMinFSM);
144 return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
149 class InspectorPageAgent::GetResourceContentLoadListener final : public VoidCallback {
151 GetResourceContentLoadListener(InspectorPageAgent*, const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback>);
152 virtual void trace(Visitor*) override;
153 virtual void handleEvent() override;
155 RawPtrWillBeMember<InspectorPageAgent> m_pageAgent;
158 RefPtrWillBeMember<GetResourceContentCallback> m_callback;
161 InspectorPageAgent::GetResourceContentLoadListener::GetResourceContentLoadListener(InspectorPageAgent* pageAgent, const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)
162 : m_pageAgent(pageAgent)
165 , m_callback(callback)
169 void InspectorPageAgent::GetResourceContentLoadListener::trace(Visitor* visitor)
171 visitor->trace(m_pageAgent);
172 visitor->trace(m_callback);
173 VoidCallback::trace(visitor);
176 void InspectorPageAgent::GetResourceContentLoadListener::handleEvent()
178 if (!m_callback->isActive())
180 m_pageAgent->getResourceContentAfterResourcesContentLoaded(m_frameId, m_url, m_callback);
183 static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
186 WTF::TextEncoding encoding(textEncodingName);
187 if (!encoding.isValid())
188 encoding = WindowsLatin1Encoding();
189 *result = encoding.decode(buffer, size);
195 static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize)
197 *hasZeroSize = false;
201 if (cachedResource->dataBufferingPolicy() == DoNotBufferData)
204 // Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0.
205 if (!cachedResource->encodedSize()) {
210 if (cachedResource->isPurgeable()) {
211 // If the resource is purgeable then make it unpurgeable to get
212 // get its data. This might fail, in which case we return an
214 // FIXME: should we do something else in the case of a purged
215 // resource that informs the user why there is no data in the
217 if (!cachedResource->lock())
224 static bool hasTextContent(Resource* cachedResource)
226 Resource::Type type = cachedResource->type();
227 return type == Resource::CSSStyleSheet || type == Resource::XSLStyleSheet || type == Resource::Script || type == Resource::Raw || type == Resource::ImportResource || type == Resource::MainResource;
230 PassOwnPtr<TextResourceDecoder> InspectorPageAgent::createResourceTextDecoder(const String& mimeType, const String& textEncodingName)
232 if (!textEncodingName.isEmpty())
233 return TextResourceDecoder::create("text/plain", textEncodingName);
234 if (DOMImplementation::isXMLMIMEType(mimeType)) {
235 OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
236 decoder->useLenientXMLDecoding();
237 return decoder.release();
239 if (equalIgnoringCase(mimeType, "text/html"))
240 return TextResourceDecoder::create("text/html", "UTF-8");
241 if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || DOMImplementation::isJSONMIMEType(mimeType))
242 return TextResourceDecoder::create("text/plain", "UTF-8");
243 if (DOMImplementation::isTextMIMEType(mimeType))
244 return TextResourceDecoder::create("text/plain", "ISO-8859-1");
245 return PassOwnPtr<TextResourceDecoder>();
248 static void resourceContent(ErrorString* errorString, LocalFrame* frame, const KURL& url, String* result, bool* base64Encoded)
250 DocumentLoader* loader = InspectorPageAgent::assertDocumentLoader(errorString, frame);
254 if (!InspectorPageAgent::cachedResourceContent(InspectorPageAgent::cachedResource(frame, url), result, base64Encoded))
255 *errorString = "No resource with given URL found";
258 static bool encodeCachedResourceContent(Resource* cachedResource, bool hasZeroSize, String* result, bool* base64Encoded)
260 *base64Encoded = true;
261 RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer();
266 *result = base64Encode(buffer->data(), buffer->size());
270 bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded)
273 bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize);
277 if (!hasTextContent(cachedResource))
278 return encodeCachedResourceContent(cachedResource, hasZeroSize, result, base64Encoded);
279 *base64Encoded = false;
286 if (cachedResource) {
287 switch (cachedResource->type()) {
288 case Resource::CSSStyleSheet:
289 *result = toCSSStyleSheetResource(cachedResource)->sheetText(false);
291 case Resource::Script:
292 *result = cachedResource->resourceBuffer() ? toScriptResource(cachedResource)->decodedText() : toScriptResource(cachedResource)->script();
294 case Resource::Raw: {
295 SharedBuffer* buffer = cachedResource->resourceBuffer();
298 OwnPtr<TextResourceDecoder> decoder = InspectorPageAgent::createResourceTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName());
300 return encodeCachedResourceContent(cachedResource, hasZeroSize, result, base64Encoded);
301 String content = decoder->decode(buffer->data(), buffer->size());
302 *result = content + decoder->flush();
306 SharedBuffer* buffer = cachedResource->resourceBuffer();
307 return decodeBuffer(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, cachedResource->response().textEncodingName(), result);
314 bool InspectorPageAgent::sharedBufferContent(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, bool withBase64Encode, String* result)
316 return dataContent(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, textEncodingName, withBase64Encode, result);
319 bool InspectorPageAgent::dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result)
321 if (withBase64Encode) {
322 *result = base64Encode(data, size);
326 return decodeBuffer(data, size, textEncodingName, result);
329 PassOwnPtrWillBeRawPtr<InspectorPageAgent> InspectorPageAgent::create(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
331 return adoptPtrWillBeNoop(new InspectorPageAgent(page, injectedScriptManager, client, overlay));
334 Resource* InspectorPageAgent::cachedResource(LocalFrame* frame, const KURL& url)
336 Document* document = frame->document();
339 Resource* cachedResource = document->fetcher()->cachedResource(url);
340 if (!cachedResource) {
341 Vector<Document*> allImports = InspectorPageAgent::importsForFrame(frame);
342 for (Vector<Document*>::const_iterator it = allImports.begin(); it != allImports.end(); ++it) {
343 Document* import = *it;
344 cachedResource = import->fetcher()->cachedResource(url);
350 cachedResource = memoryCache()->resourceForURL(url, document->fetcher()->getCacheIdentifier());
351 return cachedResource;
354 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType)
356 switch (resourceType) {
357 case DocumentResource:
358 return TypeBuilder::Page::ResourceType::Document;
360 return TypeBuilder::Page::ResourceType::Font;
362 return TypeBuilder::Page::ResourceType::Image;
364 return TypeBuilder::Page::ResourceType::Media;
366 return TypeBuilder::Page::ResourceType::Script;
367 case StylesheetResource:
368 return TypeBuilder::Page::ResourceType::Stylesheet;
369 case TextTrackResource:
370 return TypeBuilder::Page::ResourceType::TextTrack;
372 return TypeBuilder::Page::ResourceType::XHR;
373 case WebSocketResource:
374 return TypeBuilder::Page::ResourceType::WebSocket;
376 return TypeBuilder::Page::ResourceType::Other;
378 return TypeBuilder::Page::ResourceType::Other;
381 InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Resource& cachedResource)
383 switch (cachedResource.type()) {
384 case Resource::Image:
385 return InspectorPageAgent::ImageResource;
387 return InspectorPageAgent::FontResource;
388 case Resource::Media:
389 return InspectorPageAgent::MediaResource;
390 case Resource::TextTrack:
391 return InspectorPageAgent::TextTrackResource;
392 case Resource::CSSStyleSheet:
394 case Resource::XSLStyleSheet:
395 return InspectorPageAgent::StylesheetResource;
396 case Resource::Script:
397 return InspectorPageAgent::ScriptResource;
398 case Resource::ImportResource:
400 case Resource::MainResource:
401 return InspectorPageAgent::DocumentResource;
405 return InspectorPageAgent::OtherResource;
408 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson(const Resource& cachedResource)
410 return resourceTypeJson(cachedResourceType(cachedResource));
413 InspectorPageAgent::InspectorPageAgent(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
414 : InspectorBaseAgent<InspectorPageAgent>("Page")
416 , m_injectedScriptManager(injectedScriptManager)
420 , m_lastScriptIdentifier(0)
422 , m_ignoreScriptsEnabledNotification(false)
423 , m_deviceMetricsOverridden(false)
424 , m_emulateMobileEnabled(false)
425 , m_touchEmulationEnabled(false)
426 , m_originalTouchEnabled(false)
427 , m_originalDeviceSupportsMouse(false)
428 , m_originalDeviceSupportsTouch(false)
429 , m_originalMaxTouchPoints(0)
430 , m_embedderTextAutosizingEnabled(m_page->settings().textAutosizingEnabled())
431 , m_embedderFontScaleFactor(m_page->settings().deviceScaleAdjustment())
432 , m_embedderPreferCompositingToLCDTextEnabled(m_page->settings().preferCompositingToLCDTextEnabled())
436 void InspectorPageAgent::setTextAutosizingEnabled(bool enabled)
438 m_embedderTextAutosizingEnabled = enabled;
439 bool emulateMobileEnabled = m_enabled && m_deviceMetricsOverridden && m_emulateMobileEnabled;
440 if (!emulateMobileEnabled)
441 m_page->settings().setTextAutosizingEnabled(enabled);
444 void InspectorPageAgent::setDeviceScaleAdjustment(float deviceScaleAdjustment)
446 m_embedderFontScaleFactor = deviceScaleAdjustment;
447 bool emulateMobileEnabled = m_enabled && m_deviceMetricsOverridden && m_emulateMobileEnabled;
448 if (!emulateMobileEnabled)
449 m_page->settings().setDeviceScaleAdjustment(deviceScaleAdjustment);
452 void InspectorPageAgent::setPreferCompositingToLCDTextEnabled(bool enabled)
454 m_embedderPreferCompositingToLCDTextEnabled = enabled;
455 bool emulateMobileEnabled = m_enabled && m_deviceMetricsOverridden && m_emulateMobileEnabled;
456 if (!emulateMobileEnabled)
457 m_page->settings().setPreferCompositingToLCDTextEnabled(enabled);
460 void InspectorPageAgent::setFrontend(InspectorFrontend* frontend)
462 m_frontend = frontend->page();
465 void InspectorPageAgent::clearFrontend()
472 void InspectorPageAgent::restore()
474 if (m_state->getBoolean(PageAgentState::pageAgentEnabled)) {
477 bool scriptExecutionDisabled = m_state->getBoolean(PageAgentState::pageAgentScriptExecutionDisabled);
478 setScriptExecutionDisabled(0, scriptExecutionDisabled);
479 bool showPaintRects = m_state->getBoolean(PageAgentState::pageAgentShowPaintRects);
480 setShowPaintRects(0, showPaintRects);
481 bool showDebugBorders = m_state->getBoolean(PageAgentState::pageAgentShowDebugBorders);
482 setShowDebugBorders(0, showDebugBorders);
483 bool showFPSCounter = m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter);
484 setShowFPSCounter(0, showFPSCounter);
485 String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
486 setEmulatedMedia(0, emulatedMedia);
487 bool continuousPaintingEnabled = m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled);
488 setContinuousPaintingEnabled(0, continuousPaintingEnabled);
489 bool showScrollBottleneckRects = m_state->getBoolean(PageAgentState::pageAgentShowScrollBottleneckRects);
490 setShowScrollBottleneckRects(0, showScrollBottleneckRects);
492 updateViewMetricsFromState();
493 updateTouchEventEmulationInPage(m_state->getBoolean(PageAgentState::touchEventEmulationEnabled));
497 void InspectorPageAgent::enable(ErrorString*)
500 m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
501 m_instrumentingAgents->setInspectorPageAgent(this);
502 if (m_inspectorResourceContentLoader)
503 m_inspectorResourceContentLoader->dispose();
504 m_inspectorResourceContentLoader = adoptPtrWillBeNoop(new InspectorResourceContentLoader(m_page));
507 void InspectorPageAgent::discardAgent()
509 if (!m_inspectorResourceContentLoader)
511 m_inspectorResourceContentLoader->dispose();
512 m_inspectorResourceContentLoader.clear();
515 void InspectorPageAgent::disable(ErrorString*)
518 m_state->setBoolean(PageAgentState::pageAgentEnabled, false);
519 m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
521 m_instrumentingAgents->setInspectorPageAgent(0);
522 if (m_inspectorResourceContentLoader) {
523 m_inspectorResourceContentLoader->dispose();
524 m_inspectorResourceContentLoader.clear();
526 m_deviceMetricsOverridden = false;
528 setShowPaintRects(0, false);
529 setShowDebugBorders(0, false);
530 setShowFPSCounter(0, false);
531 setEmulatedMedia(0, String());
532 if (m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled))
533 setContinuousPaintingEnabled(0, false);
534 setShowScrollBottleneckRects(0, false);
535 setShowViewportSizeOnResize(0, false, 0);
538 if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled)) {
539 updateTouchEventEmulationInPage(false);
540 m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, false);
543 if (!deviceMetricsChanged(false, 0, 0, 0, false, false, 1, 0, 0))
546 // When disabling the agent, reset the override values if necessary.
547 updateViewMetrics(false, 0, 0, 0, false, false, 1, 0, 0);
548 m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
549 m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
550 m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
551 m_state->setBoolean(PageAgentState::pageAgentEmulateMobile, false);
552 m_state->setBoolean(PageAgentState::pageAgentFitWindow, false);
553 m_state->setDouble(PageAgentState::deviceScale, 1);
554 m_state->setDouble(PageAgentState::deviceOffsetX, 0);
555 m_state->setDouble(PageAgentState::deviceOffsetY, 0);
558 void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier)
560 RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
562 scripts = JSONObject::create();
563 m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
565 // Assure we don't override existing ids -- m_lastScriptIdentifier could get out of sync WRT actual
566 // scripts once we restored the scripts from the cookie during navigation.
568 *identifier = String::number(++m_lastScriptIdentifier);
569 } while (scripts->find(*identifier) != scripts->end());
570 scripts->setString(*identifier, source);
572 // Force cookie serialization.
573 m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
576 void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const String& identifier)
578 RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
579 if (!scripts || scripts->find(identifier) == scripts->end()) {
580 *error = "Script not found";
583 scripts->remove(identifier);
586 void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor)
588 m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
589 m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
590 m_page->deprecatedLocalMainFrame()->loader().reload(asBool(optionalIgnoreCache) ? EndToEndReload : NormalReload);
593 void InspectorPageAgent::navigate(ErrorString*, const String& url, String* outFrameId)
595 LocalFrame* frame = m_page->deprecatedLocalMainFrame();
596 *outFrameId = frameId(frame);
599 static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
601 return TypeBuilder::Page::Cookie::create()
602 .setName(cookie.name)
603 .setValue(cookie.value)
604 .setDomain(cookie.domain)
605 .setPath(cookie.path)
606 .setExpires(cookie.expires)
607 .setSize((cookie.name.length() + cookie.value.length()))
608 .setHttpOnly(cookie.httpOnly)
609 .setSecure(cookie.secure)
610 .setSession(cookie.session)
614 static PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > buildArrayForCookies(ListHashSet<Cookie>& cookiesList)
616 RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > cookies = TypeBuilder::Array<TypeBuilder::Page::Cookie>::create();
618 ListHashSet<Cookie>::iterator end = cookiesList.end();
619 ListHashSet<Cookie>::iterator it = cookiesList.begin();
620 for (int i = 0; it != end; ++it, i++)
621 cookies->addItem(buildObjectForCookie(*it));
626 static void cachedResourcesForDocument(Document* document, Vector<Resource*>& result, bool skipXHRs)
628 const ResourceFetcher::DocumentResourceMap& allResources = document->fetcher()->allResources();
629 ResourceFetcher::DocumentResourceMap::const_iterator end = allResources.end();
630 for (ResourceFetcher::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
631 Resource* cachedResource = it->value.get();
633 switch (cachedResource->type()) {
634 case Resource::Image:
635 // Skip images that were not auto loaded (images disabled in the user agent).
636 if (toImageResource(cachedResource)->stillNeedsLoad())
640 // Skip fonts that were referenced in CSS but never used/downloaded.
641 if (toFontResource(cachedResource)->stillNeedsLoad())
649 // All other Resource types download immediately.
653 result.append(cachedResource);
658 Vector<Document*> InspectorPageAgent::importsForFrame(LocalFrame* frame)
660 Vector<Document*> result;
661 Document* rootDocument = frame->document();
663 if (HTMLImportsController* controller = rootDocument->importsController()) {
664 for (size_t i = 0; i < controller->loaderCount(); ++i) {
665 if (Document* document = controller->loaderAt(i)->document())
666 result.append(document);
673 static Vector<Resource*> cachedResourcesForFrame(LocalFrame* frame, bool skipXHRs)
675 Vector<Resource*> result;
676 Document* rootDocument = frame->document();
677 Vector<Document*> loaders = InspectorPageAgent::importsForFrame(frame);
679 cachedResourcesForDocument(rootDocument, result, skipXHRs);
680 for (size_t i = 0; i < loaders.size(); ++i)
681 cachedResourcesForDocument(loaders[i], result, skipXHRs);
686 static Vector<KURL> allResourcesURLsForFrame(LocalFrame* frame)
690 result.append(urlWithoutFragment(frame->loader().documentLoader()->url()));
692 Vector<Resource*> allResources = cachedResourcesForFrame(frame, false);
693 for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it)
694 result.append(urlWithoutFragment((*it)->url()));
699 void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies)
701 ListHashSet<Cookie> rawCookiesList;
703 for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
704 if (!frame->isLocalFrame())
706 Document* document = toLocalFrame(frame)->document();
707 Vector<KURL> allURLs = allResourcesURLsForFrame(toLocalFrame(frame));
708 for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
709 Vector<Cookie> docCookiesList;
710 getRawCookies(document, *it, docCookiesList);
711 int cookiesSize = docCookiesList.size();
712 for (int i = 0; i < cookiesSize; i++) {
713 if (!rawCookiesList.contains(docCookiesList[i]))
714 rawCookiesList.add(docCookiesList[i]);
719 cookies = buildArrayForCookies(rawCookiesList);
722 void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
724 KURL parsedURL(ParsedURLString, url);
725 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame())) {
726 if (frame->isLocalFrame())
727 blink::deleteCookie(toLocalFrame(frame)->document(), parsedURL, cookieName);
731 void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>& object)
733 object = buildObjectForFrameTree(m_page->deprecatedLocalMainFrame());
736 void InspectorPageAgent::getResourceContentAfterResourcesContentLoaded(const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)
738 ErrorString errorString;
739 LocalFrame* frame = assertFrame(&errorString, frameId);
741 callback->sendFailure(errorString);
746 resourceContent(&errorString, frame, KURL(ParsedURLString, url), &content, &base64Encoded);
747 if (!errorString.isEmpty()) {
748 callback->sendFailure(errorString);
751 callback->sendSuccess(content, base64Encoded);
754 void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, PassRefPtrWillBeRawPtr<GetResourceContentCallback> callback)
757 if (getEditedResourceContent(url, &content)) {
758 callback->sendSuccess(content, false);
761 if (!m_inspectorResourceContentLoader) {
762 callback->sendFailure("Agent is not enabled.");
765 m_inspectorResourceContentLoader->ensureResourcesContentLoaded(new GetResourceContentLoadListener(this, frameId, url, callback));
768 static bool textContentForResource(Resource* cachedResource, String* result)
770 if (hasTextContent(cachedResource)) {
773 if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {
774 ASSERT(!base64Encoded);
781 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)
783 results = TypeBuilder::Array<TypeBuilder::Page::SearchMatch>::create();
785 LocalFrame* frame = frameForId(frameId);
786 KURL kurl(ParsedURLString, url);
788 FrameLoader* frameLoader = frame ? &frame->loader() : 0;
789 DocumentLoader* loader = frameLoader ? frameLoader->documentLoader() : 0;
794 bool success = false;
795 Resource* resource = cachedResource(frame, kurl);
797 success = textContentForResource(resource, &content);
802 results = ContentSearchUtils::searchInTextByLines(content, query, asBool(optionalCaseSensitive), asBool(optionalIsRegex));
805 void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
807 LocalFrame* frame = assertFrame(errorString, frameId);
811 Document* document = frame->document();
813 *errorString = "No Document instance to set HTML for";
816 DOMPatchSupport::patchDocument(*document, html);
819 void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int width, int height, double deviceScaleFactor, bool mobile, bool fitWindow, const double* optionalScale, const double* optionalOffsetX, const double* optionalOffsetY)
821 const static long maxDimension = 10000000;
822 const static double maxScale = 10;
824 double scale = optionalScale ? *optionalScale : 1;
825 double offsetX = optionalOffsetX ? *optionalOffsetX : 0;
826 double offsetY = optionalOffsetY ? *optionalOffsetY : 0;
828 if (width < 0 || height < 0 || width > maxDimension || height > maxDimension) {
829 *errorString = "Width and height values must be positive, not greater than " + String::number(maxDimension);
833 if (deviceScaleFactor < 0) {
834 *errorString = "deviceScaleFactor must be non-negative";
838 if (scale <= 0 || scale > maxScale) {
839 *errorString = "scale must be positive, not greater than " + String::number(maxScale);
843 Settings& settings = m_page->settings();
844 if (!settings.acceleratedCompositingEnabled()) {
846 *errorString = "Compositing mode is not supported";
850 if (!deviceMetricsChanged(true, width, height, deviceScaleFactor, mobile, fitWindow, scale, offsetX, offsetY))
853 m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, true);
854 m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
855 m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
856 m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, deviceScaleFactor);
857 m_state->setBoolean(PageAgentState::pageAgentEmulateMobile, mobile);
858 m_state->setBoolean(PageAgentState::pageAgentFitWindow, fitWindow);
859 m_state->setDouble(PageAgentState::deviceScale, scale);
860 m_state->setDouble(PageAgentState::deviceOffsetX, offsetX);
861 m_state->setDouble(PageAgentState::deviceOffsetY, offsetY);
862 updateViewMetricsFromState();
865 void InspectorPageAgent::clearDeviceMetricsOverride(ErrorString*)
867 if (m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled)) {
868 m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, false);
869 updateViewMetricsFromState();
873 void InspectorPageAgent::resetScrollAndPageScaleFactor(ErrorString*)
875 m_client->resetScrollAndPageScaleFactor();
878 void InspectorPageAgent::setPageScaleFactor(ErrorString*, double pageScaleFactor)
880 m_client->setPageScaleFactor(static_cast<float>(pageScaleFactor));
883 bool InspectorPageAgent::deviceMetricsChanged(bool enabled, int width, int height, double deviceScaleFactor, bool mobile, bool fitWindow, double scale, double offsetX, double offsetY)
885 bool currentEnabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
886 // These two always fit an int.
887 int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
888 int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
889 double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
890 bool currentMobile = m_state->getBoolean(PageAgentState::pageAgentEmulateMobile);
891 bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
892 double currentScale = m_state->getDouble(PageAgentState::deviceScale, 1);
893 double currentOffsetX = m_state->getDouble(PageAgentState::deviceOffsetX, 0);
894 double currentOffsetY = m_state->getDouble(PageAgentState::deviceOffsetY, 0);
896 return enabled != currentEnabled
897 || width != currentWidth
898 || height != currentHeight
899 || deviceScaleFactor != currentDeviceScaleFactor
900 || mobile != currentMobile
901 || fitWindow != currentFitWindow
902 || scale != currentScale
903 || offsetX != currentOffsetX
904 || offsetY != currentOffsetY;
907 void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
909 m_state->setBoolean(PageAgentState::pageAgentShowPaintRects, show);
910 m_client->setShowPaintRects(show);
912 if (!show && mainFrame() && mainFrame()->view())
913 mainFrame()->view()->invalidate();
916 void InspectorPageAgent::setShowDebugBorders(ErrorString* errorString, bool show)
918 m_state->setBoolean(PageAgentState::pageAgentShowDebugBorders, show);
919 if (show && !compositingEnabled(errorString))
921 m_client->setShowDebugBorders(show);
924 void InspectorPageAgent::setShowFPSCounter(ErrorString* errorString, bool show)
926 // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
927 m_state->setBoolean(PageAgentState::pageAgentShowFPSCounter, show);
928 if (show && !compositingEnabled(errorString))
930 m_client->setShowFPSCounter(show && !m_deviceMetricsOverridden);
933 void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString* errorString, bool enabled)
935 m_state->setBoolean(PageAgentState::pageAgentContinuousPaintingEnabled, enabled);
936 if (enabled && !compositingEnabled(errorString))
938 m_client->setContinuousPaintingEnabled(enabled && !m_deviceMetricsOverridden);
941 void InspectorPageAgent::setShowScrollBottleneckRects(ErrorString* errorString, bool show)
943 m_state->setBoolean(PageAgentState::pageAgentShowScrollBottleneckRects, show);
944 if (show && !compositingEnabled(errorString))
946 m_client->setShowScrollBottleneckRects(show);
949 void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum* status)
951 bool disabledByScriptController = false;
952 bool disabledInSettings = false;
953 LocalFrame* frame = mainFrame();
955 disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript);
956 if (frame->settings())
957 disabledInSettings = !frame->settings()->scriptEnabled();
960 // Order is important.
961 if (disabledInSettings)
962 *status = PageCommandHandler::Result::Disabled;
963 else if (disabledByScriptController)
964 *status = PageCommandHandler::Result::Forbidden;
966 *status = PageCommandHandler::Result::Allowed;
969 void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
971 m_state->setBoolean(PageAgentState::pageAgentScriptExecutionDisabled, value);
975 Settings* settings = mainFrame()->settings();
977 m_ignoreScriptsEnabledNotification = true;
978 settings->setScriptEnabled(!value);
979 m_ignoreScriptsEnabledNotification = false;
983 void InspectorPageAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
985 if (frame == m_page->mainFrame())
986 m_injectedScriptManager->discardInjectedScripts();
991 RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
993 JSONObject::const_iterator end = scripts->end();
994 for (JSONObject::const_iterator it = scripts->begin(); it != end; ++it) {
996 if (it->value->asString(&scriptText))
997 frame->script().executeScriptInMainWorld(scriptText);
1000 if (!m_scriptToEvaluateOnLoadOnce.isEmpty())
1001 frame->script().executeScriptInMainWorld(m_scriptToEvaluateOnLoadOnce);
1004 void InspectorPageAgent::domContentLoadedEventFired(LocalFrame* frame)
1006 if (!frame->isMainFrame())
1008 m_frontend->domContentEventFired(currentTime());
1011 void InspectorPageAgent::loadEventFired(LocalFrame* frame)
1013 if (!frame->isMainFrame())
1015 m_frontend->loadEventFired(currentTime());
1018 void InspectorPageAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
1020 // FIXME: If "frame" is always guaranteed to be in the same Page as loader->frame()
1021 // then all we need to check here is loader->frame()->isMainFrame()
1022 // and we don't need "frame" at all.
1023 if (loader->frame() == m_page->mainFrame()) {
1024 m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce;
1025 m_scriptPreprocessorSource = m_pendingScriptPreprocessor;
1026 m_pendingScriptToEvaluateOnLoadOnce = String();
1027 m_pendingScriptPreprocessor = String();
1028 if (m_inspectorResourceContentLoader)
1029 m_inspectorResourceContentLoader->stop();
1031 m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
1035 void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame)
1037 Frame* parentFrame = frame->tree().parent();
1038 if (!parentFrame->isLocalFrame())
1040 m_frontend->frameAttached(frameId(frame), frameId(toLocalFrame(parentFrame)));
1043 void InspectorPageAgent::frameDetachedFromParent(LocalFrame* frame)
1045 HashMap<LocalFrame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
1046 if (iterator != m_frameToIdentifier.end()) {
1047 m_frontend->frameDetached(iterator->value);
1048 m_identifierToFrame.remove(iterator->value);
1049 m_frameToIdentifier.remove(iterator);
1053 LocalFrame* InspectorPageAgent::mainFrame()
1055 return m_page->deprecatedLocalMainFrame();
1058 LocalFrame* InspectorPageAgent::frameForId(const String& frameId)
1060 return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
1063 String InspectorPageAgent::frameId(LocalFrame* frame)
1067 String identifier = m_frameToIdentifier.get(frame);
1068 if (identifier.isNull()) {
1069 identifier = IdentifiersFactory::createIdentifier();
1070 m_frameToIdentifier.set(frame, identifier);
1071 m_identifierToFrame.set(identifier, frame);
1076 bool InspectorPageAgent::hasIdForFrame(LocalFrame* frame) const
1078 return frame && m_frameToIdentifier.contains(frame);
1081 String InspectorPageAgent::loaderId(DocumentLoader* loader)
1085 String identifier = m_loaderToIdentifier.get(loader);
1086 if (identifier.isNull()) {
1087 identifier = IdentifiersFactory::createIdentifier();
1088 m_loaderToIdentifier.set(loader, identifier);
1093 LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
1095 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
1096 // FIXME: RemoteFrame security origins are not yet available.
1097 if (!frame->isLocalFrame())
1099 RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin();
1100 if (documentOrigin->toRawString() == originRawString)
1101 return toLocalFrame(frame);
1106 LocalFrame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
1108 LocalFrame* frame = frameForId(frameId);
1110 *errorString = "No frame for given id found";
1114 const AtomicString& InspectorPageAgent::resourceSourceMapURL(const String& url)
1116 DEFINE_STATIC_LOCAL(const AtomicString, sourceMapHttpHeader, ("SourceMap", AtomicString::ConstructFromLiteral));
1117 DEFINE_STATIC_LOCAL(const AtomicString, deprecatedSourceMapHttpHeader, ("X-SourceMap", AtomicString::ConstructFromLiteral));
1120 LocalFrame* frame = mainFrame();
1123 Resource* resource = cachedResource(frame, KURL(ParsedURLString, url));
1126 const AtomicString& deprecatedHeaderSourceMapURL = resource->response().httpHeaderField(deprecatedSourceMapHttpHeader);
1127 if (!deprecatedHeaderSourceMapURL.isEmpty()) {
1128 // FIXME: add deprecated console message here.
1129 return deprecatedHeaderSourceMapURL;
1131 return resource->response().httpHeaderField(sourceMapHttpHeader);
1134 bool InspectorPageAgent::deviceMetricsOverrideEnabled()
1136 return m_enabled && m_deviceMetricsOverridden;
1139 bool InspectorPageAgent::screencastEnabled()
1141 return m_enabled && m_state->getBoolean(PageAgentState::screencastEnabled);
1145 DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, LocalFrame* frame)
1147 DocumentLoader* documentLoader = frame->loader().documentLoader();
1148 if (!documentLoader)
1149 *errorString = "No documentLoader for given frame found";
1150 return documentLoader;
1153 void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
1155 HashMap<DocumentLoader*, String>::iterator iterator = m_loaderToIdentifier.find(loader);
1156 if (iterator != m_loaderToIdentifier.end())
1157 m_loaderToIdentifier.remove(iterator);
1160 void InspectorPageAgent::frameStartedLoading(LocalFrame* frame)
1162 m_frontend->frameStartedLoading(frameId(frame));
1165 void InspectorPageAgent::frameStoppedLoading(LocalFrame* frame)
1167 m_frontend->frameStoppedLoading(frameId(frame));
1170 void InspectorPageAgent::frameScheduledNavigation(LocalFrame* frame, double delay)
1172 m_frontend->frameScheduledNavigation(frameId(frame), delay);
1175 void InspectorPageAgent::frameClearedScheduledNavigation(LocalFrame* frame)
1177 m_frontend->frameClearedScheduledNavigation(frameId(frame));
1180 void InspectorPageAgent::willRunJavaScriptDialog(const String& message)
1182 m_frontend->javascriptDialogOpening(message);
1185 void InspectorPageAgent::didRunJavaScriptDialog()
1187 m_frontend->javascriptDialogClosed();
1190 void InspectorPageAgent::didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext* context, const LayoutRect& rect)
1192 if (!m_enabled || m_client->overridesShowPaintRects() || !m_state->getBoolean(PageAgentState::pageAgentShowPaintRects))
1195 static int colorSelector = 0;
1196 const Color colors[] = {
1197 Color(0, 0x5F, 0, 0x3F),
1198 Color(0, 0xAF, 0, 0x3F),
1199 Color(0, 0xFF, 0, 0x3F),
1202 LayoutRect inflatedRect(rect);
1203 inflatedRect.inflate(-1);
1204 m_overlay->drawOutline(context, inflatedRect, colors[colorSelector++ % WTF_ARRAY_LENGTH(colors)]);
1207 void InspectorPageAgent::didLayout(RenderObject*)
1211 m_overlay->update();
1215 void InspectorPageAgent::didScroll()
1218 m_overlay->update();
1222 void InspectorPageAgent::viewportChanged()
1224 if (!m_enabled || !m_deviceMetricsOverridden)
1226 IntSize contentsSize = m_page->deprecatedLocalMainFrame()->view()->contentsSize();
1227 IntRect viewRect = m_page->deprecatedLocalMainFrame()->view()->visibleContentRect();
1228 RefPtr<TypeBuilder::Page::Viewport> viewport = TypeBuilder::Page::Viewport::create()
1229 .setScrollX(viewRect.x())
1230 .setScrollY(viewRect.y())
1231 .setContentsWidth(contentsSize.width())
1232 .setContentsHeight(contentsSize.height())
1233 .setPageScaleFactor(m_page->pageScaleFactor())
1234 .setMinimumPageScaleFactor(m_client->minimumPageScaleFactor())
1235 .setMaximumPageScaleFactor(m_client->maximumPageScaleFactor());
1236 m_frontend->viewportChanged(viewport);
1239 void InspectorPageAgent::didResizeMainFrame()
1242 if (m_enabled && m_state->getBoolean(PageAgentState::showSizeOnResize))
1243 m_overlay->showAndHideViewSize(m_state->getBoolean(PageAgentState::showGridOnResize));
1245 m_frontend->frameResized();
1249 void InspectorPageAgent::didRecalculateStyle(int)
1252 m_overlay->update();
1255 void InspectorPageAgent::deviceOrPageScaleFactorChanged()
1258 m_overlay->update();
1262 void InspectorPageAgent::scriptsEnabled(bool isEnabled)
1264 if (m_ignoreScriptsEnabledNotification)
1267 m_frontend->scriptsEnabled(isEnabled);
1270 PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(LocalFrame* frame)
1272 RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
1273 .setId(frameId(frame))
1274 .setLoaderId(loaderId(frame->loader().documentLoader()))
1275 .setUrl(urlWithoutFragment(frame->document()->url()).string())
1276 .setMimeType(frame->loader().documentLoader()->responseMIMEType())
1277 .setSecurityOrigin(frame->document()->securityOrigin()->toRawString());
1278 // FIXME: This doesn't work for OOPI.
1279 Frame* parentFrame = frame->tree().parent();
1280 if (parentFrame && parentFrame->isLocalFrame())
1281 frameObject->setParentId(frameId(toLocalFrame(parentFrame)));
1282 if (frame->deprecatedLocalOwner()) {
1283 AtomicString name = frame->deprecatedLocalOwner()->getNameAttribute();
1285 name = frame->deprecatedLocalOwner()->getAttribute(HTMLNames::idAttr);
1286 frameObject->setName(name);
1292 PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(LocalFrame* frame)
1294 RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
1295 RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
1296 RefPtr<TypeBuilder::Page::FrameResourceTree> result = TypeBuilder::Page::FrameResourceTree::create()
1297 .setFrame(frameObject)
1298 .setResources(subresources);
1300 Vector<Resource*> allResources = cachedResourcesForFrame(frame, true);
1301 for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) {
1302 Resource* cachedResource = *it;
1304 RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
1305 .setUrl(urlWithoutFragment(cachedResource->url()).string())
1306 .setType(cachedResourceTypeJson(*cachedResource))
1307 .setMimeType(cachedResource->response().mimeType());
1308 if (cachedResource->wasCanceled())
1309 resourceObject->setCanceled(true);
1310 else if (cachedResource->status() == Resource::LoadError)
1311 resourceObject->setFailed(true);
1312 subresources->addItem(resourceObject);
1315 Vector<Document*> allImports = InspectorPageAgent::importsForFrame(frame);
1316 for (Vector<Document*>::const_iterator it = allImports.begin(); it != allImports.end(); ++it) {
1317 Document* import = *it;
1318 RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
1319 .setUrl(urlWithoutFragment(import->url()).string())
1320 .setType(resourceTypeJson(InspectorPageAgent::DocumentResource))
1321 .setMimeType(import->suggestedMIMEType());
1322 subresources->addItem(resourceObject);
1325 RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
1326 for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1327 if (!child->isLocalFrame())
1329 if (!childrenArray) {
1330 childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
1331 result->setChildFrames(childrenArray);
1333 childrenArray->addItem(buildObjectForFrameTree(toLocalFrame(child)));
1338 void InspectorPageAgent::updateViewMetricsFromState()
1340 bool enabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
1341 int width = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
1342 int height = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
1343 bool mobile = m_state->getBoolean(PageAgentState::pageAgentEmulateMobile);
1344 double deviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride);
1345 bool fitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
1346 double scale = m_state->getDouble(PageAgentState::deviceScale, 1);
1347 double offsetX = m_state->getDouble(PageAgentState::deviceOffsetX, 0);
1348 double offsetY = m_state->getDouble(PageAgentState::deviceOffsetY, 0);
1349 updateViewMetrics(enabled, width, height, deviceScaleFactor, mobile, fitWindow, scale, offsetX, offsetY);
1352 void InspectorPageAgent::updateViewMetrics(bool enabled, int width, int height, double deviceScaleFactor, bool mobile, bool fitWindow, double scale, double offsetX, double offsetY)
1354 if (enabled && !m_page->settings().acceleratedCompositingEnabled())
1357 m_deviceMetricsOverridden = enabled;
1358 m_emulateMobileEnabled = mobile;
1360 m_client->setDeviceMetricsOverride(width, height, static_cast<float>(deviceScaleFactor), mobile, fitWindow, static_cast<float>(scale), static_cast<float>(offsetX), static_cast<float>(offsetY));
1362 m_client->clearDeviceMetricsOverride();
1364 Document* document = mainFrame()->document();
1366 document->styleResolverChanged();
1367 document->mediaQueryAffectingValueChanged();
1369 InspectorInstrumentation::mediaQueryResultChanged(document);
1371 if (m_deviceMetricsOverridden) {
1372 m_page->settings().setTextAutosizingEnabled(mobile);
1373 m_page->settings().setPreferCompositingToLCDTextEnabled(mobile);
1374 m_page->settings().setDeviceScaleAdjustment(calculateFontScaleFactor(width, height, static_cast<float>(deviceScaleFactor)));
1376 m_page->settings().setTextAutosizingEnabled(m_embedderTextAutosizingEnabled);
1377 m_page->settings().setPreferCompositingToLCDTextEnabled(m_embedderPreferCompositingToLCDTextEnabled);
1378 m_page->settings().setDeviceScaleAdjustment(m_embedderFontScaleFactor);
1381 // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
1382 m_client->setShowFPSCounter(m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter) && !m_deviceMetricsOverridden);
1383 m_client->setContinuousPaintingEnabled(m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled) && !m_deviceMetricsOverridden);
1386 void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled)
1388 if (!m_touchEmulationEnabled) {
1389 m_originalTouchEnabled = RuntimeEnabledFeatures::touchEnabled();
1390 m_originalDeviceSupportsMouse = m_page->settings().deviceSupportsMouse();
1391 m_originalDeviceSupportsTouch = m_page->settings().deviceSupportsTouch();
1392 m_originalMaxTouchPoints = m_page->settings().maxTouchPoints();
1394 RuntimeEnabledFeatures::setTouchEnabled(enabled ? true : m_originalTouchEnabled);
1395 if (!m_originalDeviceSupportsTouch) {
1396 m_page->settings().setDeviceSupportsMouse(enabled ? false : m_originalDeviceSupportsMouse);
1397 m_page->settings().setDeviceSupportsTouch(enabled ? true : m_originalDeviceSupportsTouch);
1398 // Currently emulation does not provide multiple touch points.
1399 m_page->settings().setMaxTouchPoints(enabled ? 1 : m_originalMaxTouchPoints);
1401 m_touchEmulationEnabled = enabled;
1402 m_client->setTouchEventEmulationEnabled(enabled);
1403 m_page->deprecatedLocalMainFrame()->view()->layout();
1406 void InspectorPageAgent::setTouchEmulationEnabled(ErrorString*, bool enabled)
1408 if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
1411 m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
1412 updateTouchEventEmulationInPage(enabled);
1415 void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media)
1417 String currentMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
1418 if (media == currentMedia)
1421 m_state->setString(PageAgentState::pageAgentEmulatedMedia, media);
1422 Document* document = 0;
1423 if (m_page->mainFrame())
1424 document = m_page->deprecatedLocalMainFrame()->document();
1426 document->mediaQueryAffectingValueChanged();
1427 document->styleResolverChanged();
1428 document->updateLayout();
1432 bool InspectorPageAgent::applyViewportStyleOverride(StyleResolver* resolver)
1434 if (!m_deviceMetricsOverridden || !m_emulateMobileEnabled)
1437 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
1438 styleSheet->parseString(String(viewportAndroidCss, sizeof(viewportAndroidCss)));
1439 OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
1440 ruleSet->addRulesFromSheet(styleSheet.get(), MediaQueryEvaluator("screen"));
1441 resolver->viewportStyleResolver()->collectViewportRules(ruleSet.get(), ViewportStyleResolver::UserAgentOrigin);
1445 void InspectorPageAgent::applyEmulatedMedia(String* media)
1447 String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
1448 if (!emulatedMedia.isEmpty())
1449 *media = emulatedMedia;
1452 bool InspectorPageAgent::compositingEnabled(ErrorString* errorString)
1454 if (!m_page->settings().acceleratedCompositingEnabled()) {
1456 *errorString = "Compositing mode is not supported";
1462 void InspectorPageAgent::startScreencast(ErrorString*, const String* format, const int* quality, const int* maxWidth, const int* maxHeight)
1464 m_state->setBoolean(PageAgentState::screencastEnabled, true);
1467 void InspectorPageAgent::stopScreencast(ErrorString*)
1469 m_state->setBoolean(PageAgentState::screencastEnabled, false);
1472 void InspectorPageAgent::setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid)
1474 m_state->setBoolean(PageAgentState::showSizeOnResize, show);
1475 m_state->setBoolean(PageAgentState::showGridOnResize, asBool(showGrid));
1478 void InspectorPageAgent::clearEditedResourcesContent()
1480 m_editedResourceContent.clear();
1483 void InspectorPageAgent::addEditedResourceContent(const String& url, const String& content)
1485 m_editedResourceContent.set(url, content);
1488 bool InspectorPageAgent::getEditedResourceContent(const String& url, String* content)
1490 if (!m_editedResourceContent.contains(url))
1492 *content = m_editedResourceContent.get(url);
1496 void InspectorPageAgent::trace(Visitor* visitor)
1498 visitor->trace(m_page);
1499 visitor->trace(m_injectedScriptManager);
1500 visitor->trace(m_inspectorResourceContentLoader);
1501 InspectorBaseAgent::trace(visitor);
1504 } // namespace blink