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/v8/DOMWrapperWorld.h"
35 #include "bindings/v8/ScriptController.h"
36 #include "bindings/v8/ScriptRegexp.h"
37 #include "core/HTMLNames.h"
38 #include "core/UserAgentStyleSheets.h"
39 #include "core/css/StyleSheetContents.h"
40 #include "core/css/resolver/ViewportStyleResolver.h"
41 #include "core/dom/DOMImplementation.h"
42 #include "core/dom/Document.h"
43 #include "core/fetch/CSSStyleSheetResource.h"
44 #include "core/fetch/FontResource.h"
45 #include "core/fetch/ImageResource.h"
46 #include "core/fetch/MemoryCache.h"
47 #include "core/fetch/Resource.h"
48 #include "core/fetch/ResourceFetcher.h"
49 #include "core/fetch/ScriptResource.h"
50 #include "core/frame/FrameView.h"
51 #include "core/frame/LocalFrame.h"
52 #include "core/frame/Settings.h"
53 #include "core/html/HTMLFrameOwnerElement.h"
54 #include "core/html/imports/HTMLImport.h"
55 #include "core/html/imports/HTMLImportLoader.h"
56 #include "core/html/imports/HTMLImportsController.h"
57 #include "core/html/parser/TextResourceDecoder.h"
58 #include "core/inspector/ContentSearchUtils.h"
59 #include "core/inspector/DOMPatchSupport.h"
60 #include "core/inspector/IdentifiersFactory.h"
61 #include "core/inspector/InjectedScriptManager.h"
62 #include "core/inspector/InspectorClient.h"
63 #include "core/inspector/InspectorInstrumentation.h"
64 #include "core/inspector/InspectorOverlay.h"
65 #include "core/inspector/InspectorResourceContentLoader.h"
66 #include "core/inspector/InspectorState.h"
67 #include "core/inspector/InstrumentingAgents.h"
68 #include "core/loader/CookieJar.h"
69 #include "core/loader/DocumentLoader.h"
70 #include "core/loader/FrameLoadRequest.h"
71 #include "core/loader/FrameLoader.h"
72 #include "core/page/Page.h"
73 #include "platform/Cookie.h"
74 #include "platform/JSONValues.h"
75 #include "platform/UserGestureIndicator.h"
76 #include "platform/weborigin/SecurityOrigin.h"
77 #include "wtf/CurrentTime.h"
78 #include "wtf/ListHashSet.h"
79 #include "wtf/Vector.h"
80 #include "wtf/text/Base64.h"
81 #include "wtf/text/TextEncoding.h"
85 namespace PageAgentState {
86 static const char pageAgentEnabled[] = "pageAgentEnabled";
87 static const char pageAgentScriptExecutionDisabled[] = "pageAgentScriptExecutionDisabled";
88 static const char pageAgentScriptsToEvaluateOnLoad[] = "pageAgentScriptsToEvaluateOnLoad";
89 static const char deviceMetricsOverrideEnabled[] = "deviceMetricsOverrideEnabled";
90 static const char pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
91 static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
92 static const char pageAgentDeviceScaleFactorOverride[] = "pageAgentDeviceScaleFactorOverride";
93 static const char pageAgentEmulateViewport[] = "pageAgentEmulateViewport";
94 static const char pageAgentFitWindow[] = "pageAgentFitWindow";
95 static const char fontScaleFactor[] = "fontScaleFactor";
96 static const char pageAgentShowFPSCounter[] = "pageAgentShowFPSCounter";
97 static const char pageAgentTextAutosizingOverride[] = "pageAgentTextAutosizingOverride";
98 static const char pageAgentContinuousPaintingEnabled[] = "pageAgentContinuousPaintingEnabled";
99 static const char pageAgentShowPaintRects[] = "pageAgentShowPaintRects";
100 static const char pageAgentShowDebugBorders[] = "pageAgentShowDebugBorders";
101 static const char pageAgentShowScrollBottleneckRects[] = "pageAgentShowScrollBottleneckRects";
102 static const char touchEventEmulationEnabled[] = "touchEventEmulationEnabled";
103 static const char pageAgentEmulatedMedia[] = "pageAgentEmulatedMedia";
104 static const char showSizeOnResize[] = "showSizeOnResize";
105 static const char showGridOnResize[] = "showGridOnResize";
110 KURL urlWithoutFragment(const KURL& url)
113 result.removeFragmentIdentifier();
119 static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
122 WTF::TextEncoding encoding(textEncodingName);
123 if (!encoding.isValid())
124 encoding = WindowsLatin1Encoding();
125 *result = encoding.decode(buffer, size);
131 static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize)
133 *hasZeroSize = false;
137 if (cachedResource->dataBufferingPolicy() == DoNotBufferData)
140 // Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0.
141 if (!cachedResource->encodedSize()) {
146 if (cachedResource->isPurgeable()) {
147 // If the resource is purgeable then make it unpurgeable to get
148 // get its data. This might fail, in which case we return an
150 // FIXME: should we do something else in the case of a purged
151 // resource that informs the user why there is no data in the
153 if (!cachedResource->lock())
160 static bool hasTextContent(Resource* cachedResource)
162 InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource);
163 return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource;
166 static PassOwnPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName)
168 if (!textEncodingName.isEmpty())
169 return TextResourceDecoder::create("text/plain", textEncodingName);
170 if (DOMImplementation::isXMLMIMEType(mimeType)) {
171 OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
172 decoder->useLenientXMLDecoding();
173 return decoder.release();
175 if (equalIgnoringCase(mimeType, "text/html"))
176 return TextResourceDecoder::create("text/html", "UTF-8");
177 return TextResourceDecoder::create("text/plain", "UTF-8");
180 bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded)
183 bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize);
187 *base64Encoded = !hasTextContent(cachedResource);
188 if (*base64Encoded) {
189 RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer();
194 *result = base64Encode(buffer->data(), buffer->size());
203 if (cachedResource) {
204 switch (cachedResource->type()) {
205 case Resource::CSSStyleSheet:
206 *result = toCSSStyleSheetResource(cachedResource)->sheetText(false);
208 case Resource::Script:
209 *result = toScriptResource(cachedResource)->script();
211 case Resource::MainResource:
213 case Resource::Raw: {
214 SharedBuffer* buffer = cachedResource->resourceBuffer();
217 OwnPtr<TextResourceDecoder> decoder = createXHRTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName());
218 String content = decoder->decode(buffer->data(), buffer->size());
219 *result = content + decoder->flush();
223 SharedBuffer* buffer = cachedResource->resourceBuffer();
224 return decodeBuffer(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, cachedResource->response().textEncodingName(), result);
231 bool InspectorPageAgent::sharedBufferContent(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, bool withBase64Encode, String* result)
233 return dataContent(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, textEncodingName, withBase64Encode, result);
236 bool InspectorPageAgent::dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result)
238 if (withBase64Encode) {
239 *result = base64Encode(data, size);
243 return decodeBuffer(data, size, textEncodingName, result);
246 PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
248 return adoptPtr(new InspectorPageAgent(page, injectedScriptManager, client, overlay));
252 void InspectorPageAgent::resourceContent(ErrorString* errorString, LocalFrame* frame, const KURL& url, String* result, bool* base64Encoded)
254 DocumentLoader* loader = assertDocumentLoader(errorString, frame);
257 if (!cachedResourceContent(cachedResource(frame, url), result, base64Encoded))
258 *errorString = "No resource with given URL found";
261 Resource* InspectorPageAgent::cachedResource(LocalFrame* frame, const KURL& url)
263 Resource* cachedResource = frame->document()->fetcher()->cachedResource(url);
265 cachedResource = memoryCache()->resourceForURL(url);
266 return cachedResource;
269 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType)
271 switch (resourceType) {
272 case DocumentResource:
273 return TypeBuilder::Page::ResourceType::Document;
275 return TypeBuilder::Page::ResourceType::Font;
277 return TypeBuilder::Page::ResourceType::Image;
279 return TypeBuilder::Page::ResourceType::Media;
281 return TypeBuilder::Page::ResourceType::Script;
282 case StylesheetResource:
283 return TypeBuilder::Page::ResourceType::Stylesheet;
284 case TextTrackResource:
285 return TypeBuilder::Page::ResourceType::TextTrack;
287 return TypeBuilder::Page::ResourceType::XHR;
288 case WebSocketResource:
289 return TypeBuilder::Page::ResourceType::WebSocket;
291 return TypeBuilder::Page::ResourceType::Other;
293 return TypeBuilder::Page::ResourceType::Other;
296 InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Resource& cachedResource)
298 switch (cachedResource.type()) {
299 case Resource::Image:
300 return InspectorPageAgent::ImageResource;
302 return InspectorPageAgent::FontResource;
303 case Resource::Media:
304 return InspectorPageAgent::MediaResource;
305 case Resource::TextTrack:
306 return InspectorPageAgent::TextTrackResource;
307 case Resource::CSSStyleSheet:
309 case Resource::XSLStyleSheet:
310 return InspectorPageAgent::StylesheetResource;
311 case Resource::Script:
312 return InspectorPageAgent::ScriptResource;
314 return InspectorPageAgent::XHRResource;
315 case Resource::ImportResource:
317 case Resource::MainResource:
318 return InspectorPageAgent::DocumentResource;
322 return InspectorPageAgent::OtherResource;
325 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson(const Resource& cachedResource)
327 return resourceTypeJson(cachedResourceType(cachedResource));
330 InspectorPageAgent::InspectorPageAgent(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
331 : InspectorBaseAgent<InspectorPageAgent>("Page")
333 , m_injectedScriptManager(injectedScriptManager)
337 , m_lastScriptIdentifier(0)
339 , m_ignoreScriptsEnabledNotification(false)
340 , m_deviceMetricsOverridden(false)
341 , m_emulateViewportEnabled(false)
342 , m_touchEmulationEnabled(false)
343 , m_originalTouchEnabled(false)
344 , m_originalDeviceSupportsMouse(false)
345 , m_originalDeviceSupportsTouch(false)
346 , m_embedderTextAutosizingEnabled(m_page->settings().textAutosizingEnabled())
347 , m_embedderFontScaleFactor(m_page->settings().deviceScaleAdjustment())
351 void InspectorPageAgent::setTextAutosizingEnabled(bool enabled)
353 m_embedderTextAutosizingEnabled = enabled;
354 if (!m_deviceMetricsOverridden)
355 m_page->settings().setTextAutosizingEnabled(enabled);
358 void InspectorPageAgent::setDeviceScaleAdjustment(float deviceScaleAdjustment)
360 m_embedderFontScaleFactor = deviceScaleAdjustment;
361 if (!m_deviceMetricsOverridden)
362 m_page->settings().setDeviceScaleAdjustment(deviceScaleAdjustment);
365 void InspectorPageAgent::setFrontend(InspectorFrontend* frontend)
367 m_frontend = frontend->page();
370 void InspectorPageAgent::clearFrontend()
377 void InspectorPageAgent::restore()
379 if (m_state->getBoolean(PageAgentState::pageAgentEnabled)) {
382 bool scriptExecutionDisabled = m_state->getBoolean(PageAgentState::pageAgentScriptExecutionDisabled);
383 setScriptExecutionDisabled(0, scriptExecutionDisabled);
384 bool showPaintRects = m_state->getBoolean(PageAgentState::pageAgentShowPaintRects);
385 setShowPaintRects(0, showPaintRects);
386 bool showDebugBorders = m_state->getBoolean(PageAgentState::pageAgentShowDebugBorders);
387 setShowDebugBorders(0, showDebugBorders);
388 bool showFPSCounter = m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter);
389 setShowFPSCounter(0, showFPSCounter);
390 String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
391 setEmulatedMedia(0, emulatedMedia);
392 bool continuousPaintingEnabled = m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled);
393 setContinuousPaintingEnabled(0, continuousPaintingEnabled);
394 bool showScrollBottleneckRects = m_state->getBoolean(PageAgentState::pageAgentShowScrollBottleneckRects);
395 setShowScrollBottleneckRects(0, showScrollBottleneckRects);
397 updateViewMetricsFromState();
398 updateTouchEventEmulationInPage(m_state->getBoolean(PageAgentState::touchEventEmulationEnabled));
402 void InspectorPageAgent::enable(ErrorString*)
405 m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
406 m_instrumentingAgents->setInspectorPageAgent(this);
407 m_inspectorResourceContentLoader = adoptPtr(new InspectorResourceContentLoader(m_page));
410 void InspectorPageAgent::disable(ErrorString*)
413 m_state->setBoolean(PageAgentState::pageAgentEnabled, false);
414 m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
416 m_instrumentingAgents->setInspectorPageAgent(0);
417 m_inspectorResourceContentLoader.clear();
418 m_deviceMetricsOverridden = false;
420 setShowPaintRects(0, false);
421 setShowDebugBorders(0, false);
422 setShowFPSCounter(0, false);
423 setEmulatedMedia(0, String());
424 if (m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled))
425 setContinuousPaintingEnabled(0, false);
426 setShowScrollBottleneckRects(0, false);
427 setShowViewportSizeOnResize(0, false, 0);
429 if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled)) {
430 updateTouchEventEmulationInPage(false);
431 m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, false);
434 if (!deviceMetricsChanged(false, 0, 0, 0, false, false, 1, false))
437 // When disabling the agent, reset the override values if necessary.
438 updateViewMetrics(false, 0, 0, 0, false, false, m_embedderFontScaleFactor, m_embedderTextAutosizingEnabled);
439 m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
440 m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
441 m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
442 m_state->setBoolean(PageAgentState::pageAgentEmulateViewport, false);
443 m_state->setBoolean(PageAgentState::pageAgentFitWindow, false);
444 m_state->setDouble(PageAgentState::fontScaleFactor, 1);
445 m_state->setBoolean(PageAgentState::pageAgentTextAutosizingOverride, false);
448 void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier)
450 RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
452 scripts = JSONObject::create();
453 m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
455 // Assure we don't override existing ids -- m_lastScriptIdentifier could get out of sync WRT actual
456 // scripts once we restored the scripts from the cookie during navigation.
458 *identifier = String::number(++m_lastScriptIdentifier);
459 } while (scripts->find(*identifier) != scripts->end());
460 scripts->setString(*identifier, source);
462 // Force cookie serialization.
463 m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
466 void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const String& identifier)
468 RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
469 if (!scripts || scripts->find(identifier) == scripts->end()) {
470 *error = "Script not found";
473 scripts->remove(identifier);
476 void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor)
478 m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
479 m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
480 m_page->deprecatedLocalMainFrame()->loader().reload(optionalIgnoreCache && *optionalIgnoreCache ? EndToEndReload : NormalReload);
483 void InspectorPageAgent::navigate(ErrorString*, const String& url)
485 UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
486 LocalFrame* frame = m_page->deprecatedLocalMainFrame();
487 FrameLoadRequest request(frame->document(), ResourceRequest(frame->document()->completeURL(url)));
488 frame->loader().load(request);
491 static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
493 return TypeBuilder::Page::Cookie::create()
494 .setName(cookie.name)
495 .setValue(cookie.value)
496 .setDomain(cookie.domain)
497 .setPath(cookie.path)
498 .setExpires(cookie.expires)
499 .setSize((cookie.name.length() + cookie.value.length()))
500 .setHttpOnly(cookie.httpOnly)
501 .setSecure(cookie.secure)
502 .setSession(cookie.session)
506 static PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > buildArrayForCookies(ListHashSet<Cookie>& cookiesList)
508 RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > cookies = TypeBuilder::Array<TypeBuilder::Page::Cookie>::create();
510 ListHashSet<Cookie>::iterator end = cookiesList.end();
511 ListHashSet<Cookie>::iterator it = cookiesList.begin();
512 for (int i = 0; it != end; ++it, i++)
513 cookies->addItem(buildObjectForCookie(*it));
518 static void cachedResourcesForDocument(Document* document, Vector<Resource*>& result)
520 const ResourceFetcher::DocumentResourceMap& allResources = document->fetcher()->allResources();
521 ResourceFetcher::DocumentResourceMap::const_iterator end = allResources.end();
522 for (ResourceFetcher::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
523 Resource* cachedResource = it->value.get();
525 switch (cachedResource->type()) {
526 case Resource::Image:
527 // Skip images that were not auto loaded (images disabled in the user agent).
528 if (toImageResource(cachedResource)->stillNeedsLoad())
532 // Skip fonts that were referenced in CSS but never used/downloaded.
533 if (toFontResource(cachedResource)->stillNeedsLoad())
537 // All other Resource types download immediately.
541 result.append(cachedResource);
546 Vector<Document*> InspectorPageAgent::importsForFrame(LocalFrame* frame)
548 Vector<Document*> result;
549 Document* rootDocument = frame->document();
551 if (HTMLImportsController* controller = rootDocument->importsController()) {
552 for (size_t i = 0; i < controller->loaderCount(); ++i) {
553 if (Document* document = controller->loaderAt(i)->document())
554 result.append(document);
561 static Vector<Resource*> cachedResourcesForFrame(LocalFrame* frame)
563 Vector<Resource*> result;
564 Document* rootDocument = frame->document();
565 Vector<Document*> loaders = InspectorPageAgent::importsForFrame(frame);
567 cachedResourcesForDocument(rootDocument, result);
568 for (size_t i = 0; i < loaders.size(); ++i)
569 cachedResourcesForDocument(loaders[i], result);
574 static Vector<KURL> allResourcesURLsForFrame(LocalFrame* frame)
578 result.append(urlWithoutFragment(frame->loader().documentLoader()->url()));
580 Vector<Resource*> allResources = cachedResourcesForFrame(frame);
581 for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it)
582 result.append(urlWithoutFragment((*it)->url()));
587 void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies)
589 ListHashSet<Cookie> rawCookiesList;
591 for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
592 if (!frame->isLocalFrame())
594 Document* document = toLocalFrame(frame)->document();
595 Vector<KURL> allURLs = allResourcesURLsForFrame(toLocalFrame(frame));
596 for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
597 Vector<Cookie> docCookiesList;
598 getRawCookies(document, *it, docCookiesList);
599 int cookiesSize = docCookiesList.size();
600 for (int i = 0; i < cookiesSize; i++) {
601 if (!rawCookiesList.contains(docCookiesList[i]))
602 rawCookiesList.add(docCookiesList[i]);
607 cookies = buildArrayForCookies(rawCookiesList);
610 void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
612 KURL parsedURL(ParsedURLString, url);
613 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame())) {
614 if (frame->isLocalFrame())
615 WebCore::deleteCookie(toLocalFrame(frame)->document(), parsedURL, cookieName);
619 void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>& object)
621 object = buildObjectForFrameTree(m_page->deprecatedLocalMainFrame());
624 void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded)
626 LocalFrame* frame = assertFrame(errorString, frameId);
629 resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded);
632 static bool textContentForResource(Resource* cachedResource, String* result)
634 if (hasTextContent(cachedResource)) {
637 if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {
638 ASSERT(!base64Encoded);
645 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)
647 results = TypeBuilder::Array<TypeBuilder::Page::SearchMatch>::create();
649 bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
650 bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
652 LocalFrame* frame = frameForId(frameId);
653 KURL kurl(ParsedURLString, url);
655 FrameLoader* frameLoader = frame ? &frame->loader() : 0;
656 DocumentLoader* loader = frameLoader ? frameLoader->documentLoader() : 0;
661 bool success = false;
662 Resource* resource = cachedResource(frame, kurl);
664 success = textContentForResource(resource, &content);
669 results = ContentSearchUtils::searchInTextByLines(content, query, caseSensitive, isRegex);
672 void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
674 LocalFrame* frame = assertFrame(errorString, frameId);
678 Document* document = frame->document();
680 *errorString = "No Document instance to set HTML for";
683 DOMPatchSupport::patchDocument(*document, html);
686 void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, const bool* optionalTextAutosizing, const double* optionalFontScaleFactor)
688 const static long maxDimension = 10000000;
690 bool textAutosizing = optionalTextAutosizing ? *optionalTextAutosizing : false;
691 double fontScaleFactor = optionalFontScaleFactor ? *optionalFontScaleFactor : 1;
693 if (width < 0 || height < 0 || width > maxDimension || height > maxDimension) {
694 *errorString = "Width and height values must be positive, not greater than " + String::number(maxDimension);
698 if (deviceScaleFactor < 0) {
699 *errorString = "deviceScaleFactor must be non-negative";
703 if (fontScaleFactor <= 0) {
704 *errorString = "fontScaleFactor must be positive";
708 Settings& settings = m_page->settings();
709 if (!settings.acceleratedCompositingEnabled()) {
711 *errorString = "Compositing mode is not supported";
715 if (!deviceMetricsChanged(true, width, height, deviceScaleFactor, emulateViewport, fitWindow, fontScaleFactor, textAutosizing))
718 m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, true);
719 m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
720 m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
721 m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, deviceScaleFactor);
722 m_state->setBoolean(PageAgentState::pageAgentEmulateViewport, emulateViewport);
723 m_state->setBoolean(PageAgentState::pageAgentFitWindow, fitWindow);
724 m_state->setDouble(PageAgentState::fontScaleFactor, fontScaleFactor);
725 m_state->setBoolean(PageAgentState::pageAgentTextAutosizingOverride, textAutosizing);
726 updateViewMetricsFromState();
729 void InspectorPageAgent::clearDeviceMetricsOverride(ErrorString*)
731 if (m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled)) {
732 m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, false);
733 updateViewMetricsFromState();
737 bool InspectorPageAgent::deviceMetricsChanged(bool enabled, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing)
739 bool currentEnabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
740 // These two always fit an int.
741 int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
742 int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
743 double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
744 bool currentEmulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
745 bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
746 double currentFontScaleFactor = m_state->getDouble(PageAgentState::fontScaleFactor, 1);
747 bool currentTextAutosizing = m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
749 return enabled != currentEnabled
750 || width != currentWidth
751 || height != currentHeight
752 || deviceScaleFactor != currentDeviceScaleFactor
753 || emulateViewport != currentEmulateViewport
754 || fitWindow != currentFitWindow
755 || fontScaleFactor != currentFontScaleFactor
756 || textAutosizing != currentTextAutosizing;
759 void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
761 m_state->setBoolean(PageAgentState::pageAgentShowPaintRects, show);
762 m_client->setShowPaintRects(show);
764 if (!show && mainFrame() && mainFrame()->view())
765 mainFrame()->view()->invalidate();
768 void InspectorPageAgent::setShowDebugBorders(ErrorString* errorString, bool show)
770 m_state->setBoolean(PageAgentState::pageAgentShowDebugBorders, show);
771 if (show && !compositingEnabled(errorString))
773 m_client->setShowDebugBorders(show);
776 void InspectorPageAgent::setShowFPSCounter(ErrorString* errorString, bool show)
778 // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
779 m_state->setBoolean(PageAgentState::pageAgentShowFPSCounter, show);
780 if (show && !compositingEnabled(errorString))
782 m_client->setShowFPSCounter(show && !m_deviceMetricsOverridden);
785 void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString* errorString, bool enabled)
787 m_state->setBoolean(PageAgentState::pageAgentContinuousPaintingEnabled, enabled);
788 if (enabled && !compositingEnabled(errorString))
790 m_client->setContinuousPaintingEnabled(enabled && !m_deviceMetricsOverridden);
793 void InspectorPageAgent::setShowScrollBottleneckRects(ErrorString* errorString, bool show)
795 m_state->setBoolean(PageAgentState::pageAgentShowScrollBottleneckRects, show);
796 if (show && !compositingEnabled(errorString))
798 m_client->setShowScrollBottleneckRects(show);
801 void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum* status)
803 bool disabledByScriptController = false;
804 bool disabledInSettings = false;
805 LocalFrame* frame = mainFrame();
807 disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript);
808 if (frame->settings())
809 disabledInSettings = !frame->settings()->scriptEnabled();
812 // Order is important.
813 if (disabledInSettings)
814 *status = PageCommandHandler::Result::Disabled;
815 else if (disabledByScriptController)
816 *status = PageCommandHandler::Result::Forbidden;
818 *status = PageCommandHandler::Result::Allowed;
821 void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
823 m_state->setBoolean(PageAgentState::pageAgentScriptExecutionDisabled, value);
827 Settings* settings = mainFrame()->settings();
829 m_ignoreScriptsEnabledNotification = true;
830 settings->setScriptEnabled(!value);
831 m_ignoreScriptsEnabledNotification = false;
835 void InspectorPageAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
837 if (frame == m_page->mainFrame())
838 m_injectedScriptManager->discardInjectedScripts();
843 RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
845 JSONObject::const_iterator end = scripts->end();
846 for (JSONObject::const_iterator it = scripts->begin(); it != end; ++it) {
848 if (it->value->asString(&scriptText))
849 frame->script().executeScriptInMainWorld(scriptText);
852 if (!m_scriptToEvaluateOnLoadOnce.isEmpty())
853 frame->script().executeScriptInMainWorld(m_scriptToEvaluateOnLoadOnce);
856 void InspectorPageAgent::domContentLoadedEventFired(LocalFrame* frame)
858 if (!frame->isMainFrame())
860 m_frontend->domContentEventFired(currentTime());
863 void InspectorPageAgent::loadEventFired(LocalFrame* frame)
865 if (!frame->isMainFrame())
867 m_frontend->loadEventFired(currentTime());
870 void InspectorPageAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
872 // FIXME: If "frame" is always guaranteed to be in the same Page as loader->frame()
873 // then all we need to check here is loader->frame()->isMainFrame()
874 // and we don't need "frame" at all.
875 if (loader->frame() == m_page->mainFrame()) {
876 m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce;
877 m_scriptPreprocessorSource = m_pendingScriptPreprocessor;
878 m_pendingScriptToEvaluateOnLoadOnce = String();
879 m_pendingScriptPreprocessor = String();
880 if (m_inspectorResourceContentLoader)
881 m_inspectorResourceContentLoader->stop();
883 m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
886 void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame)
888 Frame* parentFrame = frame->tree().parent();
889 if (!parentFrame->isLocalFrame())
891 m_frontend->frameAttached(frameId(frame), frameId(toLocalFrame(parentFrame)));
894 void InspectorPageAgent::frameDetachedFromParent(LocalFrame* frame)
896 HashMap<LocalFrame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
897 if (iterator != m_frameToIdentifier.end()) {
898 m_frontend->frameDetached(iterator->value);
899 m_identifierToFrame.remove(iterator->value);
900 m_frameToIdentifier.remove(iterator);
904 LocalFrame* InspectorPageAgent::mainFrame()
906 return m_page->deprecatedLocalMainFrame();
909 LocalFrame* InspectorPageAgent::frameForId(const String& frameId)
911 return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
914 String InspectorPageAgent::frameId(LocalFrame* frame)
918 String identifier = m_frameToIdentifier.get(frame);
919 if (identifier.isNull()) {
920 identifier = IdentifiersFactory::createIdentifier();
921 m_frameToIdentifier.set(frame, identifier);
922 m_identifierToFrame.set(identifier, frame);
927 bool InspectorPageAgent::hasIdForFrame(LocalFrame* frame) const
929 return frame && m_frameToIdentifier.contains(frame);
932 String InspectorPageAgent::loaderId(DocumentLoader* loader)
936 String identifier = m_loaderToIdentifier.get(loader);
937 if (identifier.isNull()) {
938 identifier = IdentifiersFactory::createIdentifier();
939 m_loaderToIdentifier.set(loader, identifier);
944 LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
946 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
947 // FIXME: RemoteFrame security origins are not yet available.
948 if (!frame->isLocalFrame())
950 RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin();
951 if (documentOrigin->toRawString() == originRawString)
952 return toLocalFrame(frame);
957 LocalFrame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
959 LocalFrame* frame = frameForId(frameId);
961 *errorString = "No frame for given id found";
965 const AtomicString& InspectorPageAgent::resourceSourceMapURL(const String& url)
967 DEFINE_STATIC_LOCAL(const AtomicString, sourceMapHttpHeader, ("SourceMap", AtomicString::ConstructFromLiteral));
968 DEFINE_STATIC_LOCAL(const AtomicString, deprecatedSourceMapHttpHeader, ("X-SourceMap", AtomicString::ConstructFromLiteral));
971 LocalFrame* frame = mainFrame();
974 Resource* resource = cachedResource(frame, KURL(ParsedURLString, url));
977 const AtomicString& deprecatedHeaderSourceMapURL = resource->response().httpHeaderField(deprecatedSourceMapHttpHeader);
978 if (!deprecatedHeaderSourceMapURL.isEmpty()) {
979 // FIXME: add deprecated console message here.
980 return deprecatedHeaderSourceMapURL;
982 return resource->response().httpHeaderField(sourceMapHttpHeader);
985 bool InspectorPageAgent::deviceMetricsOverrideEnabled()
987 return m_enabled && m_deviceMetricsOverridden;
991 DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, LocalFrame* frame)
993 DocumentLoader* documentLoader = frame->loader().documentLoader();
995 *errorString = "No documentLoader for given frame found";
996 return documentLoader;
999 void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
1001 HashMap<DocumentLoader*, String>::iterator iterator = m_loaderToIdentifier.find(loader);
1002 if (iterator != m_loaderToIdentifier.end())
1003 m_loaderToIdentifier.remove(iterator);
1006 void InspectorPageAgent::frameStartedLoading(LocalFrame* frame)
1008 m_frontend->frameStartedLoading(frameId(frame));
1011 void InspectorPageAgent::frameStoppedLoading(LocalFrame* frame)
1013 m_frontend->frameStoppedLoading(frameId(frame));
1016 void InspectorPageAgent::frameScheduledNavigation(LocalFrame* frame, double delay)
1018 m_frontend->frameScheduledNavigation(frameId(frame), delay);
1021 void InspectorPageAgent::frameClearedScheduledNavigation(LocalFrame* frame)
1023 m_frontend->frameClearedScheduledNavigation(frameId(frame));
1026 void InspectorPageAgent::willRunJavaScriptDialog(const String& message)
1028 m_frontend->javascriptDialogOpening(message);
1031 void InspectorPageAgent::didRunJavaScriptDialog()
1033 m_frontend->javascriptDialogClosed();
1036 void InspectorPageAgent::didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext* context, const LayoutRect& rect)
1038 if (!m_enabled || m_client->overridesShowPaintRects() || !m_state->getBoolean(PageAgentState::pageAgentShowPaintRects))
1041 static int colorSelector = 0;
1042 const Color colors[] = {
1043 Color(0, 0x5F, 0, 0x3F),
1044 Color(0, 0xAF, 0, 0x3F),
1045 Color(0, 0xFF, 0, 0x3F),
1048 LayoutRect inflatedRect(rect);
1049 inflatedRect.inflate(-1);
1050 m_overlay->drawOutline(context, inflatedRect, colors[colorSelector++ % WTF_ARRAY_LENGTH(colors)]);
1053 void InspectorPageAgent::didLayout(RenderObject*)
1057 m_overlay->update();
1060 void InspectorPageAgent::didScroll()
1063 m_overlay->update();
1066 void InspectorPageAgent::didResizeMainFrame()
1069 if (m_enabled && m_state->getBoolean(PageAgentState::showSizeOnResize))
1070 m_overlay->showAndHideViewSize(m_state->getBoolean(PageAgentState::showGridOnResize));
1072 m_frontend->frameResized();
1075 void InspectorPageAgent::didRecalculateStyle(int)
1078 m_overlay->update();
1081 void InspectorPageAgent::scriptsEnabled(bool isEnabled)
1083 if (m_ignoreScriptsEnabledNotification)
1086 m_frontend->scriptsEnabled(isEnabled);
1089 PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(LocalFrame* frame)
1091 RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
1092 .setId(frameId(frame))
1093 .setLoaderId(loaderId(frame->loader().documentLoader()))
1094 .setUrl(urlWithoutFragment(frame->document()->url()).string())
1095 .setMimeType(frame->loader().documentLoader()->responseMIMEType())
1096 .setSecurityOrigin(frame->document()->securityOrigin()->toRawString());
1097 // FIXME: This doesn't work for OOPI.
1098 Frame* parentFrame = frame->tree().parent();
1099 if (parentFrame && parentFrame->isLocalFrame())
1100 frameObject->setParentId(frameId(toLocalFrame(parentFrame)));
1101 if (frame->deprecatedLocalOwner()) {
1102 AtomicString name = frame->deprecatedLocalOwner()->getNameAttribute();
1104 name = frame->deprecatedLocalOwner()->getAttribute(HTMLNames::idAttr);
1105 frameObject->setName(name);
1111 PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(LocalFrame* frame)
1113 RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
1114 RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
1115 RefPtr<TypeBuilder::Page::FrameResourceTree> result = TypeBuilder::Page::FrameResourceTree::create()
1116 .setFrame(frameObject)
1117 .setResources(subresources);
1119 Vector<Resource*> allResources = cachedResourcesForFrame(frame);
1120 for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) {
1121 Resource* cachedResource = *it;
1123 RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
1124 .setUrl(urlWithoutFragment(cachedResource->url()).string())
1125 .setType(cachedResourceTypeJson(*cachedResource))
1126 .setMimeType(cachedResource->response().mimeType());
1127 if (cachedResource->wasCanceled())
1128 resourceObject->setCanceled(true);
1129 else if (cachedResource->status() == Resource::LoadError)
1130 resourceObject->setFailed(true);
1131 subresources->addItem(resourceObject);
1134 Vector<Document*> allImports = InspectorPageAgent::importsForFrame(frame);
1135 for (Vector<Document*>::const_iterator it = allImports.begin(); it != allImports.end(); ++it) {
1136 Document* import = *it;
1137 RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
1138 .setUrl(urlWithoutFragment(import->url()).string())
1139 .setType(resourceTypeJson(InspectorPageAgent::DocumentResource))
1140 .setMimeType(import->suggestedMIMEType());
1141 subresources->addItem(resourceObject);
1144 RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
1145 for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1146 if (!child->isLocalFrame())
1148 if (!childrenArray) {
1149 childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
1150 result->setChildFrames(childrenArray);
1152 childrenArray->addItem(buildObjectForFrameTree(toLocalFrame(child)));
1157 void InspectorPageAgent::updateViewMetricsFromState()
1159 bool enabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
1160 int width = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
1161 int height = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
1162 bool emulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
1163 double deviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride);
1164 bool fitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
1165 double fontScaleFactor = m_state->getDouble(PageAgentState::fontScaleFactor);
1166 bool textAutosizingEnabled = m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
1167 updateViewMetrics(enabled, width, height, deviceScaleFactor, emulateViewport, fitWindow, fontScaleFactor, textAutosizingEnabled);
1170 void InspectorPageAgent::updateViewMetrics(bool enabled, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizingEnabled)
1172 if (enabled && !m_page->settings().acceleratedCompositingEnabled())
1175 m_deviceMetricsOverridden = enabled;
1176 m_emulateViewportEnabled = emulateViewport;
1178 m_client->setDeviceMetricsOverride(width, height, static_cast<float>(deviceScaleFactor), emulateViewport, fitWindow);
1180 m_client->clearDeviceMetricsOverride();
1182 Document* document = mainFrame()->document();
1184 document->styleResolverChanged();
1185 document->mediaQueryAffectingValueChanged();
1187 InspectorInstrumentation::mediaQueryResultChanged(document);
1189 if (m_deviceMetricsOverridden) {
1190 m_page->settings().setTextAutosizingEnabled(textAutosizingEnabled);
1191 m_page->settings().setDeviceScaleAdjustment(fontScaleFactor);
1193 m_page->settings().setTextAutosizingEnabled(m_embedderTextAutosizingEnabled);
1194 m_page->settings().setDeviceScaleAdjustment(m_embedderFontScaleFactor);
1197 // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
1198 m_client->setShowFPSCounter(m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter) && !m_deviceMetricsOverridden);
1199 m_client->setContinuousPaintingEnabled(m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled) && !m_deviceMetricsOverridden);
1202 void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled)
1204 if (!m_touchEmulationEnabled) {
1205 m_originalTouchEnabled = RuntimeEnabledFeatures::touchEnabled();
1206 m_originalDeviceSupportsMouse = m_page->settings().deviceSupportsMouse();
1207 m_originalDeviceSupportsTouch = m_page->settings().deviceSupportsTouch();
1209 RuntimeEnabledFeatures::setTouchEnabled(enabled ? true : m_originalTouchEnabled);
1210 m_page->settings().setDeviceSupportsMouse(enabled ? false : m_originalDeviceSupportsMouse);
1211 m_page->settings().setDeviceSupportsTouch(enabled ? true : m_originalDeviceSupportsTouch);
1212 m_touchEmulationEnabled = enabled;
1213 m_client->setTouchEventEmulationEnabled(enabled);
1214 m_page->deprecatedLocalMainFrame()->view()->layout();
1217 void InspectorPageAgent::hasTouchInputs(ErrorString*, bool* result)
1219 *result = m_touchEmulationEnabled ? m_originalDeviceSupportsTouch : m_page->settings().deviceSupportsTouch();
1222 void InspectorPageAgent::setTouchEmulationEnabled(ErrorString* error, bool enabled)
1224 if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
1227 bool hasTouch = false;
1228 hasTouchInputs(error, &hasTouch);
1229 if (enabled && hasTouch) {
1231 *error = "Device already supports touch input";
1235 m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
1236 updateTouchEventEmulationInPage(enabled);
1239 void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media)
1241 String currentMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
1242 if (media == currentMedia)
1245 m_state->setString(PageAgentState::pageAgentEmulatedMedia, media);
1246 Document* document = 0;
1247 if (m_page->mainFrame())
1248 document = m_page->deprecatedLocalMainFrame()->document();
1250 document->mediaQueryAffectingValueChanged();
1251 document->styleResolverChanged();
1252 document->updateLayout();
1256 bool InspectorPageAgent::applyViewportStyleOverride(StyleResolver* resolver)
1258 if (!m_deviceMetricsOverridden || !m_emulateViewportEnabled)
1261 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
1262 styleSheet->parseString(String(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet)));
1263 OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
1264 ruleSet->addRulesFromSheet(styleSheet.get(), MediaQueryEvaluator("screen"));
1265 resolver->viewportStyleResolver()->collectViewportRules(ruleSet.get(), ViewportStyleResolver::UserAgentOrigin);
1269 void InspectorPageAgent::applyEmulatedMedia(String* media)
1271 String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
1272 if (!emulatedMedia.isEmpty())
1273 *media = emulatedMedia;
1276 bool InspectorPageAgent::compositingEnabled(ErrorString* errorString)
1278 if (!m_page->settings().acceleratedCompositingEnabled()) {
1280 *errorString = "Compositing mode is not supported";
1286 void InspectorPageAgent::setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid)
1288 m_state->setBoolean(PageAgentState::showSizeOnResize, show);
1289 m_state->setBoolean(PageAgentState::showGridOnResize, showGrid && *showGrid);
1292 } // namespace WebCore