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