Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/inspector/InspectorPageAgent.h"
     33 
     34 #include "HTMLNames.h"
     35 #include "UserAgentStyleSheets.h"
     36 #include "bindings/v8/DOMWrapperWorld.h"
     37 #include "bindings/v8/ScriptController.h"
     38 #include "bindings/v8/ScriptRegexp.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/fetch/TextResourceDecoder.h"
     51 #include "core/html/HTMLFrameOwnerElement.h"
     52 #include "core/inspector/ContentSearchUtils.h"
     53 #include "core/inspector/DOMPatchSupport.h"
     54 #include "core/inspector/IdentifiersFactory.h"
     55 #include "core/inspector/InjectedScriptManager.h"
     56 #include "core/inspector/InspectorClient.h"
     57 #include "core/inspector/InspectorInstrumentation.h"
     58 #include "core/inspector/InspectorOverlay.h"
     59 #include "core/inspector/InspectorState.h"
     60 #include "core/inspector/InstrumentingAgents.h"
     61 #include "core/loader/CookieJar.h"
     62 #include "core/loader/DocumentLoader.h"
     63 #include "core/loader/FrameLoadRequest.h"
     64 #include "core/loader/FrameLoader.h"
     65 #include "core/frame/Frame.h"
     66 #include "core/frame/FrameView.h"
     67 #include "core/page/Page.h"
     68 #include "core/page/PageConsole.h"
     69 #include "core/frame/Settings.h"
     70 #include "modules/device_orientation/DeviceOrientationController.h"
     71 #include "modules/device_orientation/DeviceOrientationData.h"
     72 #include "modules/geolocation/GeolocationController.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"
     82 
     83 namespace WebCore {
     84 
     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 pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
     90 static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
     91 static const char pageAgentDeviceScaleFactorOverride[] = "pageAgentDeviceScaleFactorOverride";
     92 static const char pageAgentEmulateViewport[] = "pageAgentEmulateViewport";
     93 static const char pageAgentFitWindow[] = "pageAgentFitWindow";
     94 static const char fontScaleFactor[] = "fontScaleFactor";
     95 static const char pageAgentShowFPSCounter[] = "pageAgentShowFPSCounter";
     96 static const char pageAgentTextAutosizingOverride[] = "pageAgentTextAutosizingOverride";
     97 static const char pageAgentContinuousPaintingEnabled[] = "pageAgentContinuousPaintingEnabled";
     98 static const char pageAgentShowPaintRects[] = "pageAgentShowPaintRects";
     99 static const char pageAgentShowDebugBorders[] = "pageAgentShowDebugBorders";
    100 static const char pageAgentShowScrollBottleneckRects[] = "pageAgentShowScrollBottleneckRects";
    101 static const char touchEventEmulationEnabled[] = "touchEventEmulationEnabled";
    102 static const char pageAgentEmulatedMedia[] = "pageAgentEmulatedMedia";
    103 static const char showSizeOnResize[] = "showSizeOnResize";
    104 static const char showGridOnResize[] = "showGridOnResize";
    105 }
    106 
    107 namespace {
    108 
    109 KURL urlWithoutFragment(const KURL& url)
    110 {
    111     KURL result = url;
    112     result.removeFragmentIdentifier();
    113     return result;
    114 }
    115 
    116 }
    117 
    118 static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
    119 {
    120     if (buffer) {
    121         WTF::TextEncoding encoding(textEncodingName);
    122         if (!encoding.isValid())
    123             encoding = WindowsLatin1Encoding();
    124         *result = encoding.decode(buffer, size);
    125         return true;
    126     }
    127     return false;
    128 }
    129 
    130 static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize)
    131 {
    132     *hasZeroSize = false;
    133     if (!cachedResource)
    134         return false;
    135 
    136     if (cachedResource->dataBufferingPolicy() == DoNotBufferData)
    137         return false;
    138 
    139     // Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0.
    140     if (!cachedResource->encodedSize()) {
    141         *hasZeroSize = true;
    142         return true;
    143     }
    144 
    145     if (cachedResource->isPurgeable()) {
    146         // If the resource is purgeable then make it unpurgeable to get
    147         // get its data. This might fail, in which case we return an
    148         // empty String.
    149         // FIXME: should we do something else in the case of a purged
    150         // resource that informs the user why there is no data in the
    151         // inspector?
    152         if (!cachedResource->makePurgeable(false))
    153             return false;
    154     }
    155 
    156     return true;
    157 }
    158 
    159 static bool hasTextContent(Resource* cachedResource)
    160 {
    161     InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource);
    162     return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource;
    163 }
    164 
    165 static PassOwnPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName)
    166 {
    167     if (!textEncodingName.isEmpty())
    168         return TextResourceDecoder::create("text/plain", textEncodingName);
    169     if (DOMImplementation::isXMLMIMEType(mimeType.lower())) {
    170         OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
    171         decoder->useLenientXMLDecoding();
    172         return decoder.release();
    173     }
    174     if (equalIgnoringCase(mimeType, "text/html"))
    175         return TextResourceDecoder::create("text/html", "UTF-8");
    176     return TextResourceDecoder::create("text/plain", "UTF-8");
    177 }
    178 
    179 bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded)
    180 {
    181     bool hasZeroSize;
    182     bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize);
    183     if (!prepared)
    184         return false;
    185 
    186     *base64Encoded = !hasTextContent(cachedResource);
    187     if (*base64Encoded) {
    188         RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer();
    189 
    190         if (!buffer)
    191             return false;
    192 
    193         *result = base64Encode(buffer->data(), buffer->size());
    194         return true;
    195     }
    196 
    197     if (hasZeroSize) {
    198         *result = "";
    199         return true;
    200     }
    201 
    202     if (cachedResource) {
    203         switch (cachedResource->type()) {
    204         case Resource::CSSStyleSheet:
    205             *result = toCSSStyleSheetResource(cachedResource)->sheetText(false);
    206             return true;
    207         case Resource::Script:
    208             *result = toScriptResource(cachedResource)->script();
    209             return true;
    210         case Resource::MainResource:
    211             return false;
    212         case Resource::Raw: {
    213             SharedBuffer* buffer = cachedResource->resourceBuffer();
    214             if (!buffer)
    215                 return false;
    216             OwnPtr<TextResourceDecoder> decoder = createXHRTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName());
    217             String content = decoder->decode(buffer->data(), buffer->size());
    218             *result = content + decoder->flush();
    219             return true;
    220         }
    221         default:
    222             SharedBuffer* buffer = cachedResource->resourceBuffer();
    223             return decodeBuffer(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, cachedResource->response().textEncodingName(), result);
    224         }
    225     }
    226     return false;
    227 }
    228 
    229 // static
    230 bool InspectorPageAgent::sharedBufferContent(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, bool withBase64Encode, String* result)
    231 {
    232     return dataContent(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, textEncodingName, withBase64Encode, result);
    233 }
    234 
    235 bool InspectorPageAgent::dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result)
    236 {
    237     if (withBase64Encode) {
    238         *result = base64Encode(data, size);
    239         return true;
    240     }
    241 
    242     return decodeBuffer(data, size, textEncodingName, result);
    243 }
    244 
    245 PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(InstrumentingAgents* instrumentingAgents, Page* page, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
    246 {
    247     return adoptPtr(new InspectorPageAgent(instrumentingAgents, page, state, injectedScriptManager, client, overlay));
    248 }
    249 
    250 // static
    251 void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded)
    252 {
    253     DocumentLoader* loader = assertDocumentLoader(errorString, frame);
    254     if (!loader)
    255         return;
    256     if (!cachedResourceContent(cachedResource(frame, url), result, base64Encoded))
    257         *errorString = "No resource with given URL found";
    258 }
    259 
    260 Resource* InspectorPageAgent::cachedResource(Frame* frame, const KURL& url)
    261 {
    262     Resource* cachedResource = frame->document()->fetcher()->cachedResource(url);
    263     if (!cachedResource)
    264         cachedResource = memoryCache()->resourceForURL(url);
    265     return cachedResource;
    266 }
    267 
    268 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType)
    269 {
    270     switch (resourceType) {
    271     case DocumentResource:
    272         return TypeBuilder::Page::ResourceType::Document;
    273     case ImageResource:
    274         return TypeBuilder::Page::ResourceType::Image;
    275     case Font:
    276         return TypeBuilder::Page::ResourceType::Font;
    277     case StylesheetResource:
    278         return TypeBuilder::Page::ResourceType::Stylesheet;
    279     case ScriptResource:
    280         return TypeBuilder::Page::ResourceType::Script;
    281     case XHRResource:
    282         return TypeBuilder::Page::ResourceType::XHR;
    283     case WebSocketResource:
    284         return TypeBuilder::Page::ResourceType::WebSocket;
    285     case OtherResource:
    286         return TypeBuilder::Page::ResourceType::Other;
    287     }
    288     return TypeBuilder::Page::ResourceType::Other;
    289 }
    290 
    291 InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Resource& cachedResource)
    292 {
    293     switch (cachedResource.type()) {
    294     case Resource::Image:
    295         return InspectorPageAgent::ImageResource;
    296     case Resource::Font:
    297         return InspectorPageAgent::Font;
    298     case Resource::CSSStyleSheet:
    299         // Fall through.
    300     case Resource::XSLStyleSheet:
    301         return InspectorPageAgent::StylesheetResource;
    302     case Resource::Script:
    303         return InspectorPageAgent::ScriptResource;
    304     case Resource::Raw:
    305         return InspectorPageAgent::XHRResource;
    306     case Resource::MainResource:
    307         return InspectorPageAgent::DocumentResource;
    308     default:
    309         break;
    310     }
    311     return InspectorPageAgent::OtherResource;
    312 }
    313 
    314 TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson(const Resource& cachedResource)
    315 {
    316     return resourceTypeJson(cachedResourceType(cachedResource));
    317 }
    318 
    319 InspectorPageAgent::InspectorPageAgent(InstrumentingAgents* instrumentingAgents, Page* page, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
    320     : InspectorBaseAgent<InspectorPageAgent>("Page", instrumentingAgents, inspectorState)
    321     , m_page(page)
    322     , m_injectedScriptManager(injectedScriptManager)
    323     , m_client(client)
    324     , m_frontend(0)
    325     , m_overlay(overlay)
    326     , m_lastScriptIdentifier(0)
    327     , m_enabled(false)
    328     , m_geolocationOverridden(false)
    329     , m_ignoreScriptsEnabledNotification(false)
    330     , m_deviceMetricsOverridden(false)
    331     , m_emulateViewportEnabled(false)
    332 {
    333 }
    334 
    335 void InspectorPageAgent::setFrontend(InspectorFrontend* frontend)
    336 {
    337     m_frontend = frontend->page();
    338 }
    339 
    340 void InspectorPageAgent::clearFrontend()
    341 {
    342     ErrorString error;
    343     disable(&error);
    344     updateTouchEventEmulationInPage(false);
    345     m_frontend = 0;
    346 }
    347 
    348 void InspectorPageAgent::restore()
    349 {
    350     if (m_state->getBoolean(PageAgentState::pageAgentEnabled)) {
    351         ErrorString error;
    352         enable(&error);
    353         bool scriptExecutionDisabled = m_state->getBoolean(PageAgentState::pageAgentScriptExecutionDisabled);
    354         setScriptExecutionDisabled(0, scriptExecutionDisabled);
    355         bool showPaintRects = m_state->getBoolean(PageAgentState::pageAgentShowPaintRects);
    356         setShowPaintRects(0, showPaintRects);
    357         bool showDebugBorders = m_state->getBoolean(PageAgentState::pageAgentShowDebugBorders);
    358         setShowDebugBorders(0, showDebugBorders);
    359         bool showFPSCounter = m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter);
    360         setShowFPSCounter(0, showFPSCounter);
    361         String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
    362         setEmulatedMedia(0, emulatedMedia);
    363         bool continuousPaintingEnabled = m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled);
    364         setContinuousPaintingEnabled(0, continuousPaintingEnabled);
    365         bool showScrollBottleneckRects = m_state->getBoolean(PageAgentState::pageAgentShowScrollBottleneckRects);
    366         setShowScrollBottleneckRects(0, showScrollBottleneckRects);
    367 
    368         int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
    369         int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
    370         double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride);
    371         bool currentEmulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
    372         bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
    373         updateViewMetrics(currentWidth, currentHeight, currentDeviceScaleFactor, currentEmulateViewport, currentFitWindow);
    374         updateTouchEventEmulationInPage(m_state->getBoolean(PageAgentState::touchEventEmulationEnabled));
    375     }
    376 }
    377 
    378 void InspectorPageAgent::webViewResized(const IntSize& size)
    379 {
    380     int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
    381     m_overlay->resize(currentWidth ? size : IntSize());
    382 }
    383 
    384 void InspectorPageAgent::enable(ErrorString*)
    385 {
    386     m_enabled = true;
    387     m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
    388     m_instrumentingAgents->setInspectorPageAgent(this);
    389 }
    390 
    391 void InspectorPageAgent::disable(ErrorString*)
    392 {
    393     m_enabled = false;
    394     m_state->setBoolean(PageAgentState::pageAgentEnabled, false);
    395     m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
    396     m_overlay->hide();
    397     m_instrumentingAgents->setInspectorPageAgent(0);
    398     m_deviceMetricsOverridden = false;
    399 
    400     setShowPaintRects(0, false);
    401     setShowDebugBorders(0, false);
    402     setShowFPSCounter(0, false);
    403     setEmulatedMedia(0, String());
    404     setContinuousPaintingEnabled(0, false);
    405     setShowScrollBottleneckRects(0, false);
    406     setShowViewportSizeOnResize(0, false, 0);
    407 
    408     if (!deviceMetricsChanged(0, 0, 1, false, false, 1, false))
    409         return;
    410 
    411     // When disabling the agent, reset the override values if necessary.
    412     updateViewMetrics(0, 0, 1, false, false);
    413     m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
    414     m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
    415     m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 1);
    416     m_state->setBoolean(PageAgentState::pageAgentEmulateViewport, false);
    417     m_state->setBoolean(PageAgentState::pageAgentFitWindow, false);
    418     m_state->setDouble(PageAgentState::fontScaleFactor, 1);
    419     m_state->setBoolean(PageAgentState::pageAgentTextAutosizingOverride, false);
    420 }
    421 
    422 void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier)
    423 {
    424     RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
    425     if (!scripts) {
    426         scripts = JSONObject::create();
    427         m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
    428     }
    429     // Assure we don't override existing ids -- m_lastScriptIdentifier could get out of sync WRT actual
    430     // scripts once we restored the scripts from the cookie during navigation.
    431     do {
    432         *identifier = String::number(++m_lastScriptIdentifier);
    433     } while (scripts->find(*identifier) != scripts->end());
    434     scripts->setString(*identifier, source);
    435 
    436     // Force cookie serialization.
    437     m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
    438 }
    439 
    440 void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const String& identifier)
    441 {
    442     RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
    443     if (!scripts || scripts->find(identifier) == scripts->end()) {
    444         *error = "Script not found";
    445         return;
    446     }
    447     scripts->remove(identifier);
    448 }
    449 
    450 void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor)
    451 {
    452     m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
    453     m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
    454     m_page->mainFrame()->loader().reload(optionalIgnoreCache && *optionalIgnoreCache ? EndToEndReload : NormalReload);
    455 }
    456 
    457 void InspectorPageAgent::navigate(ErrorString*, const String& url)
    458 {
    459     UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
    460     Frame* frame = m_page->mainFrame();
    461     FrameLoadRequest request(frame->document(), ResourceRequest(frame->document()->completeURL(url)));
    462     frame->loader().load(request);
    463 }
    464 
    465 void InspectorPageAgent::getNavigationHistory(ErrorString*, int*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::NavigationEntry> >&)
    466 { }
    467 
    468 void InspectorPageAgent::navigateToHistoryEntry(ErrorString*, int)
    469 { }
    470 
    471 static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
    472 {
    473     return TypeBuilder::Page::Cookie::create()
    474         .setName(cookie.name)
    475         .setValue(cookie.value)
    476         .setDomain(cookie.domain)
    477         .setPath(cookie.path)
    478         .setExpires(cookie.expires)
    479         .setSize((cookie.name.length() + cookie.value.length()))
    480         .setHttpOnly(cookie.httpOnly)
    481         .setSecure(cookie.secure)
    482         .setSession(cookie.session)
    483         .release();
    484 }
    485 
    486 static PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > buildArrayForCookies(ListHashSet<Cookie>& cookiesList)
    487 {
    488     RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > cookies = TypeBuilder::Array<TypeBuilder::Page::Cookie>::create();
    489 
    490     ListHashSet<Cookie>::iterator end = cookiesList.end();
    491     ListHashSet<Cookie>::iterator it = cookiesList.begin();
    492     for (int i = 0; it != end; ++it, i++)
    493         cookies->addItem(buildObjectForCookie(*it));
    494 
    495     return cookies;
    496 }
    497 
    498 static Vector<Resource*> cachedResourcesForFrame(Frame* frame)
    499 {
    500     Vector<Resource*> result;
    501 
    502     const ResourceFetcher::DocumentResourceMap& allResources = frame->document()->fetcher()->allResources();
    503     ResourceFetcher::DocumentResourceMap::const_iterator end = allResources.end();
    504     for (ResourceFetcher::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
    505         Resource* cachedResource = it->value.get();
    506 
    507         switch (cachedResource->type()) {
    508         case Resource::Image:
    509             // Skip images that were not auto loaded (images disabled in the user agent).
    510             if (toImageResource(cachedResource)->stillNeedsLoad())
    511                 continue;
    512             break;
    513         case Resource::Font:
    514             // Skip fonts that were referenced in CSS but never used/downloaded.
    515             if (toFontResource(cachedResource)->stillNeedsLoad())
    516                 continue;
    517             break;
    518         default:
    519             // All other Resource types download immediately.
    520             break;
    521         }
    522 
    523         result.append(cachedResource);
    524     }
    525 
    526     return result;
    527 }
    528 
    529 static Vector<KURL> allResourcesURLsForFrame(Frame* frame)
    530 {
    531     Vector<KURL> result;
    532 
    533     result.append(urlWithoutFragment(frame->loader().documentLoader()->url()));
    534 
    535     Vector<Resource*> allResources = cachedResourcesForFrame(frame);
    536     for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it)
    537         result.append(urlWithoutFragment((*it)->url()));
    538 
    539     return result;
    540 }
    541 
    542 void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies)
    543 {
    544     ListHashSet<Cookie> rawCookiesList;
    545 
    546     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
    547         Document* document = frame->document();
    548         Vector<KURL> allURLs = allResourcesURLsForFrame(frame);
    549         for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
    550             Vector<Cookie> docCookiesList;
    551             getRawCookies(document, *it, docCookiesList);
    552             int cookiesSize = docCookiesList.size();
    553             for (int i = 0; i < cookiesSize; i++) {
    554                 if (!rawCookiesList.contains(docCookiesList[i]))
    555                     rawCookiesList.add(docCookiesList[i]);
    556             }
    557         }
    558     }
    559 
    560     cookies = buildArrayForCookies(rawCookiesList);
    561 }
    562 
    563 void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
    564 {
    565     KURL parsedURL(ParsedURLString, url);
    566     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame()))
    567         WebCore::deleteCookie(frame->document(), parsedURL, cookieName);
    568 }
    569 
    570 void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>& object)
    571 {
    572     object = buildObjectForFrameTree(m_page->mainFrame());
    573 }
    574 
    575 void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded)
    576 {
    577     Frame* frame = assertFrame(errorString, frameId);
    578     if (!frame)
    579         return;
    580     resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded);
    581 }
    582 
    583 static bool textContentForResource(Resource* cachedResource, String* result)
    584 {
    585     if (hasTextContent(cachedResource)) {
    586         String content;
    587         bool base64Encoded;
    588         if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {
    589             ASSERT(!base64Encoded);
    590             return true;
    591         }
    592     }
    593     return false;
    594 }
    595 
    596 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)
    597 {
    598     results = TypeBuilder::Array<TypeBuilder::Page::SearchMatch>::create();
    599 
    600     bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
    601     bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
    602 
    603     Frame* frame = frameForId(frameId);
    604     KURL kurl(ParsedURLString, url);
    605 
    606     FrameLoader* frameLoader = frame ? &frame->loader() : 0;
    607     DocumentLoader* loader = frameLoader ? frameLoader->documentLoader() : 0;
    608     if (!loader)
    609         return;
    610 
    611     String content;
    612     bool success = false;
    613     Resource* resource = cachedResource(frame, kurl);
    614     if (resource)
    615         success = textContentForResource(resource, &content);
    616 
    617     if (!success)
    618         return;
    619 
    620     results = ContentSearchUtils::searchInTextByLines(content, query, caseSensitive, isRegex);
    621 }
    622 
    623 void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
    624 {
    625     Frame* frame = assertFrame(errorString, frameId);
    626     if (!frame)
    627         return;
    628 
    629     Document* document = frame->document();
    630     if (!document) {
    631         *errorString = "No Document instance to set HTML for";
    632         return;
    633     }
    634     DOMPatchSupport::patchDocument(*document, html);
    635 }
    636 
    637 void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, const bool* optionalTextAutosizing, const double* optionalFontScaleFactor)
    638 {
    639     const static long maxDimension = 10000000;
    640 
    641     bool textAutosizing = optionalTextAutosizing ? *optionalTextAutosizing : false;
    642     double fontScaleFactor = optionalFontScaleFactor ? *optionalFontScaleFactor : 1;
    643 
    644     if (width < 0 || height < 0 || width > maxDimension || height > maxDimension) {
    645         *errorString = "Width and height values must be positive, not greater than " + String::number(maxDimension);
    646         return;
    647     }
    648 
    649     if (!width ^ !height) {
    650         *errorString = "Both width and height must be either zero or non-zero at once";
    651         return;
    652     }
    653 
    654     if (deviceScaleFactor <= 0) {
    655         *errorString = "deviceScaleFactor must be positive";
    656         return;
    657     }
    658 
    659     if (fontScaleFactor <= 0) {
    660         *errorString = "fontScaleFactor must be positive";
    661         return;
    662     }
    663 
    664     Settings& settings = m_page->settings();
    665     if (width && height && !settings.acceleratedCompositingEnabled()) {
    666         if (errorString)
    667             *errorString = "Compositing mode is not supported";
    668         return;
    669     }
    670 
    671     if (!deviceMetricsChanged(width, height, deviceScaleFactor, emulateViewport, fitWindow, fontScaleFactor, textAutosizing))
    672         return;
    673 
    674 
    675     m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
    676     m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
    677     m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, deviceScaleFactor);
    678     m_state->setBoolean(PageAgentState::pageAgentEmulateViewport, emulateViewport);
    679     m_state->setBoolean(PageAgentState::pageAgentFitWindow, fitWindow);
    680     m_state->setDouble(PageAgentState::fontScaleFactor, fontScaleFactor);
    681     m_state->setBoolean(PageAgentState::pageAgentTextAutosizingOverride, textAutosizing);
    682 
    683     updateViewMetrics(width, height, deviceScaleFactor, emulateViewport, fitWindow);
    684 }
    685 
    686 bool InspectorPageAgent::deviceMetricsChanged(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing)
    687 {
    688     // These two always fit an int.
    689     int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
    690     int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
    691     double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 1);
    692     bool currentEmulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
    693     bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
    694     double currentFontScaleFactor = m_state->getDouble(PageAgentState::fontScaleFactor, 1);
    695     bool currentTextAutosizing = m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
    696 
    697     return width != currentWidth || height != currentHeight || deviceScaleFactor != currentDeviceScaleFactor || emulateViewport != currentEmulateViewport || fitWindow != currentFitWindow || fontScaleFactor != currentFontScaleFactor || textAutosizing != currentTextAutosizing;
    698 }
    699 
    700 void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
    701 {
    702     m_state->setBoolean(PageAgentState::pageAgentShowPaintRects, show);
    703     m_client->setShowPaintRects(show);
    704 
    705     if (!show && mainFrame() && mainFrame()->view())
    706         mainFrame()->view()->invalidate();
    707 }
    708 
    709 void InspectorPageAgent::setShowDebugBorders(ErrorString* errorString, bool show)
    710 {
    711     m_state->setBoolean(PageAgentState::pageAgentShowDebugBorders, show);
    712     if (show && !forceCompositingMode(errorString))
    713         return;
    714     m_client->setShowDebugBorders(show);
    715 }
    716 
    717 void InspectorPageAgent::setShowFPSCounter(ErrorString* errorString, bool show)
    718 {
    719     // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
    720     m_state->setBoolean(PageAgentState::pageAgentShowFPSCounter, show);
    721     if (show && !forceCompositingMode(errorString))
    722         return;
    723     m_client->setShowFPSCounter(show && !m_deviceMetricsOverridden);
    724 }
    725 
    726 void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString* errorString, bool enabled)
    727 {
    728     m_state->setBoolean(PageAgentState::pageAgentContinuousPaintingEnabled, enabled);
    729     if (enabled && !forceCompositingMode(errorString))
    730         return;
    731     m_client->setContinuousPaintingEnabled(enabled && !m_deviceMetricsOverridden);
    732 }
    733 
    734 void InspectorPageAgent::setShowScrollBottleneckRects(ErrorString* errorString, bool show)
    735 {
    736     m_state->setBoolean(PageAgentState::pageAgentShowScrollBottleneckRects, show);
    737     if (show && !forceCompositingMode(errorString))
    738         return;
    739     m_client->setShowScrollBottleneckRects(show);
    740 }
    741 
    742 void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum* status)
    743 {
    744     bool disabledByScriptController = false;
    745     bool disabledInSettings = false;
    746     Frame* frame = mainFrame();
    747     if (frame) {
    748         disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript);
    749         if (frame->settings())
    750             disabledInSettings = !frame->settings()->isScriptEnabled();
    751     }
    752 
    753     if (!disabledByScriptController) {
    754         *status = PageCommandHandler::Result::Allowed;
    755         return;
    756     }
    757 
    758     if (disabledInSettings)
    759         *status = PageCommandHandler::Result::Disabled;
    760     else
    761         *status = PageCommandHandler::Result::Forbidden;
    762 }
    763 
    764 void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
    765 {
    766     m_state->setBoolean(PageAgentState::pageAgentScriptExecutionDisabled, value);
    767     if (!mainFrame())
    768         return;
    769 
    770     Settings* settings = mainFrame()->settings();
    771     if (settings) {
    772         m_ignoreScriptsEnabledNotification = true;
    773         settings->setScriptEnabled(!value);
    774         m_ignoreScriptsEnabledNotification = false;
    775     }
    776 }
    777 
    778 void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
    779 {
    780     if (world != mainThreadNormalWorld())
    781         return;
    782 
    783     if (frame == m_page->mainFrame())
    784         m_injectedScriptManager->discardInjectedScripts();
    785 
    786     if (!m_frontend)
    787         return;
    788 
    789     RefPtr<JSONObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
    790     if (scripts) {
    791         JSONObject::const_iterator end = scripts->end();
    792         for (JSONObject::const_iterator it = scripts->begin(); it != end; ++it) {
    793             String scriptText;
    794             if (it->value->asString(&scriptText))
    795                 frame->script().executeScriptInMainWorld(scriptText);
    796         }
    797     }
    798     if (!m_scriptToEvaluateOnLoadOnce.isEmpty())
    799         frame->script().executeScriptInMainWorld(m_scriptToEvaluateOnLoadOnce);
    800 }
    801 
    802 void InspectorPageAgent::domContentLoadedEventFired(Frame* frame)
    803 {
    804     if (!frame->isMainFrame())
    805         return;
    806     m_frontend->domContentEventFired(currentTime());
    807 }
    808 
    809 void InspectorPageAgent::loadEventFired(Frame* frame)
    810 {
    811     if (!frame->isMainFrame())
    812         return;
    813     m_frontend->loadEventFired(currentTime());
    814 }
    815 
    816 void InspectorPageAgent::didCommitLoad(Frame*, DocumentLoader* loader)
    817 {
    818     // FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
    819     // then all we need to check here is loader->frame()->isMainFrame()
    820     // and we don't need "frame" at all.
    821     if (loader->frame() == m_page->mainFrame()) {
    822         m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce;
    823         m_scriptPreprocessorSource = m_pendingScriptPreprocessor;
    824         m_pendingScriptToEvaluateOnLoadOnce = String();
    825         m_pendingScriptPreprocessor = String();
    826     }
    827     m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
    828 }
    829 
    830 void InspectorPageAgent::frameAttachedToParent(Frame* frame)
    831 {
    832     m_frontend->frameAttached(frameId(frame), frameId(frame->tree().parent()));
    833 }
    834 
    835 void InspectorPageAgent::frameDetachedFromParent(Frame* frame)
    836 {
    837     HashMap<Frame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
    838     if (iterator != m_frameToIdentifier.end()) {
    839         m_frontend->frameDetached(iterator->value);
    840         m_identifierToFrame.remove(iterator->value);
    841         m_frameToIdentifier.remove(iterator);
    842     }
    843 }
    844 
    845 Frame* InspectorPageAgent::mainFrame()
    846 {
    847     return m_page->mainFrame();
    848 }
    849 
    850 Frame* InspectorPageAgent::frameForId(const String& frameId)
    851 {
    852     return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
    853 }
    854 
    855 String InspectorPageAgent::frameId(Frame* frame)
    856 {
    857     if (!frame)
    858         return "";
    859     String identifier = m_frameToIdentifier.get(frame);
    860     if (identifier.isNull()) {
    861         identifier = IdentifiersFactory::createIdentifier();
    862         m_frameToIdentifier.set(frame, identifier);
    863         m_identifierToFrame.set(identifier, frame);
    864     }
    865     return identifier;
    866 }
    867 
    868 bool InspectorPageAgent::hasIdForFrame(Frame* frame) const
    869 {
    870     return frame && m_frameToIdentifier.contains(frame);
    871 }
    872 
    873 String InspectorPageAgent::loaderId(DocumentLoader* loader)
    874 {
    875     if (!loader)
    876         return "";
    877     String identifier = m_loaderToIdentifier.get(loader);
    878     if (identifier.isNull()) {
    879         identifier = IdentifiersFactory::createIdentifier();
    880         m_loaderToIdentifier.set(loader, identifier);
    881     }
    882     return identifier;
    883 }
    884 
    885 Frame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
    886 {
    887     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    888         RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin();
    889         if (documentOrigin->toRawString() == originRawString)
    890             return frame;
    891     }
    892     return 0;
    893 }
    894 
    895 Frame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
    896 {
    897     Frame* frame = frameForId(frameId);
    898     if (!frame)
    899         *errorString = "No frame for given id found";
    900     return frame;
    901 }
    902 
    903 const AtomicString& InspectorPageAgent::resourceSourceMapURL(const String& url)
    904 {
    905     DEFINE_STATIC_LOCAL(const AtomicString, sourceMapHttpHeader, ("SourceMap", AtomicString::ConstructFromLiteral));
    906     DEFINE_STATIC_LOCAL(const AtomicString, deprecatedSourceMapHttpHeader, ("X-SourceMap", AtomicString::ConstructFromLiteral));
    907     if (url.isEmpty())
    908         return nullAtom;
    909     Frame* frame = mainFrame();
    910     if (!frame)
    911         return nullAtom;
    912     Resource* resource = cachedResource(frame, KURL(ParsedURLString, url));
    913     if (!resource)
    914         return nullAtom;
    915     const AtomicString& deprecatedHeaderSourceMapURL = resource->response().httpHeaderField(deprecatedSourceMapHttpHeader);
    916     if (!deprecatedHeaderSourceMapURL.isEmpty()) {
    917         // FIXME: add deprecated console message here.
    918         return deprecatedHeaderSourceMapURL;
    919     }
    920     return resource->response().httpHeaderField(sourceMapHttpHeader);
    921 }
    922 
    923 bool InspectorPageAgent::deviceMetricsOverrideEnabled()
    924 {
    925     return m_enabled && m_deviceMetricsOverridden;
    926 }
    927 
    928 // static
    929 DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, Frame* frame)
    930 {
    931     DocumentLoader* documentLoader = frame->loader().documentLoader();
    932     if (!documentLoader)
    933         *errorString = "No documentLoader for given frame found";
    934     return documentLoader;
    935 }
    936 
    937 void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
    938 {
    939     HashMap<DocumentLoader*, String>::iterator iterator = m_loaderToIdentifier.find(loader);
    940     if (iterator != m_loaderToIdentifier.end())
    941         m_loaderToIdentifier.remove(iterator);
    942 }
    943 
    944 void InspectorPageAgent::frameStartedLoading(Frame* frame)
    945 {
    946     m_frontend->frameStartedLoading(frameId(frame));
    947 }
    948 
    949 void InspectorPageAgent::frameStoppedLoading(Frame* frame)
    950 {
    951     m_frontend->frameStoppedLoading(frameId(frame));
    952 }
    953 
    954 void InspectorPageAgent::frameScheduledNavigation(Frame* frame, double delay)
    955 {
    956     m_frontend->frameScheduledNavigation(frameId(frame), delay);
    957 }
    958 
    959 void InspectorPageAgent::frameClearedScheduledNavigation(Frame* frame)
    960 {
    961     m_frontend->frameClearedScheduledNavigation(frameId(frame));
    962 }
    963 
    964 void InspectorPageAgent::willRunJavaScriptDialog(const String& message)
    965 {
    966     m_frontend->javascriptDialogOpening(message);
    967 }
    968 
    969 void InspectorPageAgent::didRunJavaScriptDialog()
    970 {
    971     m_frontend->javascriptDialogClosed();
    972 }
    973 
    974 void InspectorPageAgent::didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext* context, const LayoutRect& rect)
    975 {
    976     if (!m_enabled || m_client->overridesShowPaintRects() || !m_state->getBoolean(PageAgentState::pageAgentShowPaintRects))
    977         return;
    978 
    979     static int colorSelector = 0;
    980     const Color colors[] = {
    981         Color(0xFF, 0, 0, 0x3F),
    982         Color(0xFF, 0, 0xFF, 0x3F),
    983         Color(0, 0, 0xFF, 0x3F),
    984     };
    985 
    986     LayoutRect inflatedRect(rect);
    987     inflatedRect.inflate(-1);
    988     m_overlay->drawOutline(context, inflatedRect, colors[colorSelector++ % WTF_ARRAY_LENGTH(colors)]);
    989 }
    990 
    991 void InspectorPageAgent::didLayout(RenderObject*)
    992 {
    993     if (!m_enabled)
    994         return;
    995     m_overlay->update();
    996 }
    997 
    998 void InspectorPageAgent::didScroll()
    999 {
   1000     if (m_enabled)
   1001         m_overlay->update();
   1002 }
   1003 
   1004 void InspectorPageAgent::didResizeMainFrame()
   1005 {
   1006     if (m_enabled && m_state->getBoolean(PageAgentState::showSizeOnResize))
   1007         m_overlay->showAndHideViewSize(m_state->getBoolean(PageAgentState::showGridOnResize));
   1008     m_frontend->frameResized();
   1009 }
   1010 
   1011 void InspectorPageAgent::didRecalculateStyle()
   1012 {
   1013     if (m_enabled)
   1014         m_overlay->update();
   1015 }
   1016 
   1017 void InspectorPageAgent::scriptsEnabled(bool isEnabled)
   1018 {
   1019     if (m_ignoreScriptsEnabledNotification)
   1020         return;
   1021 
   1022     m_frontend->scriptsEnabled(isEnabled);
   1023 }
   1024 
   1025 PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
   1026 {
   1027     RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
   1028         .setId(frameId(frame))
   1029         .setLoaderId(loaderId(frame->loader().documentLoader()))
   1030         .setUrl(urlWithoutFragment(frame->document()->url()).string())
   1031         .setMimeType(frame->loader().documentLoader()->responseMIMEType())
   1032         .setSecurityOrigin(frame->document()->securityOrigin()->toRawString());
   1033     if (frame->tree().parent())
   1034         frameObject->setParentId(frameId(frame->tree().parent()));
   1035     if (frame->ownerElement()) {
   1036         AtomicString name = frame->ownerElement()->getNameAttribute();
   1037         if (name.isEmpty())
   1038             name = frame->ownerElement()->getAttribute(HTMLNames::idAttr);
   1039         frameObject->setName(name);
   1040     }
   1041 
   1042     return frameObject;
   1043 }
   1044 
   1045 PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(Frame* frame)
   1046 {
   1047     RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
   1048     RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
   1049     RefPtr<TypeBuilder::Page::FrameResourceTree> result = TypeBuilder::Page::FrameResourceTree::create()
   1050          .setFrame(frameObject)
   1051          .setResources(subresources);
   1052 
   1053     Vector<Resource*> allResources = cachedResourcesForFrame(frame);
   1054     for (Vector<Resource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) {
   1055         Resource* cachedResource = *it;
   1056 
   1057         RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
   1058             .setUrl(urlWithoutFragment(cachedResource->url()).string())
   1059             .setType(cachedResourceTypeJson(*cachedResource))
   1060             .setMimeType(cachedResource->response().mimeType());
   1061         if (cachedResource->wasCanceled())
   1062             resourceObject->setCanceled(true);
   1063         else if (cachedResource->status() == Resource::LoadError)
   1064             resourceObject->setFailed(true);
   1065         subresources->addItem(resourceObject);
   1066     }
   1067 
   1068     RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
   1069     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
   1070         if (!childrenArray) {
   1071             childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
   1072             result->setChildFrames(childrenArray);
   1073         }
   1074         childrenArray->addItem(buildObjectForFrameTree(child));
   1075     }
   1076     return result;
   1077 }
   1078 
   1079 void InspectorPageAgent::updateViewMetrics(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow)
   1080 {
   1081     if (width && height && !m_page->settings().acceleratedCompositingEnabled())
   1082         return;
   1083 
   1084     m_deviceMetricsOverridden = width && height;
   1085     m_emulateViewportEnabled = emulateViewport;
   1086     m_client->overrideDeviceMetrics(width, height, static_cast<float>(deviceScaleFactor), emulateViewport, fitWindow);
   1087 
   1088     Document* document = mainFrame()->document();
   1089     if (document) {
   1090         document->styleResolverChanged(RecalcStyleImmediately);
   1091         document->mediaQueryAffectingValueChanged();
   1092     }
   1093     InspectorInstrumentation::mediaQueryResultChanged(document);
   1094 
   1095     // FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
   1096     m_client->setShowFPSCounter(m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter) && !m_deviceMetricsOverridden);
   1097     m_client->setContinuousPaintingEnabled(m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled) && !m_deviceMetricsOverridden);
   1098 }
   1099 
   1100 void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled)
   1101 {
   1102     m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
   1103     if (mainFrame() && mainFrame()->settings())
   1104         mainFrame()->settings()->setTouchEventEmulationEnabled(enabled);
   1105 }
   1106 
   1107 void InspectorPageAgent::setGeolocationOverride(ErrorString* error, const double* latitude, const double* longitude, const double* accuracy)
   1108 {
   1109     GeolocationController* controller = GeolocationController::from(m_page);
   1110     GeolocationPosition* position = 0;
   1111     if (!controller) {
   1112         *error = "Internal error: unable to override geolocation";
   1113         return;
   1114     }
   1115     position = controller->lastPosition();
   1116     if (!m_geolocationOverridden && position)
   1117         m_platformGeolocationPosition = position;
   1118 
   1119     m_geolocationOverridden = true;
   1120     if (latitude && longitude && accuracy)
   1121         m_geolocationPosition = GeolocationPosition::create(currentTimeMS(), *latitude, *longitude, *accuracy);
   1122     else
   1123         m_geolocationPosition.clear();
   1124 
   1125     controller->positionChanged(0); // Kick location update.
   1126 }
   1127 
   1128 void InspectorPageAgent::clearGeolocationOverride(ErrorString*)
   1129 {
   1130     if (!m_geolocationOverridden)
   1131         return;
   1132     m_geolocationOverridden = false;
   1133     m_geolocationPosition.clear();
   1134 
   1135     GeolocationController* controller = GeolocationController::from(m_page);
   1136     if (controller && m_platformGeolocationPosition.get())
   1137         controller->positionChanged(m_platformGeolocationPosition.get());
   1138 }
   1139 
   1140 GeolocationPosition* InspectorPageAgent::overrideGeolocationPosition(GeolocationPosition* position)
   1141 {
   1142     if (m_geolocationOverridden) {
   1143         if (position)
   1144             m_platformGeolocationPosition = position;
   1145         return m_geolocationPosition.get();
   1146     }
   1147     return position;
   1148 }
   1149 
   1150 void InspectorPageAgent::setDeviceOrientationOverride(ErrorString* error, double alpha, double beta, double gamma)
   1151 {
   1152     DeviceOrientationController* controller = DeviceOrientationController::from(mainFrame()->document());
   1153     if (!controller) {
   1154         *error = "Internal error: unable to override device orientation";
   1155         return;
   1156     }
   1157 
   1158     controller->didChangeDeviceOrientation(DeviceOrientationData::create(true, alpha, true, beta, true, gamma).get());
   1159 }
   1160 
   1161 void InspectorPageAgent::clearDeviceOrientationOverride(ErrorString* error)
   1162 {
   1163     setDeviceOrientationOverride(error, 0, 0, 0);
   1164 }
   1165 
   1166 bool InspectorPageAgent::overrideTextAutosizing(bool textAutosizing)
   1167 {
   1168     if (!m_deviceMetricsOverridden)
   1169         return textAutosizing;
   1170     return m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
   1171 }
   1172 
   1173 float InspectorPageAgent::overrideFontScaleFactor(float fontScaleFactor)
   1174 {
   1175     if (!m_deviceMetricsOverridden)
   1176         return fontScaleFactor;
   1177     return static_cast<float>(m_state->getDouble(PageAgentState::fontScaleFactor));
   1178 }
   1179 
   1180 void InspectorPageAgent::setTouchEmulationEnabled(ErrorString*, bool enabled)
   1181 {
   1182     if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
   1183         return;
   1184     updateTouchEventEmulationInPage(enabled);
   1185 }
   1186 
   1187 void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media)
   1188 {
   1189     String currentMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
   1190     if (media == currentMedia)
   1191         return;
   1192 
   1193     m_state->setString(PageAgentState::pageAgentEmulatedMedia, media);
   1194     Document* document = 0;
   1195     if (m_page->mainFrame())
   1196         document = m_page->mainFrame()->document();
   1197     if (document) {
   1198         document->mediaQueryAffectingValueChanged();
   1199         document->styleResolverChanged(RecalcStyleImmediately);
   1200         document->updateLayout();
   1201     }
   1202 }
   1203 
   1204 bool InspectorPageAgent::applyViewportStyleOverride(StyleResolver* resolver)
   1205 {
   1206     if (!m_deviceMetricsOverridden || !m_emulateViewportEnabled)
   1207         return false;
   1208 
   1209     RefPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode));
   1210     styleSheet->parseString(String(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet)));
   1211     OwnPtr<RuleSet> ruleSet = RuleSet::create();
   1212     ruleSet->addRulesFromSheet(styleSheet.get(), MediaQueryEvaluator("screen"));
   1213     resolver->viewportStyleResolver()->collectViewportRules(ruleSet.get(), ViewportStyleResolver::UserAgentOrigin);
   1214     return true;
   1215 }
   1216 
   1217 void InspectorPageAgent::applyEmulatedMedia(String* media)
   1218 {
   1219     String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
   1220     if (!emulatedMedia.isEmpty())
   1221         *media = emulatedMedia;
   1222 }
   1223 
   1224 bool InspectorPageAgent::forceCompositingMode(ErrorString* errorString)
   1225 {
   1226     Settings& settings = m_page->settings();
   1227     if (!settings.acceleratedCompositingEnabled()) {
   1228         if (errorString)
   1229             *errorString = "Compositing mode is not supported";
   1230         return false;
   1231     }
   1232     if (settings.forceCompositingMode())
   1233         return true;
   1234     settings.setForceCompositingMode(true);
   1235     Frame* mainFrame = m_page->mainFrame();
   1236     if (mainFrame)
   1237         mainFrame->view()->updateCompositingLayersAfterStyleChange();
   1238     return true;
   1239 }
   1240 
   1241 void InspectorPageAgent::captureScreenshot(ErrorString*, const String*, const int*, const int*, const int*, String*, RefPtr<TypeBuilder::Page::ScreencastFrameMetadata>&)
   1242 {
   1243     // Handled on the browser level.
   1244 }
   1245 
   1246 void InspectorPageAgent::canScreencast(ErrorString*, bool*)
   1247 {
   1248     // Handled on the browser level.
   1249 }
   1250 
   1251 void InspectorPageAgent::startScreencast(ErrorString*, const String*, const int*, const int*, const int*)
   1252 {
   1253     // Handled on the browser level.
   1254 }
   1255 
   1256 void InspectorPageAgent::stopScreencast(ErrorString*)
   1257 {
   1258     // Handled on the browser level.
   1259 }
   1260 
   1261 void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool accept, const String* promptText)
   1262 {
   1263     // Handled on the browser level.
   1264 }
   1265 
   1266 void InspectorPageAgent::queryUsageAndQuota(WebCore::ErrorString*, const WTF::String&, WTF::RefPtr<WebCore::TypeBuilder::Page::Quota>&, WTF::RefPtr<WebCore::TypeBuilder::Page::Usage>&)
   1267 {
   1268     // Handled on the browser level.
   1269 }
   1270 
   1271 void InspectorPageAgent::setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid)
   1272 {
   1273     m_state->setBoolean(PageAgentState::showSizeOnResize, show);
   1274     m_state->setBoolean(PageAgentState::showGridOnResize, showGrid && *showGrid);
   1275 }
   1276 
   1277 } // namespace WebCore
   1278 
   1279