1cad810f21b803229eb11403f9209855525a25d57Steve Block/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved.
3cad810f21b803229eb11403f9209855525a25d57Steve Block *
4cad810f21b803229eb11403f9209855525a25d57Steve Block * Redistribution and use in source and binary forms, with or without
5cad810f21b803229eb11403f9209855525a25d57Steve Block * modification, are permitted provided that the following conditions are
6cad810f21b803229eb11403f9209855525a25d57Steve Block * met:
7cad810f21b803229eb11403f9209855525a25d57Steve Block *
8cad810f21b803229eb11403f9209855525a25d57Steve Block *     * Redistributions of source code must retain the above copyright
9cad810f21b803229eb11403f9209855525a25d57Steve Block * notice, this list of conditions and the following disclaimer.
10cad810f21b803229eb11403f9209855525a25d57Steve Block *     * Redistributions in binary form must reproduce the above
11cad810f21b803229eb11403f9209855525a25d57Steve Block * copyright notice, this list of conditions and the following disclaimer
12cad810f21b803229eb11403f9209855525a25d57Steve Block * in the documentation and/or other materials provided with the
13cad810f21b803229eb11403f9209855525a25d57Steve Block * distribution.
14cad810f21b803229eb11403f9209855525a25d57Steve Block *     * Neither the name of Google Inc. nor the names of its
15cad810f21b803229eb11403f9209855525a25d57Steve Block * contributors may be used to endorse or promote products derived from
16cad810f21b803229eb11403f9209855525a25d57Steve Block * this software without specific prior written permission.
17cad810f21b803229eb11403f9209855525a25d57Steve Block *
18cad810f21b803229eb11403f9209855525a25d57Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19cad810f21b803229eb11403f9209855525a25d57Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20cad810f21b803229eb11403f9209855525a25d57Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21cad810f21b803229eb11403f9209855525a25d57Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22cad810f21b803229eb11403f9209855525a25d57Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23cad810f21b803229eb11403f9209855525a25d57Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24cad810f21b803229eb11403f9209855525a25d57Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25cad810f21b803229eb11403f9209855525a25d57Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26cad810f21b803229eb11403f9209855525a25d57Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27cad810f21b803229eb11403f9209855525a25d57Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28cad810f21b803229eb11403f9209855525a25d57Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29cad810f21b803229eb11403f9209855525a25d57Steve Block */
30cad810f21b803229eb11403f9209855525a25d57Steve Block
31cad810f21b803229eb11403f9209855525a25d57Steve Block
322bde8e466a4451c7319e3a072d118917957d6554Steve BlockWebInspector.ResourceTreeModel = function(networkManager)
33cad810f21b803229eb11403f9209855525a25d57Steve Block{
342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
352bde8e466a4451c7319e3a072d118917957d6554Steve Block    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceUpdated, this._onResourceUpdated, this);
362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceUpdated, this);
372bde8e466a4451c7319e3a072d118917957d6554Steve Block    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.FrameDetached, this._onFrameDetachedFromParent, this);
382bde8e466a4451c7319e3a072d118917957d6554Steve Block    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.FrameCommittedLoad, this._onCommitLoad, this);
392bde8e466a4451c7319e3a072d118917957d6554Steve Block
402bde8e466a4451c7319e3a072d118917957d6554Steve Block    this.frontendReused();
412bde8e466a4451c7319e3a072d118917957d6554Steve Block}
422bde8e466a4451c7319e3a072d118917957d6554Steve Block
432bde8e466a4451c7319e3a072d118917957d6554Steve BlockWebInspector.ResourceTreeModel.EventTypes = {
442bde8e466a4451c7319e3a072d118917957d6554Steve Block    FrameAdded: "FrameAdded",
452bde8e466a4451c7319e3a072d118917957d6554Steve Block    FrameNavigated: "FrameNavigated",
462bde8e466a4451c7319e3a072d118917957d6554Steve Block    FrameDetached: "FrameDetached",
472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ResourceAdded: "ResourceAdded",
482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    CachedResourcesLoaded: "CachedResourcesLoaded"
49cad810f21b803229eb11403f9209855525a25d57Steve Block}
50cad810f21b803229eb11403f9209855525a25d57Steve Block
51cad810f21b803229eb11403f9209855525a25d57Steve BlockWebInspector.ResourceTreeModel.prototype = {
522bde8e466a4451c7319e3a072d118917957d6554Steve Block    frontendReused: function()
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        this._resourcesByURL = {};
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        this._resourcesByFrameId = {};
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        this._subframes = {};
572bde8e466a4451c7319e3a072d118917957d6554Steve Block        NetworkAgent.getCachedResources(this._processCachedResources.bind(this));
582bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
592bde8e466a4451c7319e3a072d118917957d6554Steve Block
602bde8e466a4451c7319e3a072d118917957d6554Steve Block    _processCachedResources: function(error, mainFramePayload)
612bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
622bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (error)
632bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
642bde8e466a4451c7319e3a072d118917957d6554Steve Block
652bde8e466a4451c7319e3a072d118917957d6554Steve Block        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, 0);
662bde8e466a4451c7319e3a072d118917957d6554Steve Block
672bde8e466a4451c7319e3a072d118917957d6554Steve Block        WebInspector.mainResource = this._addFramesRecursively(mainFramePayload);
682bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._cachedResourcesProcessed = true;
692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    },
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
732bde8e466a4451c7319e3a072d118917957d6554Steve Block    _addOrUpdateFrame: function(frame)
74cad810f21b803229eb11403f9209855525a25d57Steve Block    {
752bde8e466a4451c7319e3a072d118917957d6554Steve Block        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
762bde8e466a4451c7319e3a072d118917957d6554Steve Block
77cad810f21b803229eb11403f9209855525a25d57Steve Block        var subframes = this._subframes[frame.parentId];
78cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!subframes) {
792bde8e466a4451c7319e3a072d118917957d6554Steve Block            subframes = [];
80cad810f21b803229eb11403f9209855525a25d57Steve Block            this._subframes[frame.parentId || 0] = subframes;
81cad810f21b803229eb11403f9209855525a25d57Steve Block        }
822bde8e466a4451c7319e3a072d118917957d6554Steve Block        subframes.push(frame);
83cad810f21b803229eb11403f9209855525a25d57Steve Block    },
84cad810f21b803229eb11403f9209855525a25d57Steve Block
852bde8e466a4451c7319e3a072d118917957d6554Steve Block    frames: function(parentFrameId)
86cad810f21b803229eb11403f9209855525a25d57Steve Block    {
872bde8e466a4451c7319e3a072d118917957d6554Steve Block        return this._subframes[parentFrameId] || [];
882bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
892bde8e466a4451c7319e3a072d118917957d6554Steve Block
902bde8e466a4451c7319e3a072d118917957d6554Steve Block    subframes: function(parentFrameId)
912bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
922bde8e466a4451c7319e3a072d118917957d6554Steve Block        return this._subframes[parentFrameId] || [];
932bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
942bde8e466a4451c7319e3a072d118917957d6554Steve Block
952bde8e466a4451c7319e3a072d118917957d6554Steve Block    resources: function(frameId)
962bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
972bde8e466a4451c7319e3a072d118917957d6554Steve Block        var result = [];
982bde8e466a4451c7319e3a072d118917957d6554Steve Block        var resources = this._resourcesByFrameId[frameId] || {};
992bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var url in resources)
1002bde8e466a4451c7319e3a072d118917957d6554Steve Block            result.push(resources[url]);
1012bde8e466a4451c7319e3a072d118917957d6554Steve Block        return result;
1022bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
1032bde8e466a4451c7319e3a072d118917957d6554Steve Block
1042bde8e466a4451c7319e3a072d118917957d6554Steve Block    _onCommitLoad: function(event)
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
1062bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!this._cachedResourcesProcessed)
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block
1092bde8e466a4451c7319e3a072d118917957d6554Steve Block        var frame = event.data.frame;
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block        var loaderId = event.data.loaderId;
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block        var isMainFrame = !frame.parentId;
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block
113cad810f21b803229eb11403f9209855525a25d57Steve Block        // frame.parentId === 0 is when main frame navigation happens.
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._clearChildFramesAndResources(isMainFrame ? 0 : frame.id, loaderId);
115cad810f21b803229eb11403f9209855525a25d57Steve Block
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._addOrUpdateFrame(frame);
117cad810f21b803229eb11403f9209855525a25d57Steve Block
118cad810f21b803229eb11403f9209855525a25d57Steve Block        var resourcesForFrame = this._resourcesByFrameId[frame.id];
1192bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (resourcesForFrame) {
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block            for (var url in resourcesForFrame)
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block                this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resourcesForFrame[url]);
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (isMainFrame && this.resourceForURL(frame.url))
1252bde8e466a4451c7319e3a072d118917957d6554Steve Block            WebInspector.mainResource = this.resourceForURL(frame.url);
126cad810f21b803229eb11403f9209855525a25d57Steve Block    },
127cad810f21b803229eb11403f9209855525a25d57Steve Block
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block    _onFrameDetachedFromParent: function(event)
129cad810f21b803229eb11403f9209855525a25d57Steve Block    {
1302bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!this._cachedResourcesProcessed)
1312bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
1322bde8e466a4451c7319e3a072d118917957d6554Steve Block
1332bde8e466a4451c7319e3a072d118917957d6554Steve Block        var frameId = event.data;
134cad810f21b803229eb11403f9209855525a25d57Steve Block        this._clearChildFramesAndResources(frameId, 0);
1352bde8e466a4451c7319e3a072d118917957d6554Steve Block        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, frameId);
1362bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block
1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _onResourceStarted: function(event)
1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!this._cachedResourcesProcessed)
1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._bindResourceURL(event.data);
1432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1452bde8e466a4451c7319e3a072d118917957d6554Steve Block    _onResourceUpdated: function(event)
1462bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
1472bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!this._cachedResourcesProcessed)
1482bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._addResourceToFrame(event.data);
150cad810f21b803229eb11403f9209855525a25d57Steve Block    },
151cad810f21b803229eb11403f9209855525a25d57Steve Block
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block    _addResourceToFrame: function(resource)
153cad810f21b803229eb11403f9209855525a25d57Steve Block    {
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block        var frameId = resource.frameId;
155cad810f21b803229eb11403f9209855525a25d57Steve Block        var resourcesForFrame = this._resourcesByFrameId[frameId];
156cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!resourcesForFrame) {
1572bde8e466a4451c7319e3a072d118917957d6554Steve Block            resourcesForFrame = {};
158cad810f21b803229eb11403f9209855525a25d57Steve Block            this._resourcesByFrameId[frameId] = resourcesForFrame;
159cad810f21b803229eb11403f9209855525a25d57Steve Block        }
1602bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (resourcesForFrame[resource.url] === resource) {
1612bde8e466a4451c7319e3a072d118917957d6554Steve Block            // Already in the tree, we just got an extra update.
1622bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
1632bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
164cad810f21b803229eb11403f9209855525a25d57Steve Block
1652bde8e466a4451c7319e3a072d118917957d6554Steve Block        resourcesForFrame[resource.url] = resource;
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._bindResourceURL(resource);
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
168cad810f21b803229eb11403f9209855525a25d57Steve Block    },
169cad810f21b803229eb11403f9209855525a25d57Steve Block
170cad810f21b803229eb11403f9209855525a25d57Steve Block    forAllResources: function(callback)
171cad810f21b803229eb11403f9209855525a25d57Steve Block    {
172cad810f21b803229eb11403f9209855525a25d57Steve Block        this._callForFrameResources(0, callback);
173cad810f21b803229eb11403f9209855525a25d57Steve Block    },
174cad810f21b803229eb11403f9209855525a25d57Steve Block
175cad810f21b803229eb11403f9209855525a25d57Steve Block    addConsoleMessage: function(msg)
176cad810f21b803229eb11403f9209855525a25d57Steve Block    {
177cad810f21b803229eb11403f9209855525a25d57Steve Block        var resource = this.resourceForURL(msg.url);
178cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!resource)
179cad810f21b803229eb11403f9209855525a25d57Steve Block            return;
180cad810f21b803229eb11403f9209855525a25d57Steve Block
181cad810f21b803229eb11403f9209855525a25d57Steve Block        switch (msg.level) {
182cad810f21b803229eb11403f9209855525a25d57Steve Block        case WebInspector.ConsoleMessage.MessageLevel.Warning:
183cad810f21b803229eb11403f9209855525a25d57Steve Block            resource.warnings += msg.repeatDelta;
184cad810f21b803229eb11403f9209855525a25d57Steve Block            break;
185cad810f21b803229eb11403f9209855525a25d57Steve Block        case WebInspector.ConsoleMessage.MessageLevel.Error:
186cad810f21b803229eb11403f9209855525a25d57Steve Block            resource.errors += msg.repeatDelta;
187cad810f21b803229eb11403f9209855525a25d57Steve Block            break;
188cad810f21b803229eb11403f9209855525a25d57Steve Block        }
189cad810f21b803229eb11403f9209855525a25d57Steve Block
190cad810f21b803229eb11403f9209855525a25d57Steve Block        var view = WebInspector.ResourceView.resourceViewForResource(resource);
1912bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (view.addMessage && msg.isErrorOrWarning() && msg.message)
192cad810f21b803229eb11403f9209855525a25d57Steve Block            view.addMessage(msg);
193cad810f21b803229eb11403f9209855525a25d57Steve Block    },
194cad810f21b803229eb11403f9209855525a25d57Steve Block
195cad810f21b803229eb11403f9209855525a25d57Steve Block    clearConsoleMessages: function()
196cad810f21b803229eb11403f9209855525a25d57Steve Block    {
197cad810f21b803229eb11403f9209855525a25d57Steve Block        function callback(resource)
198cad810f21b803229eb11403f9209855525a25d57Steve Block        {
199cad810f21b803229eb11403f9209855525a25d57Steve Block            resource.clearErrorsAndWarnings();
200cad810f21b803229eb11403f9209855525a25d57Steve Block        }
201cad810f21b803229eb11403f9209855525a25d57Steve Block        this.forAllResources(callback);
202cad810f21b803229eb11403f9209855525a25d57Steve Block    },
203cad810f21b803229eb11403f9209855525a25d57Steve Block
204cad810f21b803229eb11403f9209855525a25d57Steve Block    resourceForURL: function(url)
205cad810f21b803229eb11403f9209855525a25d57Steve Block    {
2062bde8e466a4451c7319e3a072d118917957d6554Steve Block        return this._resourcesByURL[url];
207cad810f21b803229eb11403f9209855525a25d57Steve Block    },
208cad810f21b803229eb11403f9209855525a25d57Steve Block
2092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _bindResourceURL: function(resource)
210cad810f21b803229eb11403f9209855525a25d57Steve Block    {
2112bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._resourcesByURL[resource.url] = resource;
212cad810f21b803229eb11403f9209855525a25d57Steve Block    },
213cad810f21b803229eb11403f9209855525a25d57Steve Block
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block    _clearChildFramesAndResources: function(frameId, loaderToPreserveId)
215cad810f21b803229eb11403f9209855525a25d57Steve Block    {
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frameId);
217cad810f21b803229eb11403f9209855525a25d57Steve Block
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._clearResources(frameId, loaderToPreserveId);
219cad810f21b803229eb11403f9209855525a25d57Steve Block        var subframes = this._subframes[frameId];
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; subframes && i < subframes.length; ++ i) {
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block            this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameRemoved, subframes[i].id);
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._clearChildFramesAndResources(subframes[i].id, loaderToPreserveId);
223cad810f21b803229eb11403f9209855525a25d57Steve Block        }
224cad810f21b803229eb11403f9209855525a25d57Steve Block        delete this._subframes[frameId];
225cad810f21b803229eb11403f9209855525a25d57Steve Block    },
226cad810f21b803229eb11403f9209855525a25d57Steve Block
227cad810f21b803229eb11403f9209855525a25d57Steve Block    _clearResources: function(frameId, loaderToPreserveId)
228cad810f21b803229eb11403f9209855525a25d57Steve Block    {
229cad810f21b803229eb11403f9209855525a25d57Steve Block        var resourcesForFrame = this._resourcesByFrameId[frameId];
230cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!resourcesForFrame)
231cad810f21b803229eb11403f9209855525a25d57Steve Block            return;
232cad810f21b803229eb11403f9209855525a25d57Steve Block
233cad810f21b803229eb11403f9209855525a25d57Steve Block        var preservedResourcesForFrame = [];
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var url in resourcesForFrame) {
2352bde8e466a4451c7319e3a072d118917957d6554Steve Block            var resource = resourcesForFrame[url];
2362bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (resource.loaderId === loaderToPreserveId) {
2372bde8e466a4451c7319e3a072d118917957d6554Steve Block                preservedResourcesForFrame[url] = resource;
238cad810f21b803229eb11403f9209855525a25d57Steve Block                continue;
239cad810f21b803229eb11403f9209855525a25d57Steve Block            }
2402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._unbindResourceURL(resource);
241cad810f21b803229eb11403f9209855525a25d57Steve Block        }
242cad810f21b803229eb11403f9209855525a25d57Steve Block
243cad810f21b803229eb11403f9209855525a25d57Steve Block        delete this._resourcesByFrameId[frameId];
2442bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (preservedResourcesForFrame.length) {
245cad810f21b803229eb11403f9209855525a25d57Steve Block            this._resourcesByFrameId[frameId] = preservedResourcesForFrame;
2462bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
247cad810f21b803229eb11403f9209855525a25d57Steve Block    },
248cad810f21b803229eb11403f9209855525a25d57Steve Block
249cad810f21b803229eb11403f9209855525a25d57Steve Block    _callForFrameResources: function(frameId, callback)
250cad810f21b803229eb11403f9209855525a25d57Steve Block    {
251cad810f21b803229eb11403f9209855525a25d57Steve Block        var resources = this._resourcesByFrameId[frameId];
2522bde8e466a4451c7319e3a072d118917957d6554Steve Block
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var url in resources) {
2542bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (callback(resources[url]))
255cad810f21b803229eb11403f9209855525a25d57Steve Block                return true;
256cad810f21b803229eb11403f9209855525a25d57Steve Block        }
257cad810f21b803229eb11403f9209855525a25d57Steve Block
258cad810f21b803229eb11403f9209855525a25d57Steve Block        var frames = this._subframes[frameId];
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; frames && i < frames.length; ++i) {
2602bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (this._callForFrameResources(frames[i].id, callback))
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block                return true;
262cad810f21b803229eb11403f9209855525a25d57Steve Block        }
263cad810f21b803229eb11403f9209855525a25d57Steve Block        return false;
264cad810f21b803229eb11403f9209855525a25d57Steve Block    },
265cad810f21b803229eb11403f9209855525a25d57Steve Block
2662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _unbindResourceURL: function(resource)
267cad810f21b803229eb11403f9209855525a25d57Steve Block    {
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block        delete this._resourcesByURL[resource.url];
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block
2712bde8e466a4451c7319e3a072d118917957d6554Steve Block    _addFramesRecursively: function(frameTreePayload)
2722bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2732bde8e466a4451c7319e3a072d118917957d6554Steve Block        var framePayload = frameTreePayload.frame;
2742bde8e466a4451c7319e3a072d118917957d6554Steve Block
2752bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Create frame resource.
2762bde8e466a4451c7319e3a072d118917957d6554Steve Block        var frameResource = this._createResource(framePayload, framePayload.url);
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block        frameResource.type = WebInspector.Resource.Type.Document;
2782bde8e466a4451c7319e3a072d118917957d6554Steve Block        frameResource.finished = true;
2792bde8e466a4451c7319e3a072d118917957d6554Steve Block
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._addOrUpdateFrame(framePayload);
2812bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._addResourceToFrame(frameResource);
282cad810f21b803229eb11403f9209855525a25d57Steve Block
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
2842bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._addFramesRecursively(frameTreePayload.childFrames[i]);
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block
2862bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!frameTreePayload.resources)
287cad810f21b803229eb11403f9209855525a25d57Steve Block            return;
2882bde8e466a4451c7319e3a072d118917957d6554Steve Block
2892bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Create frame subresources.
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; i < frameTreePayload.resources.length; ++i) {
2912bde8e466a4451c7319e3a072d118917957d6554Steve Block            var subresource = frameTreePayload.resources[i];
2922bde8e466a4451c7319e3a072d118917957d6554Steve Block            var resource = this._createResource(framePayload, subresource.url);
2932bde8e466a4451c7319e3a072d118917957d6554Steve Block            resource.type = WebInspector.Resource.Type[subresource.type];
2942bde8e466a4451c7319e3a072d118917957d6554Steve Block            resource.finished = true;
2952bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._addResourceToFrame(resource);
296cad810f21b803229eb11403f9209855525a25d57Steve Block        }
2972bde8e466a4451c7319e3a072d118917957d6554Steve Block        return frameResource;
2982bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
299cad810f21b803229eb11403f9209855525a25d57Steve Block
3002bde8e466a4451c7319e3a072d118917957d6554Steve Block    _createResource: function(frame, url)
3012bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
3022bde8e466a4451c7319e3a072d118917957d6554Steve Block        var resource = new WebInspector.Resource(null, url);
3032bde8e466a4451c7319e3a072d118917957d6554Steve Block        resource.frameId = frame.id;
3042bde8e466a4451c7319e3a072d118917957d6554Steve Block        resource.loaderId = frame.loaderId;
3052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        resource.documentURL = frame.url;
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block        return resource;
307cad810f21b803229eb11403f9209855525a25d57Steve Block    }
308cad810f21b803229eb11403f9209855525a25d57Steve Block}
3092bde8e466a4451c7319e3a072d118917957d6554Steve Block
3102bde8e466a4451c7319e3a072d118917957d6554Steve BlockWebInspector.ResourceTreeModel.prototype.__proto__ = WebInspector.Object.prototype;
311