• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @constructor
31 * @extends {WebInspector.TargetAwareObject}
32 * @param {!WebInspector.Target} target
33 */
34WebInspector.ApplicationCacheModel = function(target)
35{
36    WebInspector.TargetAwareObject.call(this, target);
37
38    target.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
39    this._agent = target.applicationCacheAgent();
40    this._agent.enable();
41
42    target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
43    target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
44
45    this._statuses = {};
46    this._manifestURLsByFrame = {};
47
48    this._mainFrameNavigated();
49
50    this._onLine = true;
51}
52
53WebInspector.ApplicationCacheModel.EventTypes = {
54    FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
55    FrameManifestAdded: "FrameManifestAdded",
56    FrameManifestRemoved: "FrameManifestRemoved",
57    NetworkStateChanged: "NetworkStateChanged"
58}
59
60WebInspector.ApplicationCacheModel.prototype = {
61    _frameNavigated: function(event)
62    {
63        var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
64        if (frame.isMainFrame()) {
65            this._mainFrameNavigated();
66            return;
67        }
68
69        this._agent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
70    },
71
72    /**
73     * @param {!WebInspector.Event} event
74     */
75    _frameDetached: function(event)
76    {
77        var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
78        this._frameManifestRemoved(frame.id);
79    },
80
81    _mainFrameNavigated: function()
82    {
83        this._agent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
84    },
85
86    /**
87     * @param {string} frameId
88     * @param {?Protocol.Error} error
89     * @param {string} manifestURL
90     */
91    _manifestForFrameLoaded: function(frameId, error, manifestURL)
92    {
93        if (error) {
94            console.error(error);
95            return;
96        }
97
98        if (!manifestURL)
99            this._frameManifestRemoved(frameId);
100    },
101
102    /**
103     * @param {?Protocol.Error} error
104     * @param {!Array.<!ApplicationCacheAgent.FrameWithManifest>} framesWithManifests
105     */
106    _framesWithManifestsLoaded: function(error, framesWithManifests)
107    {
108        if (error) {
109            console.error(error);
110            return;
111        }
112
113        for (var i = 0; i < framesWithManifests.length; ++i)
114            this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
115    },
116
117    /**
118     * @param {string} frameId
119     * @param {string} manifestURL
120     * @param {number} status
121     */
122    _frameManifestUpdated: function(frameId, manifestURL, status)
123    {
124        if (status === applicationCache.UNCACHED) {
125            this._frameManifestRemoved(frameId);
126            return;
127        }
128
129        if (!manifestURL)
130            return;
131
132        if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
133            this._frameManifestRemoved(frameId);
134
135        var statusChanged = this._statuses[frameId] !== status;
136        this._statuses[frameId] = status;
137
138        if (!this._manifestURLsByFrame[frameId]) {
139            this._manifestURLsByFrame[frameId] = manifestURL;
140            this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
141        }
142
143        if (statusChanged)
144            this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
145    },
146
147    /**
148     * @param {string} frameId
149     */
150    _frameManifestRemoved: function(frameId)
151    {
152        if (!this._manifestURLsByFrame[frameId])
153            return;
154
155        var manifestURL = this._manifestURLsByFrame[frameId];
156        delete this._manifestURLsByFrame[frameId];
157        delete this._statuses[frameId];
158
159        this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
160    },
161
162    /**
163     * @param {string} frameId
164     * @return {string}
165     */
166    frameManifestURL: function(frameId)
167    {
168        return this._manifestURLsByFrame[frameId] || "";
169    },
170
171    /**
172     * @param {string} frameId
173     * @return {number}
174     */
175    frameManifestStatus: function(frameId)
176    {
177        return this._statuses[frameId] || applicationCache.UNCACHED;
178    },
179
180    /**
181     * @return {boolean}
182     */
183    get onLine()
184    {
185        return this._onLine;
186    },
187
188    /**
189     * @param {string} frameId
190     * @param {string} manifestURL
191     * @param {number} status
192     */
193    _statusUpdated: function(frameId, manifestURL, status)
194    {
195        this._frameManifestUpdated(frameId, manifestURL, status);
196    },
197
198    /**
199     * @param {string} frameId
200     * @param {function(?ApplicationCacheAgent.ApplicationCache)} callback
201     */
202    requestApplicationCache: function(frameId, callback)
203    {
204        /**
205         * @param {?Protocol.Error} error
206         * @param {!ApplicationCacheAgent.ApplicationCache} applicationCache
207         */
208        function callbackWrapper(error, applicationCache)
209        {
210            if (error) {
211                console.error(error);
212                callback(null);
213                return;
214            }
215
216            callback(applicationCache);
217        }
218
219        this._agent.getApplicationCacheForFrame(frameId, callbackWrapper);
220    },
221
222    /**
223     * @param {boolean} isNowOnline
224     */
225    _networkStateUpdated: function(isNowOnline)
226    {
227        this._onLine = isNowOnline;
228        this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
229    },
230
231    __proto__: WebInspector.TargetAwareObject.prototype
232}
233
234/**
235 * @constructor
236 * @implements {ApplicationCacheAgent.Dispatcher}
237 */
238WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
239{
240    this._applicationCacheModel = applicationCacheModel;
241}
242
243WebInspector.ApplicationCacheDispatcher.prototype = {
244    /**
245     * @param {string} frameId
246     * @param {string} manifestURL
247     * @param {number} status
248     */
249    applicationCacheStatusUpdated: function(frameId, manifestURL, status)
250    {
251        this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
252    },
253
254    /**
255     * @param {boolean} isNowOnline
256     */
257    networkStateUpdated: function(isNowOnline)
258    {
259        this._applicationCacheModel._networkStateUpdated(isNowOnline);
260    }
261}
262